1
2
3
4
5 package ecdsa_test
6
7 import (
8 "bufio"
9 "bytes"
10 "compress/bzip2"
11 "crypto"
12 . "crypto/ecdsa"
13 "crypto/elliptic"
14 "crypto/internal/cryptotest"
15 "crypto/internal/fips140/ecdsa"
16 "crypto/rand"
17 "crypto/sha1"
18 "crypto/sha256"
19 "crypto/sha512"
20 "crypto/x509"
21 "encoding/hex"
22 "encoding/json"
23 "fmt"
24 "hash"
25 "io"
26 "math/big"
27 "os"
28 "strings"
29 "testing"
30
31 "golang.org/x/crypto/cryptobyte"
32 "golang.org/x/crypto/cryptobyte/asn1"
33 )
34
35 func testAllCurves(t *testing.T, f func(*testing.T, elliptic.Curve)) {
36 tests := []struct {
37 name string
38 curve elliptic.Curve
39 }{
40 {"P256", elliptic.P256()},
41 {"P224", elliptic.P224()},
42 {"P384", elliptic.P384()},
43 {"P521", elliptic.P521()},
44 {"P256/Generic", genericParamsForCurve(elliptic.P256())},
45 }
46 if testing.Short() {
47 tests = tests[:1]
48 }
49 for _, test := range tests {
50 curve := test.curve
51 cryptotest.TestAllImplementations(t, "ecdsa", func(t *testing.T) {
52 t.Run(test.name, func(t *testing.T) {
53 t.Parallel()
54 f(t, curve)
55 })
56 })
57 }
58 }
59
60
61
62
63
64 func genericParamsForCurve(c elliptic.Curve) *elliptic.CurveParams {
65 d := *(c.Params())
66 return &d
67 }
68
69 func TestKeyGeneration(t *testing.T) {
70 testAllCurves(t, testKeyGeneration)
71 }
72
73 func testKeyGeneration(t *testing.T, c elliptic.Curve) {
74 priv, err := GenerateKey(c, rand.Reader)
75 if err != nil {
76 t.Fatal(err)
77 }
78 if !c.IsOnCurve(priv.PublicKey.X, priv.PublicKey.Y) {
79 t.Errorf("public key invalid: %s", err)
80 }
81 }
82
83 func TestSignAndVerify(t *testing.T) {
84 testAllCurves(t, testSignAndVerify)
85 }
86
87 func testSignAndVerify(t *testing.T, c elliptic.Curve) {
88 priv, _ := GenerateKey(c, rand.Reader)
89
90 hashed := []byte("testing")
91 r, s, err := Sign(rand.Reader, priv, hashed)
92 if err != nil {
93 t.Errorf("error signing: %s", err)
94 return
95 }
96
97 if !Verify(&priv.PublicKey, hashed, r, s) {
98 t.Errorf("Verify failed")
99 }
100
101 hashed[0] ^= 0xff
102 if Verify(&priv.PublicKey, hashed, r, s) {
103 t.Errorf("Verify always works!")
104 }
105 }
106
107 func TestSignAndVerifyASN1(t *testing.T) {
108 testAllCurves(t, testSignAndVerifyASN1)
109 }
110
111 func TestEmptyHashRejection(t *testing.T) {
112 testAllCurves(t, testEmptyHashRejection)
113 }
114
115 func testEmptyHashRejection(t *testing.T, c elliptic.Curve) {
116 priv, err := GenerateKey(c, rand.Reader)
117 if err != nil {
118 t.Fatal(err)
119 }
120
121 t.Run("SignASN1", func(t *testing.T) {
122 _, err := SignASN1(rand.Reader, priv, nil)
123 if err == nil {
124 t.Fatal("SignASN1 with nil hash should fail")
125 }
126 if !strings.Contains(err.Error(), "cannot be empty") {
127 t.Errorf("unexpected error: %v", err)
128 }
129
130 _, err = SignASN1(rand.Reader, priv, []byte{})
131 if err == nil {
132 t.Fatal("SignASN1 with empty hash should fail")
133 }
134 if !strings.Contains(err.Error(), "cannot be empty") {
135 t.Errorf("unexpected error: %v", err)
136 }
137 })
138
139 t.Run("Sign", func(t *testing.T) {
140 _, err := priv.Sign(rand.Reader, nil, nil)
141 if err == nil {
142 t.Fatal("Sign with nil hash should fail")
143 }
144 if !strings.Contains(err.Error(), "cannot be empty") {
145 t.Errorf("unexpected error: %v", err)
146 }
147
148 _, err = priv.Sign(rand.Reader, []byte{}, nil)
149 if err == nil {
150 t.Fatal("Sign with empty hash should fail")
151 }
152 if !strings.Contains(err.Error(), "cannot be empty") {
153 t.Errorf("unexpected error: %v", err)
154 }
155 })
156
157 t.Run("SignDeterministic", func(t *testing.T) {
158 if _, err := priv.Sign(nil, nil, nil); err == nil {
159 t.Error("deterministic Sign with nil hash should fail")
160 }
161 if _, err := priv.Sign(nil, []byte{}, nil); err == nil {
162 t.Error("deterministic Sign with empty hash should fail")
163 }
164 })
165
166 t.Run("VerifyASN1", func(t *testing.T) {
167
168 hash := []byte("test hash")
169 sig, err := SignASN1(rand.Reader, priv, hash)
170 if err != nil {
171 t.Fatal(err)
172 }
173
174
175 if VerifyASN1(&priv.PublicKey, nil, sig) {
176 t.Error("VerifyASN1 with nil hash should return false")
177 }
178
179
180 if VerifyASN1(&priv.PublicKey, []byte{}, sig) {
181 t.Error("VerifyASN1 with empty hash should return false")
182 }
183 })
184 }
185
186 func testSignAndVerifyASN1(t *testing.T, c elliptic.Curve) {
187 priv, _ := GenerateKey(c, rand.Reader)
188
189 hashed := []byte("testing")
190 sig, err := SignASN1(rand.Reader, priv, hashed)
191 if err != nil {
192 t.Errorf("error signing: %s", err)
193 return
194 }
195
196 if !VerifyASN1(&priv.PublicKey, hashed, sig) {
197 t.Errorf("VerifyASN1 failed")
198 }
199
200 hashed[0] ^= 0xff
201 if VerifyASN1(&priv.PublicKey, hashed, sig) {
202 t.Errorf("VerifyASN1 always works!")
203 }
204 }
205
206 func TestSignHashLength(t *testing.T) {
207 testAllCurves(t, testSignHashLength)
208 }
209
210 func testSignHashLength(t *testing.T, c elliptic.Curve) {
211 priv, err := GenerateKey(c, rand.Reader)
212 if err != nil {
213 t.Fatal(err)
214 }
215
216 digest := sha256.Sum256([]byte("message"))
217
218
219 if _, err := priv.Sign(rand.Reader, digest[:], nil); err != nil {
220 t.Errorf("Sign with nil opts: %v", err)
221 }
222
223
224 if _, err := priv.Sign(rand.Reader, digest[:], crypto.SHA256); err != nil {
225 t.Errorf("Sign with matching hash: %v", err)
226 }
227
228
229 if _, err := priv.Sign(rand.Reader, digest[:], crypto.SHA384); err == nil {
230 t.Error("Sign with mismatched hash length should fail")
231 }
232 if _, err := priv.Sign(rand.Reader, digest[:len(digest)-1], crypto.SHA256); err == nil {
233 t.Error("Sign with short digest should fail")
234 }
235 if _, err := priv.Sign(rand.Reader, nil, crypto.SHA256); err == nil {
236 t.Error("Sign with empty digest should fail")
237 }
238
239
240 if _, err := priv.Sign(rand.Reader, digest[:], crypto.Hash(0)); err == nil {
241 t.Error("Sign with crypto.Hash(0) should fail")
242 }
243 }
244
245 func TestNonceSafety(t *testing.T) {
246 testAllCurves(t, testNonceSafety)
247 }
248
249 func testNonceSafety(t *testing.T, c elliptic.Curve) {
250 priv, _ := GenerateKey(c, rand.Reader)
251
252 hashed := []byte("testing")
253 r0, s0, err := Sign(zeroReader, priv, hashed)
254 if err != nil {
255 t.Errorf("error signing: %s", err)
256 return
257 }
258
259 hashed = []byte("testing...")
260 r1, s1, err := Sign(zeroReader, priv, hashed)
261 if err != nil {
262 t.Errorf("error signing: %s", err)
263 return
264 }
265
266 if s0.Cmp(s1) == 0 {
267
268 t.Errorf("the signatures on two different messages were the same")
269 }
270
271 if r0.Cmp(r1) == 0 {
272 t.Errorf("the nonce used for two different messages was the same")
273 }
274 }
275
276 type readerFunc func([]byte) (int, error)
277
278 func (f readerFunc) Read(b []byte) (int, error) { return f(b) }
279
280 var zeroReader = readerFunc(func(b []byte) (int, error) {
281 clear(b)
282 return len(b), nil
283 })
284
285 func TestINDCCA(t *testing.T) {
286 testAllCurves(t, testINDCCA)
287 }
288
289 func testINDCCA(t *testing.T, c elliptic.Curve) {
290 priv, _ := GenerateKey(c, rand.Reader)
291
292 hashed := []byte("testing")
293 r0, s0, err := Sign(rand.Reader, priv, hashed)
294 if err != nil {
295 t.Errorf("error signing: %s", err)
296 return
297 }
298
299 r1, s1, err := Sign(rand.Reader, priv, hashed)
300 if err != nil {
301 t.Errorf("error signing: %s", err)
302 return
303 }
304
305 if s0.Cmp(s1) == 0 {
306 t.Errorf("two signatures of the same message produced the same result")
307 }
308
309 if r0.Cmp(r1) == 0 {
310 t.Errorf("two signatures of the same message produced the same nonce")
311 }
312 }
313
314 func fromHex(s string) *big.Int {
315 r, ok := new(big.Int).SetString(s, 16)
316 if !ok {
317 panic("bad hex")
318 }
319 return r
320 }
321
322 func TestVectors(t *testing.T) {
323 cryptotest.TestAllImplementations(t, "ecdsa", testVectors)
324 }
325
326 func testVectors(t *testing.T) {
327
328
329
330
331
332
333 if testing.Short() {
334 return
335 }
336
337 f, err := os.Open("testdata/SigVer.rsp.bz2")
338 if err != nil {
339 t.Fatal(err)
340 }
341
342 buf := bufio.NewReader(bzip2.NewReader(f))
343
344 lineNo := 1
345 var h hash.Hash
346 var msg []byte
347 var hashed []byte
348 var r, s *big.Int
349 pub := new(PublicKey)
350
351 for {
352 line, err := buf.ReadString('\n')
353 if len(line) == 0 {
354 if err == io.EOF {
355 break
356 }
357 t.Fatalf("error reading from input: %s", err)
358 }
359 lineNo++
360
361 if !strings.HasSuffix(line, "\r\n") {
362 t.Fatalf("bad line ending (expected \\r\\n) on line %d", lineNo)
363 }
364 line = line[:len(line)-2]
365
366 if len(line) == 0 || line[0] == '#' {
367 continue
368 }
369
370 if line[0] == '[' {
371 line = line[1 : len(line)-1]
372 curve, hash, _ := strings.Cut(line, ",")
373
374 switch curve {
375 case "P-224":
376 pub.Curve = elliptic.P224()
377 case "P-256":
378 pub.Curve = elliptic.P256()
379 case "P-384":
380 pub.Curve = elliptic.P384()
381 case "P-521":
382 pub.Curve = elliptic.P521()
383 default:
384 pub.Curve = nil
385 }
386
387 switch hash {
388 case "SHA-1":
389 h = sha1.New()
390 case "SHA-224":
391 h = sha256.New224()
392 case "SHA-256":
393 h = sha256.New()
394 case "SHA-384":
395 h = sha512.New384()
396 case "SHA-512":
397 h = sha512.New()
398 default:
399 h = nil
400 }
401
402 continue
403 }
404
405 if h == nil || pub.Curve == nil {
406 continue
407 }
408
409 switch {
410 case strings.HasPrefix(line, "Msg = "):
411 if msg, err = hex.DecodeString(line[6:]); err != nil {
412 t.Fatalf("failed to decode message on line %d: %s", lineNo, err)
413 }
414 case strings.HasPrefix(line, "Qx = "):
415 pub.X = fromHex(line[5:])
416 case strings.HasPrefix(line, "Qy = "):
417 pub.Y = fromHex(line[5:])
418 case strings.HasPrefix(line, "R = "):
419 r = fromHex(line[4:])
420 case strings.HasPrefix(line, "S = "):
421 s = fromHex(line[4:])
422 case strings.HasPrefix(line, "Result = "):
423 expected := line[9] == 'P'
424 h.Reset()
425 h.Write(msg)
426 hashed := h.Sum(hashed[:0])
427 if Verify(pub, hashed, r, s) != expected {
428 t.Fatalf("incorrect result on line %d", lineNo)
429 }
430 default:
431 t.Fatalf("unknown variable on line %d: %s", lineNo, line)
432 }
433 }
434 }
435
436 func TestNegativeInputs(t *testing.T) {
437 testAllCurves(t, testNegativeInputs)
438 }
439
440 func testNegativeInputs(t *testing.T, curve elliptic.Curve) {
441 key, err := GenerateKey(curve, rand.Reader)
442 if err != nil {
443 t.Errorf("failed to generate key")
444 }
445
446 var hash [32]byte
447 r := new(big.Int).SetInt64(1)
448 r.Lsh(r, 550 )
449 r.Neg(r)
450
451 if Verify(&key.PublicKey, hash[:], r, r) {
452 t.Errorf("bogus signature accepted")
453 }
454 }
455
456 func TestZeroHashSignature(t *testing.T) {
457 testAllCurves(t, testZeroHashSignature)
458 }
459
460 func testZeroHashSignature(t *testing.T, curve elliptic.Curve) {
461 zeroHash := make([]byte, 64)
462
463 privKey, err := GenerateKey(curve, rand.Reader)
464 if err != nil {
465 panic(err)
466 }
467
468
469 r, s, err := Sign(rand.Reader, privKey, zeroHash)
470 if err != nil {
471 panic(err)
472 }
473
474
475 if !Verify(&privKey.PublicKey, zeroHash, r, s) {
476 t.Errorf("zero hash signature verify failed for %T", curve)
477 }
478 }
479
480 func TestZeroSignature(t *testing.T) {
481 testAllCurves(t, testZeroSignature)
482 }
483
484 func testZeroSignature(t *testing.T, curve elliptic.Curve) {
485 privKey, err := GenerateKey(curve, rand.Reader)
486 if err != nil {
487 panic(err)
488 }
489
490 if Verify(&privKey.PublicKey, make([]byte, 64), big.NewInt(0), big.NewInt(0)) {
491 t.Errorf("Verify with r,s=0 succeeded: %T", curve)
492 }
493 }
494
495 func TestNegativeSignature(t *testing.T) {
496 testAllCurves(t, testNegativeSignature)
497 }
498
499 func testNegativeSignature(t *testing.T, curve elliptic.Curve) {
500 zeroHash := make([]byte, 64)
501
502 privKey, err := GenerateKey(curve, rand.Reader)
503 if err != nil {
504 panic(err)
505 }
506 r, s, err := Sign(rand.Reader, privKey, zeroHash)
507 if err != nil {
508 panic(err)
509 }
510
511 r = r.Neg(r)
512 if Verify(&privKey.PublicKey, zeroHash, r, s) {
513 t.Errorf("Verify with r=-r succeeded: %T", curve)
514 }
515 }
516
517 func TestRPlusNSignature(t *testing.T) {
518 testAllCurves(t, testRPlusNSignature)
519 }
520
521 func testRPlusNSignature(t *testing.T, curve elliptic.Curve) {
522 zeroHash := make([]byte, 64)
523
524 privKey, err := GenerateKey(curve, rand.Reader)
525 if err != nil {
526 panic(err)
527 }
528 r, s, err := Sign(rand.Reader, privKey, zeroHash)
529 if err != nil {
530 panic(err)
531 }
532
533 r = r.Add(r, curve.Params().N)
534 if Verify(&privKey.PublicKey, zeroHash, r, s) {
535 t.Errorf("Verify with r=r+n succeeded: %T", curve)
536 }
537 }
538
539 func TestRMinusNSignature(t *testing.T) {
540 testAllCurves(t, testRMinusNSignature)
541 }
542
543 func testRMinusNSignature(t *testing.T, curve elliptic.Curve) {
544 zeroHash := make([]byte, 64)
545
546 privKey, err := GenerateKey(curve, rand.Reader)
547 if err != nil {
548 panic(err)
549 }
550 r, s, err := Sign(rand.Reader, privKey, zeroHash)
551 if err != nil {
552 panic(err)
553 }
554
555 r = r.Sub(r, curve.Params().N)
556 if Verify(&privKey.PublicKey, zeroHash, r, s) {
557 t.Errorf("Verify with r=r-n succeeded: %T", curve)
558 }
559 }
560
561 func TestRFC6979(t *testing.T) {
562 t.Run("P-224", func(t *testing.T) {
563 testRFC6979(t, elliptic.P224(),
564 "F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1",
565 "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
566 "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
567 "sample",
568 "61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA",
569 "BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101")
570 testRFC6979(t, elliptic.P224(),
571 "F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1",
572 "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
573 "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
574 "test",
575 "AD04DDE87B84747A243A631EA47A1BA6D1FAA059149AD2440DE6FBA6",
576 "178D49B1AE90E3D8B629BE3DB5683915F4E8C99FDF6E666CF37ADCFD")
577 })
578 t.Run("P-256", func(t *testing.T) {
579
580
581
582
583
584
585
586
587
588
589
590 testRFC6979(t, elliptic.P256(),
591 "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721",
592 "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
593 "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
594 "wv[vnX",
595 "EFD9073B652E76DA1B5A019C0E4A2E3FA529B035A6ABB91EF67F0ED7A1F21234",
596 "3DB4706C9D9F4A4FE13BB5E08EF0FAB53A57DBAB2061C83A35FA411C68D2BA33")
597
598
599 testRFC6979(t, elliptic.P256(),
600 "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721",
601 "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
602 "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
603 "sample",
604 "EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716",
605 "F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8")
606 testRFC6979(t, elliptic.P256(),
607 "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721",
608 "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
609 "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
610 "test",
611 "F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367",
612 "019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083")
613 })
614 t.Run("P-384", func(t *testing.T) {
615 testRFC6979(t, elliptic.P384(),
616 "6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5",
617 "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
618 "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
619 "sample",
620 "21B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A21D3DAA33BDE1E888E63355D92FA2B3C36D8FB2CD",
621 "F3AA443FB107745BF4BD77CB3891674632068A10CA67E3D45DB2266FA7D1FEEBEFDC63ECCD1AC42EC0CB8668A4FA0AB0")
622 testRFC6979(t, elliptic.P384(),
623 "6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5",
624 "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
625 "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
626 "test",
627 "6D6DEFAC9AB64DABAFE36C6BF510352A4CC27001263638E5B16D9BB51D451559F918EEDAF2293BE5B475CC8F0188636B",
628 "2D46F3BECBCC523D5F1A1256BF0C9B024D879BA9E838144C8BA6BAEB4B53B47D51AB373F9845C0514EEFB14024787265")
629 })
630 t.Run("P-521", func(t *testing.T) {
631 testRFC6979(t, elliptic.P521(),
632 "0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538",
633 "1894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
634 "0493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
635 "sample",
636 "1511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659D16876E25C7C1E57648F23B73564D67F61C6F14D527D54972810421E7D87589E1A7",
637 "04A171143A83163D6DF460AAF61522695F207A58B95C0644D87E52AA1A347916E4F7A72930B1BC06DBE22CE3F58264AFD23704CBB63B29B931F7DE6C9D949A7ECFC")
638 testRFC6979(t, elliptic.P521(),
639 "0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538",
640 "1894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
641 "0493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
642 "test",
643 "00E871C4A14F993C6C7369501900C4BC1E9C7B0B4BA44E04868B30B41D8071042EB28C4C250411D0CE08CD197E4188EA4876F279F90B3D8D74A3C76E6F1E4656AA8",
644 "0CD52DBAA33B063C3A6CD8058A1FB0A46A4754B034FCC644766CA14DA8CA5CA9FDE00E88C1AD60CCBA759025299079D7A427EC3CC5B619BFBC828E7769BCD694E86")
645 })
646 }
647
648 func testRFC6979(t *testing.T, curve elliptic.Curve, D, X, Y, msg, r, s string) {
649 priv := &PrivateKey{
650 D: fromHex(D),
651 PublicKey: PublicKey{
652 Curve: curve,
653 X: fromHex(X),
654 Y: fromHex(Y),
655 },
656 }
657 h := sha256.Sum256([]byte(msg))
658 sig, err := priv.Sign(nil, h[:], crypto.SHA256)
659 if err != nil {
660 t.Fatal(err)
661 }
662 expected, err := encodeSignature(fromHex(r).Bytes(), fromHex(s).Bytes())
663 if err != nil {
664 t.Fatal(err)
665 }
666 if !bytes.Equal(sig, expected) {
667 t.Errorf("signature mismatch:\n got: %x\nwant: %x", sig, expected)
668 }
669 }
670
671 func encodeSignature(r, s []byte) ([]byte, error) {
672 var b cryptobyte.Builder
673 b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
674 addASN1IntBytes(b, r)
675 addASN1IntBytes(b, s)
676 })
677 return b.Bytes()
678 }
679
680 func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) {
681 for len(bytes) > 0 && bytes[0] == 0 {
682 bytes = bytes[1:]
683 }
684 b.AddASN1(asn1.INTEGER, func(c *cryptobyte.Builder) {
685 if bytes[0]&0x80 != 0 {
686 c.AddUint8(0)
687 }
688 c.AddBytes(bytes)
689 })
690 }
691
692 func TestParseAndBytesRoundTrip(t *testing.T) {
693 testAllCurves(t, testParseAndBytesRoundTrip)
694 }
695
696 func testParseAndBytesRoundTrip(t *testing.T, curve elliptic.Curve) {
697 if strings.HasSuffix(t.Name(), "/Generic") {
698 t.Skip("these methods don't support generic curves")
699 }
700 priv, _ := GenerateKey(curve, rand.Reader)
701
702 b, err := priv.PublicKey.Bytes()
703 if err != nil {
704 t.Fatalf("failed to serialize private key's public key: %v", err)
705 }
706 if b[0] != 4 {
707 t.Fatalf("public key bytes doesn't start with 0x04 (uncompressed format)")
708 }
709 p, err := ParseUncompressedPublicKey(curve, b)
710 if err != nil {
711 t.Fatalf("failed to parse private key's public key: %v", err)
712 }
713 if !priv.PublicKey.Equal(p) {
714 t.Errorf("parsed private key's public key doesn't match original")
715 }
716
717 bk, err := priv.Bytes()
718 if err != nil {
719 t.Fatalf("failed to serialize private key: %v", err)
720 }
721 k, err := ParseRawPrivateKey(curve, bk)
722 if err != nil {
723 t.Fatalf("failed to parse private key: %v", err)
724 }
725 if !priv.Equal(k) {
726 t.Errorf("parsed private key doesn't match original")
727 }
728
729 if curve != elliptic.P224() {
730 privECDH, err := priv.ECDH()
731 if err != nil {
732 t.Fatalf("failed to convert private key to ECDH: %v", err)
733 }
734
735 pp, err := privECDH.Curve().NewPublicKey(b)
736 if err != nil {
737 t.Fatalf("failed to parse with ECDH: %v", err)
738 }
739 if !privECDH.PublicKey().Equal(pp) {
740 t.Errorf("parsed ECDH public key doesn't match original")
741 }
742 if !bytes.Equal(b, pp.Bytes()) {
743 t.Errorf("encoded ECDH public key doesn't match Bytes")
744 }
745
746 kk, err := privECDH.Curve().NewPrivateKey(bk)
747 if err != nil {
748 t.Fatalf("failed to parse with ECDH: %v", err)
749 }
750 if !privECDH.Equal(kk) {
751 t.Errorf("parsed ECDH private key doesn't match original")
752 }
753 if !bytes.Equal(bk, kk.Bytes()) {
754 t.Errorf("encoded ECDH private key doesn't match Bytes")
755 }
756 }
757 }
758
759 func TestInvalidPublicKeys(t *testing.T) {
760 testAllCurves(t, testInvalidPublicKeys)
761 }
762
763 func testInvalidPublicKeys(t *testing.T, curve elliptic.Curve) {
764 t.Run("Infinity", func(t *testing.T) {
765 k := &PublicKey{Curve: curve, X: big.NewInt(0), Y: big.NewInt(0)}
766 if _, err := k.Bytes(); err == nil {
767 t.Errorf("PublicKey.Bytes accepted infinity")
768 }
769
770 b := []byte{0}
771 if _, err := ParseUncompressedPublicKey(curve, b); err == nil {
772 t.Errorf("ParseUncompressedPublicKey accepted infinity")
773 }
774 b = make([]byte, 1+2*(curve.Params().BitSize+7)/8)
775 b[0] = 4
776 if _, err := ParseUncompressedPublicKey(curve, b); err == nil {
777 t.Errorf("ParseUncompressedPublicKey accepted infinity")
778 }
779 })
780 t.Run("NotOnCurve", func(t *testing.T) {
781 k, _ := GenerateKey(curve, rand.Reader)
782 k.X = k.X.Add(k.X, big.NewInt(1))
783 if _, err := k.Bytes(); err == nil {
784 t.Errorf("PublicKey.Bytes accepted not on curve")
785 }
786
787 b := make([]byte, 1+2*(curve.Params().BitSize+7)/8)
788 b[0] = 4
789 k.X.FillBytes(b[1 : 1+len(b)/2])
790 k.Y.FillBytes(b[1+len(b)/2:])
791 if _, err := ParseUncompressedPublicKey(curve, b); err == nil {
792 t.Errorf("ParseUncompressedPublicKey accepted not on curve")
793 }
794 })
795 t.Run("Compressed", func(t *testing.T) {
796 k, _ := GenerateKey(curve, rand.Reader)
797 b := elliptic.MarshalCompressed(curve, k.X, k.Y)
798 if _, err := ParseUncompressedPublicKey(curve, b); err == nil {
799 t.Errorf("ParseUncompressedPublicKey accepted compressed key")
800 }
801 })
802 }
803
804 func TestInvalidPrivateKeys(t *testing.T) {
805 testAllCurves(t, testInvalidPrivateKeys)
806 }
807
808 func testInvalidPrivateKeys(t *testing.T, curve elliptic.Curve) {
809 t.Run("Zero", func(t *testing.T) {
810 k := &PrivateKey{PublicKey{curve, big.NewInt(0), big.NewInt(0)}, big.NewInt(0)}
811 if _, err := k.Bytes(); err == nil {
812 t.Errorf("PrivateKey.Bytes accepted zero key")
813 }
814
815 b := make([]byte, (curve.Params().BitSize+7)/8)
816 if _, err := ParseRawPrivateKey(curve, b); err == nil {
817 t.Errorf("ParseRawPrivateKey accepted zero key")
818 }
819 })
820 t.Run("Overflow", func(t *testing.T) {
821 d := new(big.Int).Add(curve.Params().N, big.NewInt(5))
822 x, y := curve.ScalarBaseMult(d.Bytes())
823 k := &PrivateKey{PublicKey{curve, x, y}, d}
824 if _, err := k.Bytes(); err == nil {
825 t.Errorf("PrivateKey.Bytes accepted overflow key")
826 }
827
828 b := make([]byte, (curve.Params().BitSize+7)/8)
829 k.D.FillBytes(b)
830 if _, err := ParseRawPrivateKey(curve, b); err == nil {
831 t.Errorf("ParseRawPrivateKey accepted overflow key")
832 }
833 })
834 t.Run("Length", func(t *testing.T) {
835 b := []byte{1, 2, 3}
836 if _, err := ParseRawPrivateKey(curve, b); err == nil {
837 t.Errorf("ParseRawPrivateKey accepted short key")
838 }
839
840 b = make([]byte, (curve.Params().BitSize+7)/8)
841 b = append(b, []byte{1, 2, 3}...)
842 if _, err := ParseRawPrivateKey(curve, b); err == nil {
843 t.Errorf("ParseRawPrivateKey accepted long key")
844 }
845 })
846 }
847
848
849
850
851 func TestKeyGenerationVectors(t *testing.T) {
852 var vectors []struct {
853 Curve string
854 Seed []byte
855 PKCS8 []byte `json:"private_key_pkcs8"`
856 }
857 f, err := os.Open("testdata/det-keygen.json")
858 if err != nil {
859 t.Fatalf("failed to open det-keygen.json: %v", err)
860 }
861 defer f.Close()
862 if err := json.NewDecoder(f).Decode(&vectors); err != nil {
863 t.Fatalf("failed to decode keygen.json: %v", err)
864 }
865 for i, v := range vectors {
866 t.Run(fmt.Sprintf("%s-%d", v.Curve, i), func(t *testing.T) {
867 t.Setenv("GODEBUG", "cryptocustomrand=1")
868 var pers []byte
869 var curve elliptic.Curve
870 switch v.Curve {
871 case "secp224r1":
872 curve = elliptic.P224()
873 pers = []byte("det ECDSA key gen P-224")
874 case "secp256r1":
875 curve = elliptic.P256()
876 pers = []byte("det ECDSA key gen P-256")
877 case "secp384r1":
878 curve = elliptic.P384()
879 pers = []byte("det ECDSA key gen P-384")
880 case "secp521r1":
881 curve = elliptic.P521()
882 pers = []byte("det ECDSA key gen P-521")
883 default:
884 t.Fatalf("unknown curve: %q", v.Curve)
885 }
886 drbg := ecdsa.TestingOnlyNewDRBG(sha256.New, v.Seed, nil, pers)
887 rng := &keyGenTestReader{next: func(p []byte) error {
888 drbg.Generate(p)
889 return nil
890 }}
891 priv, err := GenerateKey(curve, rng)
892 if err != nil {
893 t.Fatalf("GenerateKey: %v", err)
894 }
895 der, err := x509.MarshalPKCS8PrivateKey(priv)
896 if err != nil {
897 t.Fatalf("MarshalPKCS8PrivateKey: %v", err)
898 }
899 if !bytes.Equal(der, v.PKCS8) {
900 t.Errorf("PKCS8 mismatch:\n%s\nvs\n\n%s", hex.Dump(der), hex.Dump(v.PKCS8))
901 }
902 })
903 }
904 }
905
906 type keyGenTestReader struct {
907 next func([]byte) error
908 }
909
910 func (r *keyGenTestReader) Read(p []byte) (n int, err error) {
911
912
913
914
915
916
917
918 if len(p) == 1 {
919 return 1, nil
920 }
921
922 if err := r.next(p); err != nil {
923 return 0, err
924 }
925 return len(p), nil
926 }
927
928 func benchmarkAllCurves(b *testing.B, f func(*testing.B, elliptic.Curve)) {
929 tests := []struct {
930 name string
931 curve elliptic.Curve
932 }{
933 {"P256", elliptic.P256()},
934 {"P384", elliptic.P384()},
935 {"P521", elliptic.P521()},
936 }
937 for _, test := range tests {
938 curve := test.curve
939 b.Run(test.name, func(b *testing.B) {
940 f(b, curve)
941 })
942 }
943 }
944
945 func BenchmarkSign(b *testing.B) {
946 benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
947 r := bufio.NewReaderSize(rand.Reader, 1<<15)
948 priv, err := GenerateKey(curve, r)
949 if err != nil {
950 b.Fatal(err)
951 }
952 hashed := []byte("testing")
953
954 b.ReportAllocs()
955 b.ResetTimer()
956 for i := 0; i < b.N; i++ {
957 sig, err := SignASN1(r, priv, hashed)
958 if err != nil {
959 b.Fatal(err)
960 }
961
962 hashed[0] = sig[0]
963 }
964 })
965 }
966
967 func BenchmarkVerify(b *testing.B) {
968 benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
969 r := bufio.NewReaderSize(rand.Reader, 1<<15)
970 priv, err := GenerateKey(curve, r)
971 if err != nil {
972 b.Fatal(err)
973 }
974 hashed := []byte("testing")
975 sig, err := SignASN1(r, priv, hashed)
976 if err != nil {
977 b.Fatal(err)
978 }
979
980 b.ReportAllocs()
981 b.ResetTimer()
982 for i := 0; i < b.N; i++ {
983 if !VerifyASN1(&priv.PublicKey, hashed, sig) {
984 b.Fatal("verify failed")
985 }
986 }
987 })
988 }
989
990 func BenchmarkGenerateKey(b *testing.B) {
991 benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
992 r := bufio.NewReaderSize(rand.Reader, 1<<15)
993 b.ReportAllocs()
994 b.ResetTimer()
995 for i := 0; i < b.N; i++ {
996 if _, err := GenerateKey(curve, r); err != nil {
997 b.Fatal(err)
998 }
999 }
1000 })
1001 }
1002
View as plain text