1
2
3
4
5 package ecdsa
6
7 import (
8 "bytes"
9 "crypto/internal/fips140"
10 "crypto/internal/fips140/bigmod"
11 "crypto/internal/fips140/drbg"
12 "crypto/internal/fips140/nistec"
13 "errors"
14 "hash"
15 "io"
16 "math/bits"
17 "sync"
18 )
19
20
21
22
23
24 type PrivateKey struct {
25 pub PublicKey
26 d []byte
27 }
28
29 func (priv *PrivateKey) Bytes() []byte {
30 return priv.d
31 }
32
33 func (priv *PrivateKey) PublicKey() *PublicKey {
34 return &priv.pub
35 }
36
37 type PublicKey struct {
38 curve curveID
39 q []byte
40 }
41
42 func (pub *PublicKey) Bytes() []byte {
43 return pub.q
44 }
45
46 type curveID string
47
48 const (
49 p224 curveID = "P-224"
50 p256 curveID = "P-256"
51 p384 curveID = "P-384"
52 p521 curveID = "P-521"
53 )
54
55 type Curve[P Point[P]] struct {
56 curve curveID
57 newPoint func() P
58 ordInverse func(*[4]uint64)
59 N *bigmod.Modulus
60 nMinus2 []byte
61 }
62
63
64 type Point[P any] interface {
65 *nistec.P224Point | *nistec.P256Point | *nistec.P384Point | *nistec.P521Point
66 Bytes() []byte
67 BytesX() ([]byte, error)
68 SetBytes([]byte) (P, error)
69 ScalarMult(P, []byte) (P, error)
70 ScalarBaseMult([]byte) (P, error)
71 Add(p1, p2 P) P
72 }
73
74 func precomputeParams[P Point[P]](c *Curve[P], order []byte) {
75 var err error
76 c.N, err = bigmod.NewModulus(order)
77 if err != nil {
78 panic(err)
79 }
80 two, _ := bigmod.NewNat().SetBytes([]byte{2}, c.N)
81 c.nMinus2 = bigmod.NewNat().ExpandFor(c.N).Sub(two, c.N).Bytes(c.N)
82 }
83
84 func P224() *Curve[*nistec.P224Point] { return _P224() }
85
86 var _P224 = sync.OnceValue(func() *Curve[*nistec.P224Point] {
87 c := &Curve[*nistec.P224Point]{
88 curve: p224,
89 newPoint: nistec.NewP224Point,
90 }
91 precomputeParams(c, p224Order)
92 return c
93 })
94
95 var p224Order = []byte{
96 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
97 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0xa2,
98 0xe0, 0xb8, 0xf0, 0x3e, 0x13, 0xdd, 0x29, 0x45,
99 0x5c, 0x5c, 0x2a, 0x3d,
100 }
101
102 func P256() *Curve[*nistec.P256Point] { return _P256() }
103
104 var _P256 = sync.OnceValue(func() *Curve[*nistec.P256Point] {
105 c := &Curve[*nistec.P256Point]{
106 curve: p256,
107 newPoint: nistec.NewP256Point,
108 ordInverse: nistec.P256OrdInverse,
109 }
110 precomputeParams(c, p256Order)
111 return c
112 })
113
114 var p256Order = []byte{
115 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
116 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
117 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84,
118 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51}
119
120 func P384() *Curve[*nistec.P384Point] { return _P384() }
121
122 var _P384 = sync.OnceValue(func() *Curve[*nistec.P384Point] {
123 c := &Curve[*nistec.P384Point]{
124 curve: p384,
125 newPoint: nistec.NewP384Point,
126 }
127 precomputeParams(c, p384Order)
128 return c
129 })
130
131 var p384Order = []byte{
132 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
133 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
134 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
135 0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf,
136 0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a,
137 0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73}
138
139 func P521() *Curve[*nistec.P521Point] { return _P521() }
140
141 var _P521 = sync.OnceValue(func() *Curve[*nistec.P521Point] {
142 c := &Curve[*nistec.P521Point]{
143 curve: p521,
144 newPoint: nistec.NewP521Point,
145 }
146 precomputeParams(c, p521Order)
147 return c
148 })
149
150 var p521Order = []byte{0x01, 0xff,
151 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
152 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
153 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
154 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
155 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b,
156 0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09, 0xa5, 0xd0,
157 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
158 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09}
159
160
161
162
163 func NewPrivateKey[P Point[P]](c *Curve[P], D, Q []byte) (*PrivateKey, error) {
164 fips140.RecordApproved()
165 pub, err := NewPublicKey(c, Q)
166 if err != nil {
167 return nil, err
168 }
169 if len(D) != c.N.Size() {
170 return nil, errors.New("ecdsa: invalid private key length")
171 }
172 d, err := bigmod.NewNat().SetBytes(D, c.N)
173 if err != nil {
174 return nil, err
175 }
176 if d.IsZero() == 1 {
177 return nil, errors.New("ecdsa: private key is zero")
178 }
179 priv := &PrivateKey{pub: *pub, d: d.Bytes(c.N)}
180 return priv, nil
181 }
182
183
184
185 func NewPublicKey[P Point[P]](c *Curve[P], Q []byte) (*PublicKey, error) {
186
187
188
189 if len(Q) < 1 || Q[0] == 0 {
190 return nil, errors.New("ecdsa: invalid public key encoding")
191 }
192 _, err := c.newPoint().SetBytes(Q)
193 if err != nil {
194 return nil, err
195 }
196 return &PublicKey{curve: c.curve, q: Q}, nil
197 }
198
199
200 func GenerateKey[P Point[P]](c *Curve[P], rand io.Reader) (*PrivateKey, error) {
201 fips140.RecordApproved()
202
203 k, Q, err := randomPoint(c, func(b []byte) error {
204 return drbg.ReadWithReader(rand, b)
205 })
206 if err != nil {
207 return nil, err
208 }
209
210 priv := &PrivateKey{
211 pub: PublicKey{
212 curve: c.curve,
213 q: Q.Bytes(),
214 },
215 d: k.Bytes(c.N),
216 }
217 fipsPCT(c, priv)
218 return priv, nil
219 }
220
221
222
223
224
225
226
227 func randomPoint[P Point[P]](c *Curve[P], generate func([]byte) error) (k *bigmod.Nat, p P, err error) {
228 for {
229 b := make([]byte, c.N.Size())
230 if err := generate(b); err != nil {
231 return nil, nil, err
232 }
233
234
235
236
237
238
239
240
241
242
243 if excess := len(b)*8 - c.N.BitLen(); excess > 0 {
244
245
246 if c.curve != p521 {
247 panic("ecdsa: internal error: unexpectedly masking off bits")
248 }
249 b = rightShift(b, excess)
250 }
251
252
253
254
255
256
257 if k, err := bigmod.NewNat().SetBytes(b, c.N); err == nil && k.IsZero() == 0 {
258 p, err := c.newPoint().ScalarBaseMult(k.Bytes(c.N))
259 return k, p, err
260 }
261
262 if testingOnlyRejectionSamplingLooped != nil {
263 testingOnlyRejectionSamplingLooped()
264 }
265 }
266 }
267
268
269
270 var testingOnlyRejectionSamplingLooped func()
271
272
273
274 type Signature struct {
275 R, S []byte
276 }
277
278
279
280
281
282 func Sign[P Point[P], H hash.Hash](c *Curve[P], h func() H, priv *PrivateKey, rand io.Reader, hash []byte) (*Signature, error) {
283 if priv.pub.curve != c.curve {
284 return nil, errors.New("ecdsa: private key does not match curve")
285 }
286 if len(hash) == 0 {
287 return nil, errors.New("ecdsa: hash cannot be empty")
288 }
289 fips140.RecordApproved()
290 fipsSelfTest()
291
292
293
294
295
296
297 Z := make([]byte, len(priv.d))
298 if err := drbg.ReadWithReader(rand, Z); err != nil {
299 return nil, err
300 }
301
302
303
304
305
306
307
308 drbg := newDRBG(h, Z, nil, blockAlignedPersonalizationString{priv.d, bits2octets(c, hash)})
309
310 return sign(c, priv, drbg, hash)
311 }
312
313
314
315
316
317
318 func SignDeterministic[P Point[P], H hash.Hash](c *Curve[P], h func() H, priv *PrivateKey, hash []byte) (*Signature, error) {
319 if priv.pub.curve != c.curve {
320 return nil, errors.New("ecdsa: private key does not match curve")
321 }
322 if len(hash) == 0 {
323 return nil, errors.New("ecdsa: hash cannot be empty")
324 }
325 fips140.RecordApproved()
326 fipsSelfTestDeterministic()
327 drbg := newDRBG(h, priv.d, bits2octets(c, hash), nil)
328 return sign(c, priv, drbg, hash)
329 }
330
331
332
333 func bits2octets[P Point[P]](c *Curve[P], hash []byte) []byte {
334 e := bigmod.NewNat()
335 hashToNat(c, e, hash)
336 return e.Bytes(c.N)
337 }
338
339 func signGeneric[P Point[P]](c *Curve[P], priv *PrivateKey, drbg *hmacDRBG, hash []byte) (*Signature, error) {
340
341
342 k, R, err := randomPoint(c, func(b []byte) error {
343 drbg.Generate(b)
344 return nil
345 })
346 if err != nil {
347 return nil, err
348 }
349
350
351 kInv := bigmod.NewNat()
352 inverse(c, kInv, k)
353
354 Rx, err := R.BytesX()
355 if err != nil {
356 return nil, err
357 }
358 r, err := bigmod.NewNat().SetOverflowingBytes(Rx, c.N)
359 if err != nil {
360 return nil, err
361 }
362
363
364
365
366 if r.IsZero() == 1 {
367 return nil, errors.New("ecdsa: internal error: r is zero")
368 }
369
370 e := bigmod.NewNat()
371 hashToNat(c, e, hash)
372
373 s, err := bigmod.NewNat().SetBytes(priv.d, c.N)
374 if err != nil {
375 return nil, err
376 }
377 s.Mul(r, c.N)
378 s.Add(e, c.N)
379 s.Mul(kInv, c.N)
380
381
382 if s.IsZero() == 1 {
383 return nil, errors.New("ecdsa: internal error: s is zero")
384 }
385
386 return &Signature{r.Bytes(c.N), s.Bytes(c.N)}, nil
387 }
388
389
390 func inverse[P Point[P]](c *Curve[P], kInv, k *bigmod.Nat) {
391 if c.ordInverse != nil && bits.UintSize == 64 {
392 if kb := k.Bits(); len(kb) == 4 {
393 k64 := [4]uint64{uint64(kb[0]), uint64(kb[1]), uint64(kb[2]), uint64(kb[3])}
394 c.ordInverse(&k64)
395 kInv.SetBits([]uint{uint(k64[0]), uint(k64[1]), uint(k64[2]), uint(k64[3])})
396 return
397 }
398 }
399
400
401
402 kInv.Exp(k, c.nMinus2, c.N)
403 }
404
405
406
407 func hashToNat[P Point[P]](c *Curve[P], e *bigmod.Nat, hash []byte) {
408
409
410
411
412 if size := c.N.Size(); len(hash) >= size {
413 hash = hash[:size]
414 if excess := len(hash)*8 - c.N.BitLen(); excess > 0 {
415 hash = rightShift(hash, excess)
416 }
417 }
418 _, err := e.SetOverflowingBytes(hash, c.N)
419 if err != nil {
420 panic("ecdsa: internal error: truncated hash is too long")
421 }
422 }
423
424
425
426
427
428
429 func rightShift(b []byte, shift int) []byte {
430 if shift <= 0 || shift >= 8 {
431 panic("ecdsa: internal error: shift can only be by 1 to 7 bits")
432 }
433 b = bytes.Clone(b)
434 for i := len(b) - 1; i >= 0; i-- {
435 b[i] >>= shift
436 if i > 0 {
437 b[i] |= b[i-1] << (8 - shift)
438 }
439 }
440 return b
441 }
442
443
444
445
446
447
448
449
450 func Verify[P Point[P]](c *Curve[P], pub *PublicKey, hash []byte, sig *Signature) error {
451 if pub.curve != c.curve {
452 return errors.New("ecdsa: public key does not match curve")
453 }
454 if len(hash) == 0 {
455 return errors.New("ecdsa: hash cannot be empty")
456 }
457 fips140.RecordApproved()
458 fipsSelfTest()
459 return verify(c, pub, hash, sig)
460 }
461
462 func verifyGeneric[P Point[P]](c *Curve[P], pub *PublicKey, hash []byte, sig *Signature) error {
463
464
465 Q, err := c.newPoint().SetBytes(pub.q)
466 if err != nil {
467 return err
468 }
469
470 r, err := bigmod.NewNat().SetBytes(sig.R, c.N)
471 if err != nil {
472 return err
473 }
474 if r.IsZero() == 1 {
475 return errors.New("ecdsa: invalid signature: r is zero")
476 }
477 s, err := bigmod.NewNat().SetBytes(sig.S, c.N)
478 if err != nil {
479 return err
480 }
481 if s.IsZero() == 1 {
482 return errors.New("ecdsa: invalid signature: s is zero")
483 }
484
485 e := bigmod.NewNat()
486 hashToNat(c, e, hash)
487
488
489 w := bigmod.NewNat()
490 inverse(c, w, s)
491
492
493 p1, err := c.newPoint().ScalarBaseMult(e.Mul(w, c.N).Bytes(c.N))
494 if err != nil {
495 return err
496 }
497
498 p2, err := Q.ScalarMult(Q, w.Mul(r, c.N).Bytes(c.N))
499 if err != nil {
500 return err
501 }
502
503 Rx, err := p1.Add(p1, p2).BytesX()
504 if err != nil {
505 return err
506 }
507
508 v, err := bigmod.NewNat().SetOverflowingBytes(Rx, c.N)
509 if err != nil {
510 return err
511 }
512
513 if v.Equal(r) != 1 {
514 return errors.New("ecdsa: signature did not verify")
515 }
516 return nil
517 }
518
View as plain text