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 φ, err := bigmod.NewModulusProduct(P.Nat().SubOne(P).Bytes(P),
58 Q.Nat().SubOne(Q).Bytes(Q))
59 if err != nil {
60 return nil, err
61 }
62
63 e := bigmod.NewNat().SetUint(65537)
64 d, ok := bigmod.NewNat().InverseVarTime(e, φ)
65 if !ok {
66
67
68
69 continue
70 }
71
72 if e.ExpandFor(φ).Mul(d, φ).IsOne() == 0 {
73 return nil, errors.New("rsa: internal error: e*d != 1 mod φ(N)")
74 }
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 return newPrivateKey(N, 65537, d, P, Q)
90 }
91 }
92
93
94
95 func randomPrime(rand io.Reader, bits int) ([]byte, error) {
96 if bits < 16 {
97 return nil, errors.New("rsa: prime size must be at least 16 bits")
98 }
99
100 b := make([]byte, (bits+7)/8)
101 for {
102 if err := drbg.ReadWithReader(rand, b); err != nil {
103 return nil, err
104 }
105 if excess := len(b)*8 - bits; excess != 0 {
106 b[0] >>= excess
107 }
108
109
110
111
112
113 if excess := len(b)*8 - bits; excess < 7 {
114 b[0] |= 0b1100_0000 >> excess
115 } else {
116 b[0] |= 0b0000_0001
117 b[1] |= 0b1000_0000
118 }
119
120
121 b[len(b)-1] |= 1
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139 if isPrime(b) {
140 return b, nil
141 }
142 }
143 }
144
145
146
147
148
149
150
151
152 func isPrime(w []byte) bool {
153 mr, err := millerRabinSetup(w)
154 if err != nil {
155
156 return false
157 }
158
159 primes, err := bigmod.NewNat().SetBytes(productOfPrimes, mr.w)
160
161
162 if err == nil {
163 _, hasInverse := primes.InverseVarTime(primes, mr.w)
164 if !hasInverse {
165
166
167 return false
168 }
169 }
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184 bits := mr.w.BitLen()
185 var iterations int
186 switch {
187 case bits >= 3747:
188 iterations = 3
189 case bits >= 1345:
190 iterations = 4
191 case bits >= 476:
192 iterations = 5
193 case bits >= 400:
194 iterations = 6
195 case bits >= 347:
196 iterations = 7
197 case bits >= 308:
198 iterations = 8
199 case bits >= 55:
200 iterations = 27
201 default:
202 iterations = 34
203 }
204
205 b := make([]byte, (bits+7)/8)
206 for {
207 drbg.Read(b)
208 if excess := len(b)*8 - bits; excess != 0 {
209 b[0] >>= excess
210 }
211 result, err := millerRabinIteration(mr, b)
212 if err != nil {
213
214 continue
215 }
216 if result == millerRabinCOMPOSITE {
217 return false
218 }
219 iterations--
220 if iterations == 0 {
221 return true
222 }
223 }
224 }
225
226
227
228
229
230
231
232
233 var productOfPrimes = []byte{
234 0x10, 0x6a, 0xa9, 0xfb, 0x76, 0x46, 0xfa, 0x6e, 0xb0, 0x81, 0x3c, 0x28, 0xc5, 0xd5, 0xf0, 0x9f,
235 0x07, 0x7e, 0xc3, 0xba, 0x23, 0x8b, 0xfb, 0x99, 0xc1, 0xb6, 0x31, 0xa2, 0x03, 0xe8, 0x11, 0x87,
236 0x23, 0x3d, 0xb1, 0x17, 0xcb, 0xc3, 0x84, 0x05, 0x6e, 0xf0, 0x46, 0x59, 0xa4, 0xa1, 0x1d, 0xe4,
237 0x9f, 0x7e, 0xcb, 0x29, 0xba, 0xda, 0x8f, 0x98, 0x0d, 0xec, 0xec, 0xe9, 0x2e, 0x30, 0xc4, 0x8f,
238 }
239
240 type millerRabin struct {
241 w *bigmod.Modulus
242 a uint
243 m []byte
244 }
245
246
247
248 func millerRabinSetup(w []byte) (*millerRabin, error) {
249 mr := &millerRabin{}
250
251
252 wm, err := bigmod.NewModulus(w)
253 if err != nil {
254 return nil, err
255 }
256 if wm.Nat().IsOdd() == 0 {
257 return nil, errors.New("candidate is even")
258 }
259 mr.w = wm
260
261
262 wMinus1 := mr.w.Nat().SubOne(mr.w)
263 if wMinus1.IsZero() == 1 {
264 return nil, errors.New("candidate is one")
265 }
266 mr.a = wMinus1.TrailingZeroBitsVarTime()
267
268
269
270 m := wMinus1.ShiftRightVarTime(mr.a)
271 mr.m = m.Bytes(mr.w)
272 for mr.m[0] == 0 {
273 mr.m = mr.m[1:]
274 }
275
276 return mr, nil
277 }
278
279 const millerRabinCOMPOSITE = false
280 const millerRabinPOSSIBLYPRIME = true
281
282 func millerRabinIteration(mr *millerRabin, bb []byte) (bool, error) {
283
284 if len(bb) != (mr.w.BitLen()+7)/8 {
285 return false, errors.New("incorrect length")
286 }
287 b := bigmod.NewNat()
288 if _, err := b.SetBytes(bb, mr.w); err != nil {
289 return false, err
290 }
291 if b.IsZero() == 1 || b.IsOne() == 1 || b.IsMinusOne(mr.w) == 1 {
292 return false, errors.New("out-of-range candidate")
293 }
294
295
296
297
298
299
300
301 z := bigmod.NewNat().Exp(b, mr.m, mr.w)
302 if z.IsOne() == 1 || z.IsMinusOne(mr.w) == 1 {
303 return millerRabinPOSSIBLYPRIME, nil
304 }
305
306
307 for range mr.a - 1 {
308 z.Mul(z, mr.w)
309 if z.IsMinusOne(mr.w) == 1 {
310 return millerRabinPOSSIBLYPRIME, nil
311 }
312 if z.IsOne() == 1 {
313
314 break
315 }
316 }
317
318 return millerRabinCOMPOSITE, nil
319 }
320
View as plain text