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 TestParseAndBytesRoundTrip(t *testing.T) {
550 testAllCurves(t, testParseAndBytesRoundTrip)
551 }
552
553 func testParseAndBytesRoundTrip(t *testing.T, curve elliptic.Curve) {
554 if strings.HasSuffix(t.Name(), "/Generic") {
555 t.Skip("these methods don't support generic curves")
556 }
557 priv, _ := GenerateKey(curve, rand.Reader)
558
559 b, err := priv.PublicKey.Bytes()
560 if err != nil {
561 t.Fatalf("failed to serialize private key's public key: %v", err)
562 }
563 if b[0] != 4 {
564 t.Fatalf("public key bytes doesn't start with 0x04 (uncompressed format)")
565 }
566 p, err := ParseUncompressedPublicKey(curve, b)
567 if err != nil {
568 t.Fatalf("failed to parse private key's public key: %v", err)
569 }
570 if !priv.PublicKey.Equal(p) {
571 t.Errorf("parsed private key's public key doesn't match original")
572 }
573
574 bk, err := priv.Bytes()
575 if err != nil {
576 t.Fatalf("failed to serialize private key: %v", err)
577 }
578 k, err := ParseRawPrivateKey(curve, bk)
579 if err != nil {
580 t.Fatalf("failed to parse private key: %v", err)
581 }
582 if !priv.Equal(k) {
583 t.Errorf("parsed private key doesn't match original")
584 }
585
586 if curve != elliptic.P224() {
587 privECDH, err := priv.ECDH()
588 if err != nil {
589 t.Fatalf("failed to convert private key to ECDH: %v", err)
590 }
591
592 pp, err := privECDH.Curve().NewPublicKey(b)
593 if err != nil {
594 t.Fatalf("failed to parse with ECDH: %v", err)
595 }
596 if !privECDH.PublicKey().Equal(pp) {
597 t.Errorf("parsed ECDH public key doesn't match original")
598 }
599 if !bytes.Equal(b, pp.Bytes()) {
600 t.Errorf("encoded ECDH public key doesn't match Bytes")
601 }
602
603 kk, err := privECDH.Curve().NewPrivateKey(bk)
604 if err != nil {
605 t.Fatalf("failed to parse with ECDH: %v", err)
606 }
607 if !privECDH.Equal(kk) {
608 t.Errorf("parsed ECDH private key doesn't match original")
609 }
610 if !bytes.Equal(bk, kk.Bytes()) {
611 t.Errorf("encoded ECDH private key doesn't match Bytes")
612 }
613 }
614 }
615
616 func TestInvalidPublicKeys(t *testing.T) {
617 testAllCurves(t, testInvalidPublicKeys)
618 }
619
620 func testInvalidPublicKeys(t *testing.T, curve elliptic.Curve) {
621 t.Run("Infinity", func(t *testing.T) {
622 k := &PublicKey{Curve: curve, X: big.NewInt(0), Y: big.NewInt(0)}
623 if _, err := k.Bytes(); err == nil {
624 t.Errorf("PublicKey.Bytes accepted infinity")
625 }
626
627 b := []byte{0}
628 if _, err := ParseUncompressedPublicKey(curve, b); err == nil {
629 t.Errorf("ParseUncompressedPublicKey accepted infinity")
630 }
631 b = make([]byte, 1+2*(curve.Params().BitSize+7)/8)
632 b[0] = 4
633 if _, err := ParseUncompressedPublicKey(curve, b); err == nil {
634 t.Errorf("ParseUncompressedPublicKey accepted infinity")
635 }
636 })
637 t.Run("NotOnCurve", func(t *testing.T) {
638 k, _ := GenerateKey(curve, rand.Reader)
639 k.X = k.X.Add(k.X, big.NewInt(1))
640 if _, err := k.Bytes(); err == nil {
641 t.Errorf("PublicKey.Bytes accepted not on curve")
642 }
643
644 b := make([]byte, 1+2*(curve.Params().BitSize+7)/8)
645 b[0] = 4
646 k.X.FillBytes(b[1 : 1+len(b)/2])
647 k.Y.FillBytes(b[1+len(b)/2:])
648 if _, err := ParseUncompressedPublicKey(curve, b); err == nil {
649 t.Errorf("ParseUncompressedPublicKey accepted not on curve")
650 }
651 })
652 t.Run("Compressed", func(t *testing.T) {
653 k, _ := GenerateKey(curve, rand.Reader)
654 b := elliptic.MarshalCompressed(curve, k.X, k.Y)
655 if _, err := ParseUncompressedPublicKey(curve, b); err == nil {
656 t.Errorf("ParseUncompressedPublicKey accepted compressed key")
657 }
658 })
659 }
660
661 func TestInvalidPrivateKeys(t *testing.T) {
662 testAllCurves(t, testInvalidPrivateKeys)
663 }
664
665 func testInvalidPrivateKeys(t *testing.T, curve elliptic.Curve) {
666 t.Run("Zero", func(t *testing.T) {
667 k := &PrivateKey{PublicKey{curve, big.NewInt(0), big.NewInt(0)}, big.NewInt(0)}
668 if _, err := k.Bytes(); err == nil {
669 t.Errorf("PrivateKey.Bytes accepted zero key")
670 }
671
672 b := make([]byte, (curve.Params().BitSize+7)/8)
673 if _, err := ParseRawPrivateKey(curve, b); err == nil {
674 t.Errorf("ParseRawPrivateKey accepted zero key")
675 }
676 })
677 t.Run("Overflow", func(t *testing.T) {
678 d := new(big.Int).Add(curve.Params().N, big.NewInt(5))
679 x, y := curve.ScalarBaseMult(d.Bytes())
680 k := &PrivateKey{PublicKey{curve, x, y}, d}
681 if _, err := k.Bytes(); err == nil {
682 t.Errorf("PrivateKey.Bytes accepted overflow key")
683 }
684
685 b := make([]byte, (curve.Params().BitSize+7)/8)
686 k.D.FillBytes(b)
687 if _, err := ParseRawPrivateKey(curve, b); err == nil {
688 t.Errorf("ParseRawPrivateKey accepted overflow key")
689 }
690 })
691 t.Run("Length", func(t *testing.T) {
692 b := []byte{1, 2, 3}
693 if _, err := ParseRawPrivateKey(curve, b); err == nil {
694 t.Errorf("ParseRawPrivateKey accepted short key")
695 }
696
697 b = append(b, make([]byte, (curve.Params().BitSize+7)/8)...)
698 if _, err := ParseRawPrivateKey(curve, b); err == nil {
699 t.Errorf("ParseRawPrivateKey accepted long key")
700 }
701 })
702 }
703
704 func benchmarkAllCurves(b *testing.B, f func(*testing.B, elliptic.Curve)) {
705 tests := []struct {
706 name string
707 curve elliptic.Curve
708 }{
709 {"P256", elliptic.P256()},
710 {"P384", elliptic.P384()},
711 {"P521", elliptic.P521()},
712 }
713 for _, test := range tests {
714 curve := test.curve
715 b.Run(test.name, func(b *testing.B) {
716 f(b, curve)
717 })
718 }
719 }
720
721 func BenchmarkSign(b *testing.B) {
722 benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
723 r := bufio.NewReaderSize(rand.Reader, 1<<15)
724 priv, err := GenerateKey(curve, r)
725 if err != nil {
726 b.Fatal(err)
727 }
728 hashed := []byte("testing")
729
730 b.ReportAllocs()
731 b.ResetTimer()
732 for i := 0; i < b.N; i++ {
733 sig, err := SignASN1(r, priv, hashed)
734 if err != nil {
735 b.Fatal(err)
736 }
737
738 hashed[0] = sig[0]
739 }
740 })
741 }
742
743 func BenchmarkVerify(b *testing.B) {
744 benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
745 r := bufio.NewReaderSize(rand.Reader, 1<<15)
746 priv, err := GenerateKey(curve, r)
747 if err != nil {
748 b.Fatal(err)
749 }
750 hashed := []byte("testing")
751 sig, err := SignASN1(r, priv, hashed)
752 if err != nil {
753 b.Fatal(err)
754 }
755
756 b.ReportAllocs()
757 b.ResetTimer()
758 for i := 0; i < b.N; i++ {
759 if !VerifyASN1(&priv.PublicKey, hashed, sig) {
760 b.Fatal("verify failed")
761 }
762 }
763 })
764 }
765
766 func BenchmarkGenerateKey(b *testing.B) {
767 benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
768 r := bufio.NewReaderSize(rand.Reader, 1<<15)
769 b.ReportAllocs()
770 b.ResetTimer()
771 for i := 0; i < b.N; i++ {
772 if _, err := GenerateKey(curve, r); err != nil {
773 b.Fatal(err)
774 }
775 }
776 })
777 }
778
View as plain text