1
2
3
4
5 package ecdsa
6
7 import (
8 "bufio"
9 "bytes"
10 "compress/bzip2"
11 "crypto"
12 "crypto/elliptic"
13 "crypto/internal/cryptotest"
14 "crypto/rand"
15 "crypto/sha1"
16 "crypto/sha256"
17 "crypto/sha512"
18 "encoding/hex"
19 "hash"
20 "io"
21 "math/big"
22 "os"
23 "strings"
24 "testing"
25 )
26
27 func testAllCurves(t *testing.T, f func(*testing.T, elliptic.Curve)) {
28 tests := []struct {
29 name string
30 curve elliptic.Curve
31 }{
32 {"P256", elliptic.P256()},
33 {"P224", elliptic.P224()},
34 {"P384", elliptic.P384()},
35 {"P521", elliptic.P521()},
36 {"P256/Generic", genericParamsForCurve(elliptic.P256())},
37 }
38 if testing.Short() {
39 tests = tests[:1]
40 }
41 for _, test := range tests {
42 curve := test.curve
43 cryptotest.TestAllImplementations(t, "ecdsa", func(t *testing.T) {
44 t.Run(test.name, func(t *testing.T) {
45 t.Parallel()
46 f(t, curve)
47 })
48 })
49 }
50 }
51
52
53
54
55
56 func genericParamsForCurve(c elliptic.Curve) *elliptic.CurveParams {
57 d := *(c.Params())
58 return &d
59 }
60
61 func TestKeyGeneration(t *testing.T) {
62 testAllCurves(t, testKeyGeneration)
63 }
64
65 func testKeyGeneration(t *testing.T, c elliptic.Curve) {
66 priv, err := GenerateKey(c, rand.Reader)
67 if err != nil {
68 t.Fatal(err)
69 }
70 if !c.IsOnCurve(priv.PublicKey.X, priv.PublicKey.Y) {
71 t.Errorf("public key invalid: %s", err)
72 }
73 }
74
75 func TestSignAndVerify(t *testing.T) {
76 testAllCurves(t, testSignAndVerify)
77 }
78
79 func testSignAndVerify(t *testing.T, c elliptic.Curve) {
80 priv, _ := GenerateKey(c, rand.Reader)
81
82 hashed := []byte("testing")
83 r, s, err := Sign(rand.Reader, priv, hashed)
84 if err != nil {
85 t.Errorf("error signing: %s", err)
86 return
87 }
88
89 if !Verify(&priv.PublicKey, hashed, r, s) {
90 t.Errorf("Verify failed")
91 }
92
93 hashed[0] ^= 0xff
94 if Verify(&priv.PublicKey, hashed, r, s) {
95 t.Errorf("Verify always works!")
96 }
97 }
98
99 func TestSignAndVerifyASN1(t *testing.T) {
100 testAllCurves(t, testSignAndVerifyASN1)
101 }
102
103 func testSignAndVerifyASN1(t *testing.T, c elliptic.Curve) {
104 priv, _ := GenerateKey(c, rand.Reader)
105
106 hashed := []byte("testing")
107 sig, err := SignASN1(rand.Reader, priv, hashed)
108 if err != nil {
109 t.Errorf("error signing: %s", err)
110 return
111 }
112
113 if !VerifyASN1(&priv.PublicKey, hashed, sig) {
114 t.Errorf("VerifyASN1 failed")
115 }
116
117 hashed[0] ^= 0xff
118 if VerifyASN1(&priv.PublicKey, hashed, sig) {
119 t.Errorf("VerifyASN1 always works!")
120 }
121 }
122
123 func TestNonceSafety(t *testing.T) {
124 testAllCurves(t, testNonceSafety)
125 }
126
127 func testNonceSafety(t *testing.T, c elliptic.Curve) {
128 priv, _ := GenerateKey(c, rand.Reader)
129
130 hashed := []byte("testing")
131 r0, s0, err := Sign(zeroReader, priv, hashed)
132 if err != nil {
133 t.Errorf("error signing: %s", err)
134 return
135 }
136
137 hashed = []byte("testing...")
138 r1, s1, err := Sign(zeroReader, priv, hashed)
139 if err != nil {
140 t.Errorf("error signing: %s", err)
141 return
142 }
143
144 if s0.Cmp(s1) == 0 {
145
146 t.Errorf("the signatures on two different messages were the same")
147 }
148
149 if r0.Cmp(r1) == 0 {
150 t.Errorf("the nonce used for two different messages was the same")
151 }
152 }
153
154 type readerFunc func([]byte) (int, error)
155
156 func (f readerFunc) Read(b []byte) (int, error) { return f(b) }
157
158 var zeroReader = readerFunc(func(b []byte) (int, error) {
159 clear(b)
160 return len(b), nil
161 })
162
163 func TestINDCCA(t *testing.T) {
164 testAllCurves(t, testINDCCA)
165 }
166
167 func testINDCCA(t *testing.T, c elliptic.Curve) {
168 priv, _ := GenerateKey(c, rand.Reader)
169
170 hashed := []byte("testing")
171 r0, s0, err := Sign(rand.Reader, priv, hashed)
172 if err != nil {
173 t.Errorf("error signing: %s", err)
174 return
175 }
176
177 r1, s1, err := Sign(rand.Reader, priv, hashed)
178 if err != nil {
179 t.Errorf("error signing: %s", err)
180 return
181 }
182
183 if s0.Cmp(s1) == 0 {
184 t.Errorf("two signatures of the same message produced the same result")
185 }
186
187 if r0.Cmp(r1) == 0 {
188 t.Errorf("two signatures of the same message produced the same nonce")
189 }
190 }
191
192 func fromHex(s string) *big.Int {
193 r, ok := new(big.Int).SetString(s, 16)
194 if !ok {
195 panic("bad hex")
196 }
197 return r
198 }
199
200 func TestVectors(t *testing.T) {
201 cryptotest.TestAllImplementations(t, "ecdsa", testVectors)
202 }
203
204 func testVectors(t *testing.T) {
205
206
207
208
209
210
211 if testing.Short() {
212 return
213 }
214
215 f, err := os.Open("testdata/SigVer.rsp.bz2")
216 if err != nil {
217 t.Fatal(err)
218 }
219
220 buf := bufio.NewReader(bzip2.NewReader(f))
221
222 lineNo := 1
223 var h hash.Hash
224 var msg []byte
225 var hashed []byte
226 var r, s *big.Int
227 pub := new(PublicKey)
228
229 for {
230 line, err := buf.ReadString('\n')
231 if len(line) == 0 {
232 if err == io.EOF {
233 break
234 }
235 t.Fatalf("error reading from input: %s", err)
236 }
237 lineNo++
238
239 if !strings.HasSuffix(line, "\r\n") {
240 t.Fatalf("bad line ending (expected \\r\\n) on line %d", lineNo)
241 }
242 line = line[:len(line)-2]
243
244 if len(line) == 0 || line[0] == '#' {
245 continue
246 }
247
248 if line[0] == '[' {
249 line = line[1 : len(line)-1]
250 curve, hash, _ := strings.Cut(line, ",")
251
252 switch curve {
253 case "P-224":
254 pub.Curve = elliptic.P224()
255 case "P-256":
256 pub.Curve = elliptic.P256()
257 case "P-384":
258 pub.Curve = elliptic.P384()
259 case "P-521":
260 pub.Curve = elliptic.P521()
261 default:
262 pub.Curve = nil
263 }
264
265 switch hash {
266 case "SHA-1":
267 h = sha1.New()
268 case "SHA-224":
269 h = sha256.New224()
270 case "SHA-256":
271 h = sha256.New()
272 case "SHA-384":
273 h = sha512.New384()
274 case "SHA-512":
275 h = sha512.New()
276 default:
277 h = nil
278 }
279
280 continue
281 }
282
283 if h == nil || pub.Curve == nil {
284 continue
285 }
286
287 switch {
288 case strings.HasPrefix(line, "Msg = "):
289 if msg, err = hex.DecodeString(line[6:]); err != nil {
290 t.Fatalf("failed to decode message on line %d: %s", lineNo, err)
291 }
292 case strings.HasPrefix(line, "Qx = "):
293 pub.X = fromHex(line[5:])
294 case strings.HasPrefix(line, "Qy = "):
295 pub.Y = fromHex(line[5:])
296 case strings.HasPrefix(line, "R = "):
297 r = fromHex(line[4:])
298 case strings.HasPrefix(line, "S = "):
299 s = fromHex(line[4:])
300 case strings.HasPrefix(line, "Result = "):
301 expected := line[9] == 'P'
302 h.Reset()
303 h.Write(msg)
304 hashed := h.Sum(hashed[:0])
305 if Verify(pub, hashed, r, s) != expected {
306 t.Fatalf("incorrect result on line %d", lineNo)
307 }
308 default:
309 t.Fatalf("unknown variable on line %d: %s", lineNo, line)
310 }
311 }
312 }
313
314 func TestNegativeInputs(t *testing.T) {
315 testAllCurves(t, testNegativeInputs)
316 }
317
318 func testNegativeInputs(t *testing.T, curve elliptic.Curve) {
319 key, err := GenerateKey(curve, rand.Reader)
320 if err != nil {
321 t.Errorf("failed to generate key")
322 }
323
324 var hash [32]byte
325 r := new(big.Int).SetInt64(1)
326 r.Lsh(r, 550 )
327 r.Neg(r)
328
329 if Verify(&key.PublicKey, hash[:], r, r) {
330 t.Errorf("bogus signature accepted")
331 }
332 }
333
334 func TestZeroHashSignature(t *testing.T) {
335 testAllCurves(t, testZeroHashSignature)
336 }
337
338 func testZeroHashSignature(t *testing.T, curve elliptic.Curve) {
339 zeroHash := make([]byte, 64)
340
341 privKey, err := GenerateKey(curve, rand.Reader)
342 if err != nil {
343 panic(err)
344 }
345
346
347 r, s, err := Sign(rand.Reader, privKey, zeroHash)
348 if err != nil {
349 panic(err)
350 }
351
352
353 if !Verify(&privKey.PublicKey, zeroHash, r, s) {
354 t.Errorf("zero hash signature verify failed for %T", curve)
355 }
356 }
357
358 func TestZeroSignature(t *testing.T) {
359 testAllCurves(t, testZeroSignature)
360 }
361
362 func testZeroSignature(t *testing.T, curve elliptic.Curve) {
363 privKey, err := GenerateKey(curve, rand.Reader)
364 if err != nil {
365 panic(err)
366 }
367
368 if Verify(&privKey.PublicKey, make([]byte, 64), big.NewInt(0), big.NewInt(0)) {
369 t.Errorf("Verify with r,s=0 succeeded: %T", curve)
370 }
371 }
372
373 func TestNegativeSignature(t *testing.T) {
374 testAllCurves(t, testNegativeSignature)
375 }
376
377 func testNegativeSignature(t *testing.T, curve elliptic.Curve) {
378 zeroHash := make([]byte, 64)
379
380 privKey, err := GenerateKey(curve, rand.Reader)
381 if err != nil {
382 panic(err)
383 }
384 r, s, err := Sign(rand.Reader, privKey, zeroHash)
385 if err != nil {
386 panic(err)
387 }
388
389 r = r.Neg(r)
390 if Verify(&privKey.PublicKey, zeroHash, r, s) {
391 t.Errorf("Verify with r=-r succeeded: %T", curve)
392 }
393 }
394
395 func TestRPlusNSignature(t *testing.T) {
396 testAllCurves(t, testRPlusNSignature)
397 }
398
399 func testRPlusNSignature(t *testing.T, curve elliptic.Curve) {
400 zeroHash := make([]byte, 64)
401
402 privKey, err := GenerateKey(curve, rand.Reader)
403 if err != nil {
404 panic(err)
405 }
406 r, s, err := Sign(rand.Reader, privKey, zeroHash)
407 if err != nil {
408 panic(err)
409 }
410
411 r = r.Add(r, curve.Params().N)
412 if Verify(&privKey.PublicKey, zeroHash, r, s) {
413 t.Errorf("Verify with r=r+n succeeded: %T", curve)
414 }
415 }
416
417 func TestRMinusNSignature(t *testing.T) {
418 testAllCurves(t, testRMinusNSignature)
419 }
420
421 func testRMinusNSignature(t *testing.T, curve elliptic.Curve) {
422 zeroHash := make([]byte, 64)
423
424 privKey, err := GenerateKey(curve, rand.Reader)
425 if err != nil {
426 panic(err)
427 }
428 r, s, err := Sign(rand.Reader, privKey, zeroHash)
429 if err != nil {
430 panic(err)
431 }
432
433 r = r.Sub(r, curve.Params().N)
434 if Verify(&privKey.PublicKey, zeroHash, r, s) {
435 t.Errorf("Verify with r=r-n succeeded: %T", curve)
436 }
437 }
438
439 func TestRFC6979(t *testing.T) {
440 t.Run("P-224", func(t *testing.T) {
441 testRFC6979(t, elliptic.P224(),
442 "F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1",
443 "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
444 "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
445 "sample",
446 "61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA",
447 "BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101")
448 testRFC6979(t, elliptic.P224(),
449 "F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1",
450 "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
451 "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
452 "test",
453 "AD04DDE87B84747A243A631EA47A1BA6D1FAA059149AD2440DE6FBA6",
454 "178D49B1AE90E3D8B629BE3DB5683915F4E8C99FDF6E666CF37ADCFD")
455 })
456 t.Run("P-256", func(t *testing.T) {
457
458
459
460
461
462
463
464
465
466
467
468 testRFC6979(t, elliptic.P256(),
469 "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721",
470 "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
471 "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
472 "wv[vnX",
473 "EFD9073B652E76DA1B5A019C0E4A2E3FA529B035A6ABB91EF67F0ED7A1F21234",
474 "3DB4706C9D9F4A4FE13BB5E08EF0FAB53A57DBAB2061C83A35FA411C68D2BA33")
475
476
477 testRFC6979(t, elliptic.P256(),
478 "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721",
479 "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
480 "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
481 "sample",
482 "EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716",
483 "F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8")
484 testRFC6979(t, elliptic.P256(),
485 "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721",
486 "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
487 "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
488 "test",
489 "F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367",
490 "019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083")
491 })
492 t.Run("P-384", func(t *testing.T) {
493 testRFC6979(t, elliptic.P384(),
494 "6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5",
495 "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
496 "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
497 "sample",
498 "21B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A21D3DAA33BDE1E888E63355D92FA2B3C36D8FB2CD",
499 "F3AA443FB107745BF4BD77CB3891674632068A10CA67E3D45DB2266FA7D1FEEBEFDC63ECCD1AC42EC0CB8668A4FA0AB0")
500 testRFC6979(t, elliptic.P384(),
501 "6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5",
502 "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
503 "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
504 "test",
505 "6D6DEFAC9AB64DABAFE36C6BF510352A4CC27001263638E5B16D9BB51D451559F918EEDAF2293BE5B475CC8F0188636B",
506 "2D46F3BECBCC523D5F1A1256BF0C9B024D879BA9E838144C8BA6BAEB4B53B47D51AB373F9845C0514EEFB14024787265")
507 })
508 t.Run("P-521", func(t *testing.T) {
509 testRFC6979(t, elliptic.P521(),
510 "0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538",
511 "1894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
512 "0493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
513 "sample",
514 "1511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659D16876E25C7C1E57648F23B73564D67F61C6F14D527D54972810421E7D87589E1A7",
515 "04A171143A83163D6DF460AAF61522695F207A58B95C0644D87E52AA1A347916E4F7A72930B1BC06DBE22CE3F58264AFD23704CBB63B29B931F7DE6C9D949A7ECFC")
516 testRFC6979(t, elliptic.P521(),
517 "0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538",
518 "1894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
519 "0493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
520 "test",
521 "00E871C4A14F993C6C7369501900C4BC1E9C7B0B4BA44E04868B30B41D8071042EB28C4C250411D0CE08CD197E4188EA4876F279F90B3D8D74A3C76E6F1E4656AA8",
522 "0CD52DBAA33B063C3A6CD8058A1FB0A46A4754B034FCC644766CA14DA8CA5CA9FDE00E88C1AD60CCBA759025299079D7A427EC3CC5B619BFBC828E7769BCD694E86")
523 })
524 }
525
526 func testRFC6979(t *testing.T, curve elliptic.Curve, D, X, Y, msg, r, s string) {
527 priv := &PrivateKey{
528 D: fromHex(D),
529 PublicKey: PublicKey{
530 Curve: curve,
531 X: fromHex(X),
532 Y: fromHex(Y),
533 },
534 }
535 h := sha256.Sum256([]byte(msg))
536 sig, err := priv.Sign(nil, h[:], crypto.SHA256)
537 if err != nil {
538 t.Fatal(err)
539 }
540 expected, err := encodeSignature(fromHex(r).Bytes(), fromHex(s).Bytes())
541 if err != nil {
542 t.Fatal(err)
543 }
544 if !bytes.Equal(sig, expected) {
545 t.Errorf("signature mismatch:\n got: %x\nwant: %x", sig, expected)
546 }
547 }
548
549 func benchmarkAllCurves(b *testing.B, f func(*testing.B, elliptic.Curve)) {
550 tests := []struct {
551 name string
552 curve elliptic.Curve
553 }{
554 {"P256", elliptic.P256()},
555 {"P384", elliptic.P384()},
556 {"P521", elliptic.P521()},
557 }
558 for _, test := range tests {
559 curve := test.curve
560 b.Run(test.name, func(b *testing.B) {
561 f(b, curve)
562 })
563 }
564 }
565
566 func BenchmarkSign(b *testing.B) {
567 benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
568 r := bufio.NewReaderSize(rand.Reader, 1<<15)
569 priv, err := GenerateKey(curve, r)
570 if err != nil {
571 b.Fatal(err)
572 }
573 hashed := []byte("testing")
574
575 b.ReportAllocs()
576 b.ResetTimer()
577 for i := 0; i < b.N; i++ {
578 sig, err := SignASN1(r, priv, hashed)
579 if err != nil {
580 b.Fatal(err)
581 }
582
583 hashed[0] = sig[0]
584 }
585 })
586 }
587
588 func BenchmarkVerify(b *testing.B) {
589 benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
590 r := bufio.NewReaderSize(rand.Reader, 1<<15)
591 priv, err := GenerateKey(curve, r)
592 if err != nil {
593 b.Fatal(err)
594 }
595 hashed := []byte("testing")
596 sig, err := SignASN1(r, priv, hashed)
597 if err != nil {
598 b.Fatal(err)
599 }
600
601 b.ReportAllocs()
602 b.ResetTimer()
603 for i := 0; i < b.N; i++ {
604 if !VerifyASN1(&priv.PublicKey, hashed, sig) {
605 b.Fatal("verify failed")
606 }
607 }
608 })
609 }
610
611 func BenchmarkGenerateKey(b *testing.B) {
612 benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
613 r := bufio.NewReaderSize(rand.Reader, 1<<15)
614 b.ReportAllocs()
615 b.ResetTimer()
616 for i := 0; i < b.N; i++ {
617 if _, err := GenerateKey(curve, r); err != nil {
618 b.Fatal(err)
619 }
620 }
621 })
622 }
623
View as plain text