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