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