github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/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 TestGolden(t *testing.T) { 92 // sign.input.gz is a selection of test cases from 93 // https://ed25519.cr.yp.to/python/sign.input 94 testDataZ, err := os.Open("testdata/sign.input.gz") 95 if err != nil { 96 t.Fatal(err) 97 } 98 defer testDataZ.Close() 99 testData, err := gzip.NewReader(testDataZ) 100 if err != nil { 101 t.Fatal(err) 102 } 103 defer testData.Close() 104 105 scanner := bufio.NewScanner(testData) 106 lineNo := 0 107 108 for scanner.Scan() { 109 lineNo++ 110 111 line := scanner.Text() 112 parts := strings.Split(line, ":") 113 if len(parts) != 5 { 114 t.Fatalf("bad number of parts on line %d", lineNo) 115 } 116 117 privBytes, _ := hex.DecodeString(parts[0]) 118 pubKey, _ := hex.DecodeString(parts[1]) 119 msg, _ := hex.DecodeString(parts[2]) 120 sig, _ := hex.DecodeString(parts[3]) 121 // The signatures in the test vectors also include the message 122 // at the end, but we just want R and S. 123 sig = sig[:SignatureSize] 124 125 if l := len(pubKey); l != PublicKeySize { 126 t.Fatalf("bad public key length on line %d: got %d bytes", lineNo, l) 127 } 128 129 var priv [PrivateKeySize]byte 130 copy(priv[:], privBytes) 131 copy(priv[32:], pubKey) 132 133 sig2 := Sign(priv[:], msg) 134 if !bytes.Equal(sig, sig2[:]) { 135 t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2) 136 } 137 138 if !Verify(pubKey, msg, sig2) { 139 t.Errorf("signature failed to verify on line %d", lineNo) 140 } 141 142 priv2 := NewKeyFromSeed(priv[:32]) 143 if !bytes.Equal(priv[:], priv2) { 144 t.Errorf("recreating key pair gave different private key on line %d: %x vs %x", lineNo, priv[:], priv2) 145 } 146 147 if pubKey2 := priv2.Public().(PublicKey); !bytes.Equal(pubKey, pubKey2) { 148 t.Errorf("recreating key pair gave different public key on line %d: %x vs %x", lineNo, pubKey, pubKey2) 149 } 150 151 if seed := priv2.Seed(); !bytes.Equal(priv[:32], seed) { 152 t.Errorf("recreating key pair gave different seed on line %d: %x vs %x", lineNo, priv[:32], seed) 153 } 154 } 155 156 if err := scanner.Err(); err != nil { 157 t.Fatalf("error reading test data: %s", err) 158 } 159 } 160 161 func TestMalleability(t *testing.T) { 162 // https://tools.ietf.org/html/rfc8032#section-5.1.7 adds an additional test 163 // that s be in [0, order). This prevents someone from adding a multiple of 164 // order to s and obtaining a second valid signature for the same message. 165 msg := []byte{0x54, 0x65, 0x73, 0x74} 166 sig := []byte{ 167 0x7c, 0x38, 0xe0, 0x26, 0xf2, 0x9e, 0x14, 0xaa, 0xbd, 0x05, 0x9a, 168 0x0f, 0x2d, 0xb8, 0xb0, 0xcd, 0x78, 0x30, 0x40, 0x60, 0x9a, 0x8b, 169 0xe6, 0x84, 0xdb, 0x12, 0xf8, 0x2a, 0x27, 0x77, 0x4a, 0xb0, 0x67, 170 0x65, 0x4b, 0xce, 0x38, 0x32, 0xc2, 0xd7, 0x6f, 0x8f, 0x6f, 0x5d, 171 0xaf, 0xc0, 0x8d, 0x93, 0x39, 0xd4, 0xee, 0xf6, 0x76, 0x57, 0x33, 172 0x36, 0xa5, 0xc5, 0x1e, 0xb6, 0xf9, 0x46, 0xb3, 0x1d, 173 } 174 publicKey := []byte{ 175 0x7d, 0x4d, 0x0e, 0x7f, 0x61, 0x53, 0xa6, 0x9b, 0x62, 0x42, 0xb5, 176 0x22, 0xab, 0xbe, 0xe6, 0x85, 0xfd, 0xa4, 0x42, 0x0f, 0x88, 0x34, 177 0xb1, 0x08, 0xc3, 0xbd, 0xae, 0x36, 0x9e, 0xf5, 0x49, 0xfa, 178 } 179 180 if Verify(publicKey, msg, sig) { 181 t.Fatal("non-canonical signature accepted") 182 } 183 } 184 185 func BenchmarkKeyGeneration(b *testing.B) { 186 var zero zeroReader 187 for i := 0; i < b.N; i++ { 188 if _, _, err := GenerateKey(zero); err != nil { 189 b.Fatal(err) 190 } 191 } 192 } 193 194 func BenchmarkNewKeyFromSeed(b *testing.B) { 195 seed := make([]byte, SeedSize) 196 b.ReportAllocs() 197 for i := 0; i < b.N; i++ { 198 _ = NewKeyFromSeed(seed) 199 } 200 } 201 202 func BenchmarkSigning(b *testing.B) { 203 var zero zeroReader 204 _, priv, err := GenerateKey(zero) 205 if err != nil { 206 b.Fatal(err) 207 } 208 message := []byte("Hello, world!") 209 b.ReportAllocs() 210 b.ResetTimer() 211 for i := 0; i < b.N; i++ { 212 Sign(priv, message) 213 } 214 } 215 216 func BenchmarkVerification(b *testing.B) { 217 var zero zeroReader 218 pub, priv, err := GenerateKey(zero) 219 if err != nil { 220 b.Fatal(err) 221 } 222 message := []byte("Hello, world!") 223 signature := Sign(priv, message) 224 b.ResetTimer() 225 for i := 0; i < b.N; i++ { 226 Verify(pub, message, signature) 227 } 228 }