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.
18 "golang.org/x/crypto/ed25519/internal/edwards25519"
21 type zeroReader struct{}
23 func (zeroReader) Read(buf []byte) (int, error) {
30 func TestUnmarshalMarshal(t *testing.T) {
31 pub, _, _ := GenerateKey(rand.Reader)
33 var A edwards25519.ExtendedGroupElement
35 copy(pubBytes[:], pub)
36 if !A.FromBytes(&pubBytes) {
37 t.Fatalf("ExtendedGroupElement.FromBytes failed")
44 t.Errorf("FromBytes(%v)->ToBytes does not round-trip, got %x\n", pubBytes, pub2)
48 func TestSignVerify(t *testing.T) {
50 public, private, _ := GenerateKey(zero)
52 message := []byte("test message")
53 sig := Sign(private, message)
54 if !Verify(public, message, sig) {
55 t.Errorf("valid signature rejected")
58 wrongMessage := []byte("wrong message")
59 if Verify(public, wrongMessage, sig) {
60 t.Errorf("signature of different message accepted")
64 func TestCryptoSigner(t *testing.T) {
66 public, private, _ := GenerateKey(zero)
68 signer := crypto.Signer(private)
70 publicInterface := signer.Public()
71 public2, ok := publicInterface.(PublicKey)
73 t.Fatalf("expected PublicKey from Public() but got %T", publicInterface)
76 if !bytes.Equal(public, public2) {
77 t.Errorf("public keys do not match: original:%x vs Public():%x", public, public2)
80 message := []byte("message")
81 var noHash crypto.Hash
82 signature, err := signer.Sign(zero, message, noHash)
84 t.Fatalf("error from Sign(): %s", err)
87 if !Verify(public, message, signature) {
88 t.Errorf("Verify failed on signature from Sign()")
92 func TestGolden(t *testing.T) {
93 // sign.input.gz is a selection of test cases from
94 // https://ed25519.cr.yp.to/python/sign.input
95 testDataZ, err := os.Open("testdata/sign.input.gz")
99 defer testDataZ.Close()
100 testData, err := gzip.NewReader(testDataZ)
104 defer testData.Close()
106 scanner := bufio.NewScanner(testData)
112 line := scanner.Text()
113 parts := strings.Split(line, ":")
115 t.Fatalf("bad number of parts on line %d", lineNo)
118 privBytes, _ := hex.DecodeString(parts[0])
119 pubKey, _ := hex.DecodeString(parts[1])
120 msg, _ := hex.DecodeString(parts[2])
121 sig, _ := hex.DecodeString(parts[3])
122 // The signatures in the test vectors also include the message
123 // at the end, but we just want R and S.
124 sig = sig[:SignatureSize]
126 if l := len(pubKey); l != PublicKeySize {
127 t.Fatalf("bad public key length on line %d: got %d bytes", lineNo, l)
130 var priv [PrivateKeySize]byte
131 copy(priv[:], privBytes)
132 copy(priv[32:], pubKey)
134 sig2 := Sign(priv[:], msg)
135 if !bytes.Equal(sig, sig2[:]) {
136 t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2)
139 if !Verify(pubKey, msg, sig2) {
140 t.Errorf("signature failed to verify on line %d", lineNo)
143 priv2 := NewKeyFromSeed(priv[:32])
144 if !bytes.Equal(priv[:], priv2) {
145 t.Errorf("recreating key pair gave different private key on line %d: %x vs %x", lineNo, priv[:], priv2)
148 if pubKey2 := priv2.Public().(PublicKey); !bytes.Equal(pubKey, pubKey2) {
149 t.Errorf("recreating key pair gave different public key on line %d: %x vs %x", lineNo, pubKey, pubKey2)
152 if seed := priv2.Seed(); !bytes.Equal(priv[:32], seed) {
153 t.Errorf("recreating key pair gave different seed on line %d: %x vs %x", lineNo, priv[:32], seed)
157 if err := scanner.Err(); err != nil {
158 t.Fatalf("error reading test data: %s", err)
162 func TestMalleability(t *testing.T) {
163 // https://tools.ietf.org/html/rfc8032#section-5.1.7 adds an additional test
164 // that s be in [0, order). This prevents someone from adding a multiple of
165 // order to s and obtaining a second valid signature for the same message.
166 msg := []byte{0x54, 0x65, 0x73, 0x74}
168 0x7c, 0x38, 0xe0, 0x26, 0xf2, 0x9e, 0x14, 0xaa, 0xbd, 0x05, 0x9a,
169 0x0f, 0x2d, 0xb8, 0xb0, 0xcd, 0x78, 0x30, 0x40, 0x60, 0x9a, 0x8b,
170 0xe6, 0x84, 0xdb, 0x12, 0xf8, 0x2a, 0x27, 0x77, 0x4a, 0xb0, 0x67,
171 0x65, 0x4b, 0xce, 0x38, 0x32, 0xc2, 0xd7, 0x6f, 0x8f, 0x6f, 0x5d,
172 0xaf, 0xc0, 0x8d, 0x93, 0x39, 0xd4, 0xee, 0xf6, 0x76, 0x57, 0x33,
173 0x36, 0xa5, 0xc5, 0x1e, 0xb6, 0xf9, 0x46, 0xb3, 0x1d,
176 0x7d, 0x4d, 0x0e, 0x7f, 0x61, 0x53, 0xa6, 0x9b, 0x62, 0x42, 0xb5,
177 0x22, 0xab, 0xbe, 0xe6, 0x85, 0xfd, 0xa4, 0x42, 0x0f, 0x88, 0x34,
178 0xb1, 0x08, 0xc3, 0xbd, 0xae, 0x36, 0x9e, 0xf5, 0x49, 0xfa,
181 if Verify(publicKey, msg, sig) {
182 t.Fatal("non-canonical signature accepted")
186 func BenchmarkKeyGeneration(b *testing.B) {
188 for i := 0; i < b.N; i++ {
189 if _, _, err := GenerateKey(zero); err != nil {
195 func BenchmarkSigning(b *testing.B) {
197 _, priv, err := GenerateKey(zero)
201 message := []byte("Hello, world!")
203 for i := 0; i < b.N; i++ {
208 func BenchmarkVerification(b *testing.B) {
210 pub, priv, err := GenerateKey(zero)
214 message := []byte("Hello, world!")
215 signature := Sign(priv, message)
217 for i := 0; i < b.N; i++ {
218 Verify(pub, message, signature)