1
2
3
4
5 package rsa
6
7 import (
8 "crypto/internal/fips140"
9 "crypto/internal/fips140/bigmod"
10 "crypto/internal/fips140/drbg"
11 "errors"
12 "io"
13 )
14
15
16
17 func GenerateKey(rand io.Reader, bits int) (*PrivateKey, error) {
18 if bits < 32 {
19 return nil, errors.New("rsa: key too small")
20 }
21 fips140.RecordApproved()
22 if bits < 2048 || bits%2 == 1 {
23 fips140.RecordNonApproved()
24 }
25
26 for {
27 p, err := randomPrime(rand, (bits+1)/2)
28 if err != nil {
29 return nil, err
30 }
31 q, err := randomPrime(rand, bits/2)
32 if err != nil {
33 return nil, err
34 }
35
36 P, err := bigmod.NewModulus(p)
37 if err != nil {
38 return nil, err
39 }
40 Q, err := bigmod.NewModulus(q)
41 if err != nil {
42 return nil, err
43 }
44
45 if Q.Nat().ExpandFor(P).Equal(P.Nat()) == 1 {
46 return nil, errors.New("rsa: generated p == q, random source is broken")
47 }
48
49 N, err := bigmod.NewModulusProduct(p, q)
50 if err != nil {
51 return nil, err
52 }
53 if N.BitLen() != bits {
54 return nil, errors.New("rsa: internal error: modulus size incorrect")
55 }
56
57
58
59
60
61
62
63
64
65
66
67
68
69 λ, err := totient(P, Q)
70 if err == errDivisorTooLarge {
71
72 continue
73 }
74 if err != nil {
75 return nil, err
76 }
77
78 e := bigmod.NewNat().SetUint(65537)
79 d, ok := bigmod.NewNat().InverseVarTime(e, λ)
80 if !ok {
81
82
83
84
85
86
87
88 continue
89 }
90
91 if e.ExpandFor(λ).Mul(d, λ).IsOne() == 0 {
92 return nil, errors.New("rsa: internal error: e*d != 1 mod λ(N)")
93 }
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 return newPrivateKey(N, 65537, d, P, Q)
109 }
110 }
111
112
113 var errDivisorTooLarge = errors.New("divisor too large")
114
115
116 func totient(p, q *bigmod.Modulus) (*bigmod.Modulus, error) {
117 a, b := p.Nat().SubOne(p), q.Nat().SubOne(q)
118
119
120
121
122
123
124
125 az, bz := a.TrailingZeroBitsVarTime(), b.TrailingZeroBitsVarTime()
126 if az < bz {
127 a = a.ShiftRightVarTime(az)
128 } else {
129 b = b.ShiftRightVarTime(bz)
130 }
131
132 gcd, err := bigmod.NewNat().GCDVarTime(a, b)
133 if err != nil {
134 return nil, err
135 }
136 if gcd.IsOdd() == 0 {
137 return nil, errors.New("rsa: internal error: gcd(a, b) is even")
138 }
139
140
141
142
143
144
145 if gcd.BitLenVarTime() > 32 {
146 return nil, errDivisorTooLarge
147 }
148 if gcd.IsZero() == 1 || gcd.Bits()[0] == 0 {
149 return nil, errors.New("rsa: internal error: gcd(a, b) is zero")
150 }
151 if rem := b.DivShortVarTime(gcd.Bits()[0]); rem != 0 {
152 return nil, errors.New("rsa: internal error: b is not divisible by gcd(a, b)")
153 }
154
155 return bigmod.NewModulusProduct(a.Bytes(p), b.Bytes(q))
156 }
157
158
159
160 func randomPrime(rand io.Reader, bits int) ([]byte, error) {
161 if bits < 16 {
162 return nil, errors.New("rsa: prime size must be at least 16 bits")
163 }
164
165 b := make([]byte, (bits+7)/8)
166 for {
167 if err := drbg.ReadWithReader(rand, b); err != nil {
168 return nil, err
169 }
170
171
172
173 excess := len(b)*8 - bits
174 b[0] &= 0b1111_1111 >> excess
175
176
177
178
179
180 if excess < 7 {
181 b[0] |= 0b1100_0000 >> excess
182 } else {
183 b[0] |= 0b0000_0001
184 b[1] |= 0b1000_0000
185 }
186
187
188 b[len(b)-1] |= 1
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 if isPrime(b) {
207 return b, nil
208 }
209 }
210 }
211
212
213
214
215
216
217
218
219 func isPrime(w []byte) bool {
220 mr, err := millerRabinSetup(w)
221 if err != nil {
222
223 return false
224 }
225
226 primes, err := bigmod.NewNat().SetBytes(productOfPrimes, mr.w)
227
228
229 if err == nil {
230 _, hasInverse := primes.InverseVarTime(primes, mr.w)
231 if !hasInverse {
232
233
234 return false
235 }
236 }
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251 bits := mr.w.BitLen()
252 var iterations int
253 switch {
254 case bits >= 3747:
255 iterations = 3
256 case bits >= 1345:
257 iterations = 4
258 case bits >= 476:
259 iterations = 5
260 case bits >= 400:
261 iterations = 6
262 case bits >= 347:
263 iterations = 7
264 case bits >= 308:
265 iterations = 8
266 case bits >= 55:
267 iterations = 27
268 default:
269 iterations = 34
270 }
271
272 b := make([]byte, (bits+7)/8)
273 for {
274 drbg.Read(b)
275 excess := len(b)*8 - bits
276 b[0] &= 0b1111_1111 >> excess
277 result, err := millerRabinIteration(mr, b)
278 if err != nil {
279
280 continue
281 }
282 if result == millerRabinCOMPOSITE {
283 return false
284 }
285 iterations--
286 if iterations == 0 {
287 return true
288 }
289 }
290 }
291
292
293
294
295
296
297
298
299
300
301 var productOfPrimes = []byte{
302 0x10, 0x6a, 0xa9, 0xfb, 0x76, 0x46, 0xfa, 0x6e, 0xb0, 0x81, 0x3c, 0x28, 0xc5, 0xd5, 0xf0, 0x9f,
303 0x07, 0x7e, 0xc3, 0xba, 0x23, 0x8b, 0xfb, 0x99, 0xc1, 0xb6, 0x31, 0xa2, 0x03, 0xe8, 0x11, 0x87,
304 0x23, 0x3d, 0xb1, 0x17, 0xcb, 0xc3, 0x84, 0x05, 0x6e, 0xf0, 0x46, 0x59, 0xa4, 0xa1, 0x1d, 0xe4,
305 0x9f, 0x7e, 0xcb, 0x29, 0xba, 0xda, 0x8f, 0x98, 0x0d, 0xec, 0xec, 0xe9, 0x2e, 0x30, 0xc4, 0x8f,
306 }
307
308 type millerRabin struct {
309 w *bigmod.Modulus
310 a uint
311 m []byte
312 }
313
314
315
316 func millerRabinSetup(w []byte) (*millerRabin, error) {
317 mr := &millerRabin{}
318
319
320 wm, err := bigmod.NewModulus(w)
321 if err != nil {
322 return nil, err
323 }
324 if wm.Nat().IsOdd() == 0 {
325 return nil, errors.New("candidate is even")
326 }
327 mr.w = wm
328
329
330 wMinus1 := mr.w.Nat().SubOne(mr.w)
331 if wMinus1.IsZero() == 1 {
332 return nil, errors.New("candidate is one")
333 }
334 mr.a = wMinus1.TrailingZeroBitsVarTime()
335
336
337
338 m := wMinus1.ShiftRightVarTime(mr.a)
339 mr.m = m.Bytes(mr.w)
340 for mr.m[0] == 0 {
341 mr.m = mr.m[1:]
342 }
343
344 return mr, nil
345 }
346
347 const millerRabinCOMPOSITE = false
348 const millerRabinPOSSIBLYPRIME = true
349
350 func millerRabinIteration(mr *millerRabin, bb []byte) (bool, error) {
351
352 if len(bb) != (mr.w.BitLen()+7)/8 {
353 return false, errors.New("incorrect length")
354 }
355 b := bigmod.NewNat()
356 if _, err := b.SetBytes(bb, mr.w); err != nil {
357 return false, err
358 }
359 if b.IsZero() == 1 || b.IsOne() == 1 || b.IsMinusOne(mr.w) == 1 {
360 return false, errors.New("out-of-range candidate")
361 }
362
363
364
365
366
367
368
369 z := bigmod.NewNat().Exp(b, mr.m, mr.w)
370 if z.IsOne() == 1 || z.IsMinusOne(mr.w) == 1 {
371 return millerRabinPOSSIBLYPRIME, nil
372 }
373
374
375 for range mr.a - 1 {
376 z.Mul(z, mr.w)
377 if z.IsMinusOne(mr.w) == 1 {
378 return millerRabinPOSSIBLYPRIME, nil
379 }
380 if z.IsOne() == 1 {
381
382 break
383 }
384 }
385
386 return millerRabinCOMPOSITE, nil
387 }
388
View as plain text