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 if excess := len(b)*8 - bits; excess != 0 {
171 b[0] >>= excess
172 }
173
174
175
176
177
178 if excess := len(b)*8 - bits; excess < 7 {
179 b[0] |= 0b1100_0000 >> excess
180 } else {
181 b[0] |= 0b0000_0001
182 b[1] |= 0b1000_0000
183 }
184
185
186 b[len(b)-1] |= 1
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204 if isPrime(b) {
205 return b, nil
206 }
207 }
208 }
209
210
211
212
213
214
215
216
217 func isPrime(w []byte) bool {
218 mr, err := millerRabinSetup(w)
219 if err != nil {
220
221 return false
222 }
223
224 primes, err := bigmod.NewNat().SetBytes(productOfPrimes, mr.w)
225
226
227 if err == nil {
228 _, hasInverse := primes.InverseVarTime(primes, mr.w)
229 if !hasInverse {
230
231
232 return false
233 }
234 }
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249 bits := mr.w.BitLen()
250 var iterations int
251 switch {
252 case bits >= 3747:
253 iterations = 3
254 case bits >= 1345:
255 iterations = 4
256 case bits >= 476:
257 iterations = 5
258 case bits >= 400:
259 iterations = 6
260 case bits >= 347:
261 iterations = 7
262 case bits >= 308:
263 iterations = 8
264 case bits >= 55:
265 iterations = 27
266 default:
267 iterations = 34
268 }
269
270 b := make([]byte, (bits+7)/8)
271 for {
272 drbg.Read(b)
273 if excess := len(b)*8 - bits; excess != 0 {
274 b[0] >>= excess
275 }
276 result, err := millerRabinIteration(mr, b)
277 if err != nil {
278
279 continue
280 }
281 if result == millerRabinCOMPOSITE {
282 return false
283 }
284 iterations--
285 if iterations == 0 {
286 return true
287 }
288 }
289 }
290
291
292
293
294
295
296
297
298 var productOfPrimes = []byte{
299 0x10, 0x6a, 0xa9, 0xfb, 0x76, 0x46, 0xfa, 0x6e, 0xb0, 0x81, 0x3c, 0x28, 0xc5, 0xd5, 0xf0, 0x9f,
300 0x07, 0x7e, 0xc3, 0xba, 0x23, 0x8b, 0xfb, 0x99, 0xc1, 0xb6, 0x31, 0xa2, 0x03, 0xe8, 0x11, 0x87,
301 0x23, 0x3d, 0xb1, 0x17, 0xcb, 0xc3, 0x84, 0x05, 0x6e, 0xf0, 0x46, 0x59, 0xa4, 0xa1, 0x1d, 0xe4,
302 0x9f, 0x7e, 0xcb, 0x29, 0xba, 0xda, 0x8f, 0x98, 0x0d, 0xec, 0xec, 0xe9, 0x2e, 0x30, 0xc4, 0x8f,
303 }
304
305 type millerRabin struct {
306 w *bigmod.Modulus
307 a uint
308 m []byte
309 }
310
311
312
313 func millerRabinSetup(w []byte) (*millerRabin, error) {
314 mr := &millerRabin{}
315
316
317 wm, err := bigmod.NewModulus(w)
318 if err != nil {
319 return nil, err
320 }
321 if wm.Nat().IsOdd() == 0 {
322 return nil, errors.New("candidate is even")
323 }
324 mr.w = wm
325
326
327 wMinus1 := mr.w.Nat().SubOne(mr.w)
328 if wMinus1.IsZero() == 1 {
329 return nil, errors.New("candidate is one")
330 }
331 mr.a = wMinus1.TrailingZeroBitsVarTime()
332
333
334
335 m := wMinus1.ShiftRightVarTime(mr.a)
336 mr.m = m.Bytes(mr.w)
337 for mr.m[0] == 0 {
338 mr.m = mr.m[1:]
339 }
340
341 return mr, nil
342 }
343
344 const millerRabinCOMPOSITE = false
345 const millerRabinPOSSIBLYPRIME = true
346
347 func millerRabinIteration(mr *millerRabin, bb []byte) (bool, error) {
348
349 if len(bb) != (mr.w.BitLen()+7)/8 {
350 return false, errors.New("incorrect length")
351 }
352 b := bigmod.NewNat()
353 if _, err := b.SetBytes(bb, mr.w); err != nil {
354 return false, err
355 }
356 if b.IsZero() == 1 || b.IsOne() == 1 || b.IsMinusOne(mr.w) == 1 {
357 return false, errors.New("out-of-range candidate")
358 }
359
360
361
362
363
364
365
366 z := bigmod.NewNat().Exp(b, mr.m, mr.w)
367 if z.IsOne() == 1 || z.IsMinusOne(mr.w) == 1 {
368 return millerRabinPOSSIBLYPRIME, nil
369 }
370
371
372 for range mr.a - 1 {
373 z.Mul(z, mr.w)
374 if z.IsMinusOne(mr.w) == 1 {
375 return millerRabinPOSSIBLYPRIME, nil
376 }
377 if z.IsOne() == 1 {
378
379 break
380 }
381 }
382
383 return millerRabinCOMPOSITE, nil
384 }
385
View as plain text