1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package ecdsa
16
17
18
19
20
21
22
23
24
25
26 import (
27 "bytes"
28 "crypto"
29 "crypto/aes"
30 "crypto/cipher"
31 "crypto/ecdh"
32 "crypto/elliptic"
33 "crypto/internal/bigmod"
34 "crypto/internal/boring"
35 "crypto/internal/boring/bbig"
36 "crypto/internal/nistec"
37 "crypto/internal/randutil"
38 "crypto/sha512"
39 "crypto/subtle"
40 "errors"
41 "io"
42 "math/big"
43 "sync"
44
45 "golang.org/x/crypto/cryptobyte"
46 "golang.org/x/crypto/cryptobyte/asn1"
47 )
48
49
50 type PublicKey struct {
51 elliptic.Curve
52 X, Y *big.Int
53 }
54
55
56
57
58
59
60
61 func (k *PublicKey) ECDH() (*ecdh.PublicKey, error) {
62 c := curveToECDH(k.Curve)
63 if c == nil {
64 return nil, errors.New("ecdsa: unsupported curve by crypto/ecdh")
65 }
66 if !k.Curve.IsOnCurve(k.X, k.Y) {
67 return nil, errors.New("ecdsa: invalid public key")
68 }
69 return c.NewPublicKey(elliptic.Marshal(k.Curve, k.X, k.Y))
70 }
71
72
73
74
75
76
77 func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
78 xx, ok := x.(*PublicKey)
79 if !ok {
80 return false
81 }
82 return bigIntEqual(pub.X, xx.X) && bigIntEqual(pub.Y, xx.Y) &&
83
84
85
86
87 pub.Curve == xx.Curve
88 }
89
90
91 type PrivateKey struct {
92 PublicKey
93 D *big.Int
94 }
95
96
97
98
99 func (k *PrivateKey) ECDH() (*ecdh.PrivateKey, error) {
100 c := curveToECDH(k.Curve)
101 if c == nil {
102 return nil, errors.New("ecdsa: unsupported curve by crypto/ecdh")
103 }
104 size := (k.Curve.Params().N.BitLen() + 7) / 8
105 if k.D.BitLen() > size*8 {
106 return nil, errors.New("ecdsa: invalid private key")
107 }
108 return c.NewPrivateKey(k.D.FillBytes(make([]byte, size)))
109 }
110
111 func curveToECDH(c elliptic.Curve) ecdh.Curve {
112 switch c {
113 case elliptic.P256():
114 return ecdh.P256()
115 case elliptic.P384():
116 return ecdh.P384()
117 case elliptic.P521():
118 return ecdh.P521()
119 default:
120 return nil
121 }
122 }
123
124
125 func (priv *PrivateKey) Public() crypto.PublicKey {
126 return &priv.PublicKey
127 }
128
129
130
131
132 func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
133 xx, ok := x.(*PrivateKey)
134 if !ok {
135 return false
136 }
137 return priv.PublicKey.Equal(&xx.PublicKey) && bigIntEqual(priv.D, xx.D)
138 }
139
140
141
142 func bigIntEqual(a, b *big.Int) bool {
143 return subtle.ConstantTimeCompare(a.Bytes(), b.Bytes()) == 1
144 }
145
146
147
148
149
150
151
152
153 func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
154 return SignASN1(rand, priv, digest)
155 }
156
157
158
159
160
161
162 func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
163 randutil.MaybeReadByte(rand)
164
165 if boring.Enabled && rand == boring.RandReader {
166 x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name)
167 if err != nil {
168 return nil, err
169 }
170 return &PrivateKey{PublicKey: PublicKey{Curve: c, X: bbig.Dec(x), Y: bbig.Dec(y)}, D: bbig.Dec(d)}, nil
171 }
172 boring.UnreachableExceptTests()
173
174 switch c.Params() {
175 case elliptic.P224().Params():
176 return generateNISTEC(p224(), rand)
177 case elliptic.P256().Params():
178 return generateNISTEC(p256(), rand)
179 case elliptic.P384().Params():
180 return generateNISTEC(p384(), rand)
181 case elliptic.P521().Params():
182 return generateNISTEC(p521(), rand)
183 default:
184 return generateLegacy(c, rand)
185 }
186 }
187
188 func generateNISTEC[Point nistPoint[Point]](c *nistCurve[Point], rand io.Reader) (*PrivateKey, error) {
189 k, Q, err := randomPoint(c, rand)
190 if err != nil {
191 return nil, err
192 }
193
194 priv := new(PrivateKey)
195 priv.PublicKey.Curve = c.curve
196 priv.D = new(big.Int).SetBytes(k.Bytes(c.N))
197 priv.PublicKey.X, priv.PublicKey.Y, err = c.pointToAffine(Q)
198 if err != nil {
199 return nil, err
200 }
201 return priv, nil
202 }
203
204
205
206 func randomPoint[Point nistPoint[Point]](c *nistCurve[Point], rand io.Reader) (k *bigmod.Nat, p Point, err error) {
207 k = bigmod.NewNat()
208 for {
209 b := make([]byte, c.N.Size())
210 if _, err = io.ReadFull(rand, b); err != nil {
211 return
212 }
213
214
215
216
217
218 if excess := len(b)*8 - c.N.BitLen(); excess > 0 {
219
220
221 if excess != 0 && c.curve.Params().Name != "P-521" {
222 panic("ecdsa: internal error: unexpectedly masking off bits")
223 }
224 b[0] >>= excess
225 }
226
227
228
229
230
231 if _, err = k.SetBytes(b, c.N); err == nil && k.IsZero() == 0 {
232 break
233 }
234
235 if testingOnlyRejectionSamplingLooped != nil {
236 testingOnlyRejectionSamplingLooped()
237 }
238 }
239
240 p, err = c.newPoint().ScalarBaseMult(k.Bytes(c.N))
241 return
242 }
243
244
245
246 var testingOnlyRejectionSamplingLooped func()
247
248
249
250 var errNoAsm = errors.New("no assembly implementation available")
251
252
253
254
255
256
257
258
259
260 func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
261 randutil.MaybeReadByte(rand)
262
263 if boring.Enabled && rand == boring.RandReader {
264 b, err := boringPrivateKey(priv)
265 if err != nil {
266 return nil, err
267 }
268 return boring.SignMarshalECDSA(b, hash)
269 }
270 boring.UnreachableExceptTests()
271
272 csprng, err := mixedCSPRNG(rand, priv, hash)
273 if err != nil {
274 return nil, err
275 }
276
277 if sig, err := signAsm(priv, csprng, hash); err != errNoAsm {
278 return sig, err
279 }
280
281 switch priv.Curve.Params() {
282 case elliptic.P224().Params():
283 return signNISTEC(p224(), priv, csprng, hash)
284 case elliptic.P256().Params():
285 return signNISTEC(p256(), priv, csprng, hash)
286 case elliptic.P384().Params():
287 return signNISTEC(p384(), priv, csprng, hash)
288 case elliptic.P521().Params():
289 return signNISTEC(p521(), priv, csprng, hash)
290 default:
291 return signLegacy(priv, csprng, hash)
292 }
293 }
294
295 func signNISTEC[Point nistPoint[Point]](c *nistCurve[Point], priv *PrivateKey, csprng io.Reader, hash []byte) (sig []byte, err error) {
296
297
298 k, R, err := randomPoint(c, csprng)
299 if err != nil {
300 return nil, err
301 }
302
303
304 kInv := bigmod.NewNat()
305 inverse(c, kInv, k)
306
307 Rx, err := R.BytesX()
308 if err != nil {
309 return nil, err
310 }
311 r, err := bigmod.NewNat().SetOverflowingBytes(Rx, c.N)
312 if err != nil {
313 return nil, err
314 }
315
316
317
318
319 if r.IsZero() == 1 {
320 return nil, errors.New("ecdsa: internal error: r is zero")
321 }
322
323 e := bigmod.NewNat()
324 hashToNat(c, e, hash)
325
326 s, err := bigmod.NewNat().SetBytes(priv.D.Bytes(), c.N)
327 if err != nil {
328 return nil, err
329 }
330 s.Mul(r, c.N)
331 s.Add(e, c.N)
332 s.Mul(kInv, c.N)
333
334
335 if s.IsZero() == 1 {
336 return nil, errors.New("ecdsa: internal error: s is zero")
337 }
338
339 return encodeSignature(r.Bytes(c.N), s.Bytes(c.N))
340 }
341
342 func encodeSignature(r, s []byte) ([]byte, error) {
343 var b cryptobyte.Builder
344 b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
345 addASN1IntBytes(b, r)
346 addASN1IntBytes(b, s)
347 })
348 return b.Bytes()
349 }
350
351
352
353 func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) {
354 for len(bytes) > 0 && bytes[0] == 0 {
355 bytes = bytes[1:]
356 }
357 if len(bytes) == 0 {
358 b.SetError(errors.New("invalid integer"))
359 return
360 }
361 b.AddASN1(asn1.INTEGER, func(c *cryptobyte.Builder) {
362 if bytes[0]&0x80 != 0 {
363 c.AddUint8(0)
364 }
365 c.AddBytes(bytes)
366 })
367 }
368
369
370 func inverse[Point nistPoint[Point]](c *nistCurve[Point], kInv, k *bigmod.Nat) {
371 if c.curve.Params().Name == "P-256" {
372 kBytes, err := nistec.P256OrdInverse(k.Bytes(c.N))
373
374 if err == nil {
375 _, err := kInv.SetBytes(kBytes, c.N)
376 if err != nil {
377 panic("ecdsa: internal error: P256OrdInverse produced an invalid value")
378 }
379 return
380 }
381 }
382
383
384
385 kInv.Exp(k, c.nMinus2, c.N)
386 }
387
388
389
390 func hashToNat[Point nistPoint[Point]](c *nistCurve[Point], e *bigmod.Nat, hash []byte) {
391
392
393
394
395 if size := c.N.Size(); len(hash) >= size {
396 hash = hash[:size]
397 if excess := len(hash)*8 - c.N.BitLen(); excess > 0 {
398 hash = bytes.Clone(hash)
399 for i := len(hash) - 1; i >= 0; i-- {
400 hash[i] >>= excess
401 if i > 0 {
402 hash[i] |= hash[i-1] << (8 - excess)
403 }
404 }
405 }
406 }
407 _, err := e.SetOverflowingBytes(hash, c.N)
408 if err != nil {
409 panic("ecdsa: internal error: truncated hash is too long")
410 }
411 }
412
413
414
415
416
417 func mixedCSPRNG(rand io.Reader, priv *PrivateKey, hash []byte) (io.Reader, error) {
418
419
420
421
422
423
424
425
426
427
428
429
430 entropy := make([]byte, 32)
431 if _, err := io.ReadFull(rand, entropy); err != nil {
432 return nil, err
433 }
434
435
436 md := sha512.New()
437 md.Write(priv.D.Bytes())
438 md.Write(entropy)
439 md.Write(hash)
440 key := md.Sum(nil)[:32]
441
442
443
444 block, err := aes.NewCipher(key)
445 if err != nil {
446 return nil, err
447 }
448
449
450
451 const aesIV = "IV for ECDSA CTR"
452 return &cipher.StreamReader{
453 R: zeroReader,
454 S: cipher.NewCTR(block, []byte(aesIV)),
455 }, nil
456 }
457
458 type zr struct{}
459
460 var zeroReader = zr{}
461
462
463 func (zr) Read(dst []byte) (n int, err error) {
464 clear(dst)
465 return len(dst), nil
466 }
467
468
469
470
471
472
473 func VerifyASN1(pub *PublicKey, hash, sig []byte) bool {
474 if boring.Enabled {
475 key, err := boringPublicKey(pub)
476 if err != nil {
477 return false
478 }
479 return boring.VerifyECDSA(key, hash, sig)
480 }
481 boring.UnreachableExceptTests()
482
483 if err := verifyAsm(pub, hash, sig); err != errNoAsm {
484 return err == nil
485 }
486
487 switch pub.Curve.Params() {
488 case elliptic.P224().Params():
489 return verifyNISTEC(p224(), pub, hash, sig)
490 case elliptic.P256().Params():
491 return verifyNISTEC(p256(), pub, hash, sig)
492 case elliptic.P384().Params():
493 return verifyNISTEC(p384(), pub, hash, sig)
494 case elliptic.P521().Params():
495 return verifyNISTEC(p521(), pub, hash, sig)
496 default:
497 return verifyLegacy(pub, hash, sig)
498 }
499 }
500
501 func verifyNISTEC[Point nistPoint[Point]](c *nistCurve[Point], pub *PublicKey, hash, sig []byte) bool {
502 rBytes, sBytes, err := parseSignature(sig)
503 if err != nil {
504 return false
505 }
506
507 Q, err := c.pointFromAffine(pub.X, pub.Y)
508 if err != nil {
509 return false
510 }
511
512
513
514 r, err := bigmod.NewNat().SetBytes(rBytes, c.N)
515 if err != nil || r.IsZero() == 1 {
516 return false
517 }
518 s, err := bigmod.NewNat().SetBytes(sBytes, c.N)
519 if err != nil || s.IsZero() == 1 {
520 return false
521 }
522
523 e := bigmod.NewNat()
524 hashToNat(c, e, hash)
525
526
527 w := bigmod.NewNat()
528 inverse(c, w, s)
529
530
531 p1, err := c.newPoint().ScalarBaseMult(e.Mul(w, c.N).Bytes(c.N))
532 if err != nil {
533 return false
534 }
535
536 p2, err := Q.ScalarMult(Q, w.Mul(r, c.N).Bytes(c.N))
537 if err != nil {
538 return false
539 }
540
541 Rx, err := p1.Add(p1, p2).BytesX()
542 if err != nil {
543 return false
544 }
545
546 v, err := bigmod.NewNat().SetOverflowingBytes(Rx, c.N)
547 if err != nil {
548 return false
549 }
550
551 return v.Equal(r) == 1
552 }
553
554 func parseSignature(sig []byte) (r, s []byte, err error) {
555 var inner cryptobyte.String
556 input := cryptobyte.String(sig)
557 if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
558 !input.Empty() ||
559 !inner.ReadASN1Integer(&r) ||
560 !inner.ReadASN1Integer(&s) ||
561 !inner.Empty() {
562 return nil, nil, errors.New("invalid ASN.1")
563 }
564 return r, s, nil
565 }
566
567 type nistCurve[Point nistPoint[Point]] struct {
568 newPoint func() Point
569 curve elliptic.Curve
570 N *bigmod.Modulus
571 nMinus2 []byte
572 }
573
574
575 type nistPoint[T any] interface {
576 Bytes() []byte
577 BytesX() ([]byte, error)
578 SetBytes([]byte) (T, error)
579 Add(T, T) T
580 ScalarMult(T, []byte) (T, error)
581 ScalarBaseMult([]byte) (T, error)
582 }
583
584
585 func (curve *nistCurve[Point]) pointFromAffine(x, y *big.Int) (p Point, err error) {
586 bitSize := curve.curve.Params().BitSize
587
588 if x.Sign() < 0 || y.Sign() < 0 {
589 return p, errors.New("negative coordinate")
590 }
591 if x.BitLen() > bitSize || y.BitLen() > bitSize {
592 return p, errors.New("overflowing coordinate")
593 }
594
595 byteLen := (bitSize + 7) / 8
596 buf := make([]byte, 1+2*byteLen)
597 buf[0] = 4
598 x.FillBytes(buf[1 : 1+byteLen])
599 y.FillBytes(buf[1+byteLen : 1+2*byteLen])
600 return curve.newPoint().SetBytes(buf)
601 }
602
603
604 func (curve *nistCurve[Point]) pointToAffine(p Point) (x, y *big.Int, err error) {
605 out := p.Bytes()
606 if len(out) == 1 && out[0] == 0 {
607
608 return nil, nil, errors.New("ecdsa: public key point is the infinity")
609 }
610 byteLen := (curve.curve.Params().BitSize + 7) / 8
611 x = new(big.Int).SetBytes(out[1 : 1+byteLen])
612 y = new(big.Int).SetBytes(out[1+byteLen:])
613 return x, y, nil
614 }
615
616 var p224Once sync.Once
617 var _p224 *nistCurve[*nistec.P224Point]
618
619 func p224() *nistCurve[*nistec.P224Point] {
620 p224Once.Do(func() {
621 _p224 = &nistCurve[*nistec.P224Point]{
622 newPoint: func() *nistec.P224Point { return nistec.NewP224Point() },
623 }
624 precomputeParams(_p224, elliptic.P224())
625 })
626 return _p224
627 }
628
629 var p256Once sync.Once
630 var _p256 *nistCurve[*nistec.P256Point]
631
632 func p256() *nistCurve[*nistec.P256Point] {
633 p256Once.Do(func() {
634 _p256 = &nistCurve[*nistec.P256Point]{
635 newPoint: func() *nistec.P256Point { return nistec.NewP256Point() },
636 }
637 precomputeParams(_p256, elliptic.P256())
638 })
639 return _p256
640 }
641
642 var p384Once sync.Once
643 var _p384 *nistCurve[*nistec.P384Point]
644
645 func p384() *nistCurve[*nistec.P384Point] {
646 p384Once.Do(func() {
647 _p384 = &nistCurve[*nistec.P384Point]{
648 newPoint: func() *nistec.P384Point { return nistec.NewP384Point() },
649 }
650 precomputeParams(_p384, elliptic.P384())
651 })
652 return _p384
653 }
654
655 var p521Once sync.Once
656 var _p521 *nistCurve[*nistec.P521Point]
657
658 func p521() *nistCurve[*nistec.P521Point] {
659 p521Once.Do(func() {
660 _p521 = &nistCurve[*nistec.P521Point]{
661 newPoint: func() *nistec.P521Point { return nistec.NewP521Point() },
662 }
663 precomputeParams(_p521, elliptic.P521())
664 })
665 return _p521
666 }
667
668 func precomputeParams[Point nistPoint[Point]](c *nistCurve[Point], curve elliptic.Curve) {
669 params := curve.Params()
670 c.curve = curve
671 var err error
672 c.N, err = bigmod.NewModulusFromBig(params.N)
673 if err != nil {
674 panic(err)
675 }
676 c.nMinus2 = new(big.Int).Sub(params.N, big.NewInt(2)).Bytes()
677 }
678
View as plain text