github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/crypto/ed25519/ed25519_test.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ed25519 6 7 import ( 8 "bufio" 9 "bytes" 10 "compress/gzip" 11 "crypto" 12 "crypto/ed25519/internal/edwards25519" 13 "crypto/rand" 14 "encoding/hex" 15 "os" 16 "strings" 17 "testing" 18 ) 19 20 type zeroReader struct{} 21 22 func (zeroReader) Read(buf []byte) (int, error) { 23 for i := range buf { 24 buf[i] = 0 25 } 26 return len(buf), nil 27 } 28 29 func TestUnmarshalMarshal(t *testing.T) { 30 pub, _, _ := GenerateKey(rand.Reader) 31 32 var A edwards25519.ExtendedGroupElement 33 var pubBytes [32]byte 34 copy(pubBytes[:], pub) 35 if !A.FromBytes(&pubBytes) { 36 t.Fatalf("ExtendedGroupElement.FromBytes failed") 37 } 38 39 var pub2 [32]byte 40 A.ToBytes(&pub2) 41 42 if pubBytes != pub2 { 43 t.Errorf("FromBytes(%v)->ToBytes does not round-trip, got %x\n", pubBytes, pub2) 44 } 45 } 46 47 func TestSignVerify(t *testing.T) { 48 var zero zeroReader 49 public, private, _ := GenerateKey(zero) 50 51 message := []byte("test message") 52 sig := Sign(private, message) 53 if !Verify(public, message, sig) { 54 t.Errorf("valid signature rejected") 55 } 56 57 wrongMessage := []byte("wrong message") 58 if Verify(public, wrongMessage, sig) { 59 t.Errorf("signature of different message accepted") 60 } 61 } 62 63 func TestCryptoSigner(t *testing.T) { 64 var zero zeroReader 65 public, private, _ := GenerateKey(zero) 66 67 signer := crypto.Signer(private) 68 69 publicInterface := signer.Public() 70 public2, ok := publicInterface.(PublicKey) 71 if !ok { 72 t.Fatalf("expected PublicKey from Public() but got %T", publicInterface) 73 } 74 75 if !bytes.Equal(public, public2) { 76 t.Errorf("public keys do not match: original:%x vs Public():%x", public, public2) 77 } 78 79 message := []byte("message") 80 var noHash crypto.Hash 81 signature, err := signer.Sign(zero, message, noHash) 82 if err != nil { 83 t.Fatalf("error from Sign(): %s", err) 84 } 85 86 if !Verify(public, message, signature) { 87 t.Errorf("Verify failed on signature from Sign()") 88 } 89 } 90 91 func TestEqual(t *testing.T) { 92 public, private, _ := GenerateKey(rand.Reader) 93 94 if !public.Equal(public) { 95 t.Errorf("public key is not equal to itself: %q", public) 96 } 97 if !public.Equal(crypto.Signer(private).Public()) { 98 t.Errorf("private.Public() is not Equal to public: %q", public) 99 } 100 if !private.Equal(private) { 101 t.Errorf("private key is not equal to itself: %q", private) 102 } 103 104 otherPub, otherPriv, _ := GenerateKey(rand.Reader) 105 if public.Equal(otherPub) { 106 t.Errorf("different public keys are Equal") 107 } 108 if private.Equal(otherPriv) { 109 t.Errorf("different private keys are Equal") 110 } 111 } 112 113 func TestGolden(t *testing.T) { 114 // sign.input.gz is a selection of test cases from 115 // https://ed25519.cr.yp.to/python/sign.input 116 testDataZ, err := os.Open("testdata/sign.input.gz") 117 if err != nil { 118 t.Fatal(err) 119 } 120 defer testDataZ.Close() 121 testData, err := gzip.NewReader(testDataZ) 122 if err != nil { 123 t.Fatal(err) 124 } 125 defer testData.Close() 126 127 scanner := bufio.NewScanner(testData) 128 lineNo := 0 129 130 for scanner.Scan() { 131 lineNo++ 132 133 line := scanner.Text() 134 parts := strings.Split(line, ":") 135 if len(parts) != 5 { 136 t.Fatalf("bad number of parts on line %d", lineNo) 137 } 138 139 privBytes, _ := hex.DecodeString(parts[0]) 140 pubKey, _ := hex.DecodeString(parts[1]) 141 msg, _ := hex.DecodeString(parts[2]) 142 sig, _ := hex.DecodeString(parts[3]) 143 // The signatures in the test vectors also include the message 144 // at the end, but we just want R and S. 145 sig = sig[:SignatureSize] 146 147 if l := len(pubKey); l != PublicKeySize { 148 t.Fatalf("bad public key length on line %d: got %d bytes", lineNo, l) 149 } 150 151 var priv [PrivateKeySize]byte 152 copy(priv[:], privBytes) 153 copy(priv[32:], pubKey) 154 155 sig2 := Sign(priv[:], msg) 156 if !bytes.Equal(sig, sig2[:]) { 157 t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2) 158 } 159 160 if !Verify(pubKey, msg, sig2) { 161 t.Errorf("signature failed to verify on line %d", lineNo) 162 } 163 164 priv2 := NewKeyFromSeed(priv[:32]) 165 if !bytes.Equal(priv[:], priv2) { 166 t.Errorf("recreating key pair gave different private key on line %d: %x vs %x", lineNo, priv[:], priv2) 167 } 168 169 if pubKey2 := priv2.Public().(PublicKey); !bytes.Equal(pubKey, pubKey2) { 170 t.Errorf("recreating key pair gave different public key on line %d: %x vs %x", lineNo, pubKey, pubKey2) 171 } 172 173 if seed := priv2.Seed(); !bytes.Equal(priv[:32], seed) { 174 t.Errorf("recreating key pair gave different seed on line %d: %x vs %x", lineNo, priv[:32], seed) 175 } 176 } 177 178 if err := scanner.Err(); err != nil { 179 t.Fatalf("error reading test data: %s", err) 180 } 181 } 182 183 func TestMalleability(t *testing.T) { 184 // https://tools.ietf.org/html/rfc8032#section-5.1.7 adds an additional test 185 // that s be in [0, order). This prevents someone from adding a multiple of 186 // order to s and obtaining a second valid signature for the same message. 187 msg := []byte{0x54, 0x65, 0x73, 0x74} 188 sig := []byte{ 189 0x7c, 0x38, 0xe0, 0x26, 0xf2, 0x9e, 0x14, 0xaa, 0xbd, 0x05, 0x9a, 190 0x0f, 0x2d, 0xb8, 0xb0, 0xcd, 0x78, 0x30, 0x40, 0x60, 0x9a, 0x8b, 191 0xe6, 0x84, 0xdb, 0x12, 0xf8, 0x2a, 0x27, 0x77, 0x4a, 0xb0, 0x67, 192 0x65, 0x4b, 0xce, 0x38, 0x32, 0xc2, 0xd7, 0x6f, 0x8f, 0x6f, 0x5d, 193 0xaf, 0xc0, 0x8d, 0x93, 0x39, 0xd4, 0xee, 0xf6, 0x76, 0x57, 0x33, 194 0x36, 0xa5, 0xc5, 0x1e, 0xb6, 0xf9, 0x46, 0xb3, 0x1d, 195 } 196 publicKey := []byte{ 197 0x7d, 0x4d, 0x0e, 0x7f, 0x61, 0x53, 0xa6, 0x9b, 0x62, 0x42, 0xb5, 198 0x22, 0xab, 0xbe, 0xe6, 0x85, 0xfd, 0xa4, 0x42, 0x0f, 0x88, 0x34, 199 0xb1, 0x08, 0xc3, 0xbd, 0xae, 0x36, 0x9e, 0xf5, 0x49, 0xfa, 200 } 201 202 if Verify(publicKey, msg, sig) { 203 t.Fatal("non-canonical signature accepted") 204 } 205 } 206 207 func BenchmarkKeyGeneration(b *testing.B) { 208 var zero zeroReader 209 for i := 0; i < b.N; i++ { 210 if _, _, err := GenerateKey(zero); err != nil { 211 b.Fatal(err) 212 } 213 } 214 } 215 216 func BenchmarkNewKeyFromSeed(b *testing.B) { 217 seed := make([]byte, SeedSize) 218 b.ReportAllocs() 219 for i := 0; i < b.N; i++ { 220 _ = NewKeyFromSeed(seed) 221 } 222 } 223 224 func BenchmarkSigning(b *testing.B) { 225 var zero zeroReader 226 _, priv, err := GenerateKey(zero) 227 if err != nil { 228 b.Fatal(err) 229 } 230 message := []byte("Hello, world!") 231 b.ReportAllocs() 232 b.ResetTimer() 233 for i := 0; i < b.N; i++ { 234 Sign(priv, message) 235 } 236 } 237 238 func BenchmarkVerification(b *testing.B) { 239 var zero zeroReader 240 pub, priv, err := GenerateKey(zero) 241 if err != nil { 242 b.Fatal(err) 243 } 244 message := []byte("Hello, world!") 245 signature := Sign(priv, message) 246 b.ResetTimer() 247 for i := 0; i < b.N; i++ { 248 Verify(pub, message, signature) 249 } 250 }