diff options
Diffstat (limited to 'src/lib/libcrypto/bn/bn_gcd.c')
-rw-r--r-- | src/lib/libcrypto/bn/bn_gcd.c | 570 |
1 files changed, 296 insertions, 274 deletions
diff --git a/src/lib/libcrypto/bn/bn_gcd.c b/src/lib/libcrypto/bn/bn_gcd.c index a808f53178..18f2812368 100644 --- a/src/lib/libcrypto/bn/bn_gcd.c +++ b/src/lib/libcrypto/bn/bn_gcd.c | |||
@@ -5,21 +5,21 @@ | |||
5 | * This package is an SSL implementation written | 5 | * This package is an SSL implementation written |
6 | * by Eric Young (eay@cryptsoft.com). | 6 | * by Eric Young (eay@cryptsoft.com). |
7 | * The implementation was written so as to conform with Netscapes SSL. | 7 | * The implementation was written so as to conform with Netscapes SSL. |
8 | * | 8 | * |
9 | * This library is free for commercial and non-commercial use as long as | 9 | * This library is free for commercial and non-commercial use as long as |
10 | * the following conditions are aheared to. The following conditions | 10 | * the following conditions are aheared to. The following conditions |
11 | * apply to all code found in this distribution, be it the RC4, RSA, | 11 | * apply to all code found in this distribution, be it the RC4, RSA, |
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | 12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
13 | * included with this distribution is covered by the same copyright terms | 13 | * included with this distribution is covered by the same copyright terms |
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | 14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
15 | * | 15 | * |
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | 16 | * Copyright remains Eric Young's, and as such any Copyright notices in |
17 | * the code are not to be removed. | 17 | * the code are not to be removed. |
18 | * If this package is used in a product, Eric Young should be given attribution | 18 | * If this package is used in a product, Eric Young should be given attribution |
19 | * as the author of the parts of the library used. | 19 | * as the author of the parts of the library used. |
20 | * This can be in the form of a textual message at program startup or | 20 | * This can be in the form of a textual message at program startup or |
21 | * in documentation (online or textual) provided with the package. | 21 | * in documentation (online or textual) provided with the package. |
22 | * | 22 | * |
23 | * Redistribution and use in source and binary forms, with or without | 23 | * Redistribution and use in source and binary forms, with or without |
24 | * modification, are permitted provided that the following conditions | 24 | * modification, are permitted provided that the following conditions |
25 | * are met: | 25 | * are met: |
@@ -34,10 +34,10 @@ | |||
34 | * Eric Young (eay@cryptsoft.com)" | 34 | * Eric Young (eay@cryptsoft.com)" |
35 | * The word 'cryptographic' can be left out if the rouines from the library | 35 | * The word 'cryptographic' can be left out if the rouines from the library |
36 | * being used are not cryptographic related :-). | 36 | * being used are not cryptographic related :-). |
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | 37 | * 4. If you include any Windows specific code (or a derivative thereof) from |
38 | * the apps directory (application code) you must include an acknowledgement: | 38 | * the apps directory (application code) you must include an acknowledgement: |
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | 39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
40 | * | 40 | * |
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | 41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
@@ -49,7 +49,7 @@ | |||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
51 | * SUCH DAMAGE. | 51 | * SUCH DAMAGE. |
52 | * | 52 | * |
53 | * The licence and distribution terms for any publically available version or | 53 | * The licence and distribution terms for any publically available version or |
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | 54 | * derivative of this code cannot be changed. i.e. this code cannot simply be |
55 | * copied and put under another distribution licence | 55 | * copied and put under another distribution licence |
@@ -63,7 +63,7 @@ | |||
63 | * are met: | 63 | * are met: |
64 | * | 64 | * |
65 | * 1. Redistributions of source code must retain the above copyright | 65 | * 1. Redistributions of source code must retain the above copyright |
66 | * notice, this list of conditions and the following disclaimer. | 66 | * notice, this list of conditions and the following disclaimer. |
67 | * | 67 | * |
68 | * 2. Redistributions in binary form must reproduce the above copyright | 68 | * 2. Redistributions in binary form must reproduce the above copyright |
69 | * notice, this list of conditions and the following disclaimer in | 69 | * notice, this list of conditions and the following disclaimer in |
@@ -114,10 +114,11 @@ | |||
114 | 114 | ||
115 | static BIGNUM *euclid(BIGNUM *a, BIGNUM *b); | 115 | static BIGNUM *euclid(BIGNUM *a, BIGNUM *b); |
116 | 116 | ||
117 | int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) | 117 | int |
118 | { | 118 | BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) |
119 | BIGNUM *a,*b,*t; | 119 | { |
120 | int ret=0; | 120 | BIGNUM *a, *b, *t; |
121 | int ret = 0; | ||
121 | 122 | ||
122 | bn_check_top(in_a); | 123 | bn_check_top(in_a); |
123 | bn_check_top(in_b); | 124 | bn_check_top(in_b); |
@@ -125,98 +126,121 @@ int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) | |||
125 | BN_CTX_start(ctx); | 126 | BN_CTX_start(ctx); |
126 | a = BN_CTX_get(ctx); | 127 | a = BN_CTX_get(ctx); |
127 | b = BN_CTX_get(ctx); | 128 | b = BN_CTX_get(ctx); |
128 | if (a == NULL || b == NULL) goto err; | 129 | if (a == NULL || b == NULL) |
130 | goto err; | ||
129 | 131 | ||
130 | if (BN_copy(a,in_a) == NULL) goto err; | 132 | if (BN_copy(a, in_a) == NULL) |
131 | if (BN_copy(b,in_b) == NULL) goto err; | 133 | goto err; |
134 | if (BN_copy(b, in_b) == NULL) | ||
135 | goto err; | ||
132 | a->neg = 0; | 136 | a->neg = 0; |
133 | b->neg = 0; | 137 | b->neg = 0; |
134 | 138 | ||
135 | if (BN_cmp(a,b) < 0) { t=a; a=b; b=t; } | 139 | if (BN_cmp(a, b) < 0) { |
136 | t=euclid(a,b); | 140 | t = a; |
137 | if (t == NULL) goto err; | 141 | a = b; |
142 | b = t; | ||
143 | } | ||
144 | t = euclid(a, b); | ||
145 | if (t == NULL) | ||
146 | goto err; | ||
147 | |||
148 | if (BN_copy(r, t) == NULL) | ||
149 | goto err; | ||
150 | ret = 1; | ||
138 | 151 | ||
139 | if (BN_copy(r,t) == NULL) goto err; | ||
140 | ret=1; | ||
141 | err: | 152 | err: |
142 | BN_CTX_end(ctx); | 153 | BN_CTX_end(ctx); |
143 | bn_check_top(r); | 154 | bn_check_top(r); |
144 | return(ret); | 155 | return (ret); |
145 | } | 156 | } |
146 | 157 | ||
147 | static BIGNUM *euclid(BIGNUM *a, BIGNUM *b) | 158 | static BIGNUM * |
148 | { | 159 | euclid(BIGNUM *a, BIGNUM *b) |
160 | { | ||
149 | BIGNUM *t; | 161 | BIGNUM *t; |
150 | int shifts=0; | 162 | int shifts = 0; |
151 | 163 | ||
152 | bn_check_top(a); | 164 | bn_check_top(a); |
153 | bn_check_top(b); | 165 | bn_check_top(b); |
154 | 166 | ||
155 | /* 0 <= b <= a */ | 167 | /* 0 <= b <= a */ |
156 | while (!BN_is_zero(b)) | 168 | while (!BN_is_zero(b)) { |
157 | { | ||
158 | /* 0 < b <= a */ | 169 | /* 0 < b <= a */ |
159 | 170 | ||
160 | if (BN_is_odd(a)) | 171 | if (BN_is_odd(a)) { |
161 | { | 172 | if (BN_is_odd(b)) { |
162 | if (BN_is_odd(b)) | 173 | if (!BN_sub(a, a, b)) |
163 | { | 174 | goto err; |
164 | if (!BN_sub(a,a,b)) goto err; | 175 | if (!BN_rshift1(a, a)) |
165 | if (!BN_rshift1(a,a)) goto err; | 176 | goto err; |
166 | if (BN_cmp(a,b) < 0) | 177 | if (BN_cmp(a, b) < 0) { |
167 | { t=a; a=b; b=t; } | 178 | t = a; |
179 | a = b; | ||
180 | b = t; | ||
168 | } | 181 | } |
182 | } | ||
169 | else /* a odd - b even */ | 183 | else /* a odd - b even */ |
170 | { | 184 | { |
171 | if (!BN_rshift1(b,b)) goto err; | 185 | if (!BN_rshift1(b, b)) |
172 | if (BN_cmp(a,b) < 0) | 186 | goto err; |
173 | { t=a; a=b; b=t; } | 187 | if (BN_cmp(a, b) < 0) { |
188 | t = a; | ||
189 | a = b; | ||
190 | b = t; | ||
174 | } | 191 | } |
175 | } | 192 | } |
193 | } | ||
176 | else /* a is even */ | 194 | else /* a is even */ |
177 | { | 195 | { |
178 | if (BN_is_odd(b)) | 196 | if (BN_is_odd(b)) { |
179 | { | 197 | if (!BN_rshift1(a, a)) |
180 | if (!BN_rshift1(a,a)) goto err; | 198 | goto err; |
181 | if (BN_cmp(a,b) < 0) | 199 | if (BN_cmp(a, b) < 0) { |
182 | { t=a; a=b; b=t; } | 200 | t = a; |
201 | a = b; | ||
202 | b = t; | ||
183 | } | 203 | } |
204 | } | ||
184 | else /* a even - b even */ | 205 | else /* a even - b even */ |
185 | { | 206 | { |
186 | if (!BN_rshift1(a,a)) goto err; | 207 | if (!BN_rshift1(a, a)) |
187 | if (!BN_rshift1(b,b)) goto err; | 208 | goto err; |
209 | if (!BN_rshift1(b, b)) | ||
210 | goto err; | ||
188 | shifts++; | 211 | shifts++; |
189 | } | ||
190 | } | 212 | } |
191 | /* 0 <= b <= a */ | ||
192 | } | 213 | } |
214 | /* 0 <= b <= a */ | ||
215 | } | ||
193 | 216 | ||
194 | if (shifts) | 217 | if (shifts) { |
195 | { | 218 | if (!BN_lshift(a, a, shifts)) |
196 | if (!BN_lshift(a,a,shifts)) goto err; | 219 | goto err; |
197 | } | 220 | } |
198 | bn_check_top(a); | 221 | bn_check_top(a); |
199 | return(a); | 222 | return (a); |
223 | |||
200 | err: | 224 | err: |
201 | return(NULL); | 225 | return (NULL); |
202 | } | 226 | } |
203 | 227 | ||
204 | 228 | ||
205 | /* solves ax == 1 (mod n) */ | 229 | /* solves ax == 1 (mod n) */ |
206 | static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, | 230 | static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, |
207 | const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); | 231 | const BIGNUM *n, BN_CTX *ctx); |
208 | 232 | ||
209 | BIGNUM *BN_mod_inverse(BIGNUM *in, | 233 | BIGNUM * |
210 | const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) | 234 | BN_mod_inverse(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) |
211 | { | 235 | { |
212 | BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL; | 236 | BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; |
213 | BIGNUM *ret=NULL; | 237 | BIGNUM *ret = NULL; |
214 | int sign; | 238 | int sign; |
215 | 239 | ||
216 | if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) | 240 | if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || |
217 | { | 241 | (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) { |
218 | return BN_mod_inverse_no_branch(in, a, n, ctx); | 242 | return BN_mod_inverse_no_branch(in, a, n, ctx); |
219 | } | 243 | } |
220 | 244 | ||
221 | bn_check_top(a); | 245 | bn_check_top(a); |
222 | bn_check_top(n); | 246 | bn_check_top(n); |
@@ -229,23 +253,27 @@ BIGNUM *BN_mod_inverse(BIGNUM *in, | |||
229 | M = BN_CTX_get(ctx); | 253 | M = BN_CTX_get(ctx); |
230 | Y = BN_CTX_get(ctx); | 254 | Y = BN_CTX_get(ctx); |
231 | T = BN_CTX_get(ctx); | 255 | T = BN_CTX_get(ctx); |
232 | if (T == NULL) goto err; | 256 | if (T == NULL) |
257 | goto err; | ||
233 | 258 | ||
234 | if (in == NULL) | 259 | if (in == NULL) |
235 | R=BN_new(); | 260 | R = BN_new(); |
236 | else | 261 | else |
237 | R=in; | 262 | R = in; |
238 | if (R == NULL) goto err; | 263 | if (R == NULL) |
264 | goto err; | ||
239 | 265 | ||
240 | BN_one(X); | 266 | BN_one(X); |
241 | BN_zero(Y); | 267 | BN_zero(Y); |
242 | if (BN_copy(B,a) == NULL) goto err; | 268 | if (BN_copy(B, a) == NULL) |
243 | if (BN_copy(A,n) == NULL) goto err; | 269 | goto err; |
270 | if (BN_copy(A, n) == NULL) | ||
271 | goto err; | ||
244 | A->neg = 0; | 272 | A->neg = 0; |
245 | if (B->neg || (BN_ucmp(B, A) >= 0)) | 273 | if (B->neg || (BN_ucmp(B, A) >= 0)) { |
246 | { | 274 | if (!BN_nnmod(B, B, A, ctx)) |
247 | if (!BN_nnmod(B, B, A, ctx)) goto err; | 275 | goto err; |
248 | } | 276 | } |
249 | sign = -1; | 277 | sign = -1; |
250 | /* From B = a mod |n|, A = |n| it follows that | 278 | /* From B = a mod |n|, A = |n| it follows that |
251 | * | 279 | * |
@@ -254,16 +282,14 @@ BIGNUM *BN_mod_inverse(BIGNUM *in, | |||
254 | * sign*Y*a == A (mod |n|). | 282 | * sign*Y*a == A (mod |n|). |
255 | */ | 283 | */ |
256 | 284 | ||
257 | if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) | 285 | if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) { |
258 | { | ||
259 | /* Binary inversion algorithm; requires odd modulus. | 286 | /* Binary inversion algorithm; requires odd modulus. |
260 | * This is faster than the general algorithm if the modulus | 287 | * This is faster than the general algorithm if the modulus |
261 | * is sufficiently small (about 400 .. 500 bits on 32-bit | 288 | * is sufficiently small (about 400 .. 500 bits on 32-bit |
262 | * sytems, but much more on 64-bit systems) */ | 289 | * sytems, but much more on 64-bit systems) */ |
263 | int shift; | 290 | int shift; |
264 | 291 | ||
265 | while (!BN_is_zero(B)) | 292 | while (!BN_is_zero(B)) { |
266 | { | ||
267 | /* | 293 | /* |
268 | * 0 < B < |n|, | 294 | * 0 < B < |n|, |
269 | * 0 < A <= |n|, | 295 | * 0 < A <= |n|, |
@@ -276,41 +302,43 @@ BIGNUM *BN_mod_inverse(BIGNUM *in, | |||
276 | * When we're done, (1) still holds. */ | 302 | * When we're done, (1) still holds. */ |
277 | shift = 0; | 303 | shift = 0; |
278 | while (!BN_is_bit_set(B, shift)) /* note that 0 < B */ | 304 | while (!BN_is_bit_set(B, shift)) /* note that 0 < B */ |
279 | { | 305 | { |
280 | shift++; | 306 | shift++; |
281 | 307 | ||
282 | if (BN_is_odd(X)) | 308 | if (BN_is_odd(X)) { |
283 | { | 309 | if (!BN_uadd(X, X, n)) |
284 | if (!BN_uadd(X, X, n)) goto err; | 310 | goto err; |
285 | } | ||
286 | /* now X is even, so we can easily divide it by two */ | ||
287 | if (!BN_rshift1(X, X)) goto err; | ||
288 | } | ||
289 | if (shift > 0) | ||
290 | { | ||
291 | if (!BN_rshift(B, B, shift)) goto err; | ||
292 | } | 311 | } |
312 | /* now X is even, so we can easily divide it by two */ | ||
313 | if (!BN_rshift1(X, X)) | ||
314 | goto err; | ||
315 | } | ||
316 | if (shift > 0) { | ||
317 | if (!BN_rshift(B, B, shift)) | ||
318 | goto err; | ||
319 | } | ||
293 | 320 | ||
294 | 321 | ||
295 | /* Same for A and Y. Afterwards, (2) still holds. */ | 322 | /* Same for A and Y. Afterwards, (2) still holds. */ |
296 | shift = 0; | 323 | shift = 0; |
297 | while (!BN_is_bit_set(A, shift)) /* note that 0 < A */ | 324 | while (!BN_is_bit_set(A, shift)) /* note that 0 < A */ |
298 | { | 325 | { |
299 | shift++; | 326 | shift++; |
300 | 327 | ||
301 | if (BN_is_odd(Y)) | 328 | if (BN_is_odd(Y)) { |
302 | { | 329 | if (!BN_uadd(Y, Y, n)) |
303 | if (!BN_uadd(Y, Y, n)) goto err; | 330 | goto err; |
304 | } | ||
305 | /* now Y is even */ | ||
306 | if (!BN_rshift1(Y, Y)) goto err; | ||
307 | } | ||
308 | if (shift > 0) | ||
309 | { | ||
310 | if (!BN_rshift(A, A, shift)) goto err; | ||
311 | } | 331 | } |
332 | /* now Y is even */ | ||
333 | if (!BN_rshift1(Y, Y)) | ||
334 | goto err; | ||
335 | } | ||
336 | if (shift > 0) { | ||
337 | if (!BN_rshift(A, A, shift)) | ||
338 | goto err; | ||
339 | } | ||
340 | |||
312 | 341 | ||
313 | |||
314 | /* We still have (1) and (2). | 342 | /* We still have (1) and (2). |
315 | * Both A and B are odd. | 343 | * Both A and B are odd. |
316 | * The following computations ensure that | 344 | * The following computations ensure that |
@@ -322,91 +350,87 @@ BIGNUM *BN_mod_inverse(BIGNUM *in, | |||
322 | * | 350 | * |
323 | * and that either A or B is even in the next iteration. | 351 | * and that either A or B is even in the next iteration. |
324 | */ | 352 | */ |
325 | if (BN_ucmp(B, A) >= 0) | 353 | if (BN_ucmp(B, A) >= 0) { |
326 | { | ||
327 | /* -sign*(X + Y)*a == B - A (mod |n|) */ | 354 | /* -sign*(X + Y)*a == B - A (mod |n|) */ |
328 | if (!BN_uadd(X, X, Y)) goto err; | 355 | if (!BN_uadd(X, X, Y)) |
356 | goto err; | ||
329 | /* NB: we could use BN_mod_add_quick(X, X, Y, n), but that | 357 | /* NB: we could use BN_mod_add_quick(X, X, Y, n), but that |
330 | * actually makes the algorithm slower */ | 358 | * actually makes the algorithm slower */ |
331 | if (!BN_usub(B, B, A)) goto err; | 359 | if (!BN_usub(B, B, A)) |
332 | } | 360 | goto err; |
333 | else | 361 | } else { |
334 | { | ||
335 | /* sign*(X + Y)*a == A - B (mod |n|) */ | 362 | /* sign*(X + Y)*a == A - B (mod |n|) */ |
336 | if (!BN_uadd(Y, Y, X)) goto err; | 363 | if (!BN_uadd(Y, Y, X)) |
364 | goto err; | ||
337 | /* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */ | 365 | /* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */ |
338 | if (!BN_usub(A, A, B)) goto err; | 366 | if (!BN_usub(A, A, B)) |
339 | } | 367 | goto err; |
340 | } | 368 | } |
341 | } | 369 | } |
342 | else | 370 | } else { |
343 | { | ||
344 | /* general inversion algorithm */ | 371 | /* general inversion algorithm */ |
345 | 372 | ||
346 | while (!BN_is_zero(B)) | 373 | while (!BN_is_zero(B)) { |
347 | { | ||
348 | BIGNUM *tmp; | 374 | BIGNUM *tmp; |
349 | 375 | ||
350 | /* | 376 | /* |
351 | * 0 < B < A, | 377 | * 0 < B < A, |
352 | * (*) -sign*X*a == B (mod |n|), | 378 | * (*) -sign*X*a == B (mod |n|), |
353 | * sign*Y*a == A (mod |n|) | 379 | * sign*Y*a == A (mod |n|) |
354 | */ | 380 | */ |
355 | 381 | ||
356 | /* (D, M) := (A/B, A%B) ... */ | 382 | /* (D, M) := (A/B, A%B) ... */ |
357 | if (BN_num_bits(A) == BN_num_bits(B)) | 383 | if (BN_num_bits(A) == BN_num_bits(B)) { |
358 | { | 384 | if (!BN_one(D)) |
359 | if (!BN_one(D)) goto err; | 385 | goto err; |
360 | if (!BN_sub(M,A,B)) goto err; | 386 | if (!BN_sub(M, A, B)) |
361 | } | 387 | goto err; |
362 | else if (BN_num_bits(A) == BN_num_bits(B) + 1) | 388 | } else if (BN_num_bits(A) == BN_num_bits(B) + 1) { |
363 | { | ||
364 | /* A/B is 1, 2, or 3 */ | 389 | /* A/B is 1, 2, or 3 */ |
365 | if (!BN_lshift1(T,B)) goto err; | 390 | if (!BN_lshift1(T, B)) |
366 | if (BN_ucmp(A,T) < 0) | 391 | goto err; |
367 | { | 392 | if (BN_ucmp(A, T) < 0) { |
368 | /* A < 2*B, so D=1 */ | 393 | /* A < 2*B, so D=1 */ |
369 | if (!BN_one(D)) goto err; | 394 | if (!BN_one(D)) |
370 | if (!BN_sub(M,A,B)) goto err; | 395 | goto err; |
371 | } | 396 | if (!BN_sub(M, A, B)) |
372 | else | 397 | goto err; |
373 | { | 398 | } else { |
374 | /* A >= 2*B, so D=2 or D=3 */ | 399 | /* A >= 2*B, so D=2 or D=3 */ |
375 | if (!BN_sub(M,A,T)) goto err; | 400 | if (!BN_sub(M, A, T)) |
401 | goto err; | ||
376 | if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */ | 402 | if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */ |
377 | if (BN_ucmp(A,D) < 0) | 403 | if (BN_ucmp(A, D) < 0) { |
378 | { | ||
379 | /* A < 3*B, so D=2 */ | 404 | /* A < 3*B, so D=2 */ |
380 | if (!BN_set_word(D,2)) goto err; | 405 | if (!BN_set_word(D, 2)) |
406 | goto err; | ||
381 | /* M (= A - 2*B) already has the correct value */ | 407 | /* M (= A - 2*B) already has the correct value */ |
382 | } | 408 | } else { |
383 | else | ||
384 | { | ||
385 | /* only D=3 remains */ | 409 | /* only D=3 remains */ |
386 | if (!BN_set_word(D,3)) goto err; | 410 | if (!BN_set_word(D, 3)) |
411 | goto err; | ||
387 | /* currently M = A - 2*B, but we need M = A - 3*B */ | 412 | /* currently M = A - 2*B, but we need M = A - 3*B */ |
388 | if (!BN_sub(M,M,B)) goto err; | 413 | if (!BN_sub(M, M, B)) |
389 | } | 414 | goto err; |
390 | } | 415 | } |
391 | } | 416 | } |
392 | else | 417 | } else { |
393 | { | 418 | if (!BN_div(D, M, A, B, ctx)) |
394 | if (!BN_div(D,M,A,B,ctx)) goto err; | 419 | goto err; |
395 | } | 420 | } |
396 | 421 | ||
397 | /* Now | 422 | /* Now |
398 | * A = D*B + M; | 423 | * A = D*B + M; |
399 | * thus we have | 424 | * thus we have |
400 | * (**) sign*Y*a == D*B + M (mod |n|). | 425 | * (**) sign*Y*a == D*B + M (mod |n|). |
401 | */ | 426 | */ |
402 | 427 | tmp = A; /* keep the BIGNUM object, the value does not matter */ | |
403 | tmp=A; /* keep the BIGNUM object, the value does not matter */ | 428 | |
404 | |||
405 | /* (A, B) := (B, A mod B) ... */ | 429 | /* (A, B) := (B, A mod B) ... */ |
406 | A=B; | 430 | A = B; |
407 | B=M; | 431 | B = M; |
408 | /* ... so we have 0 <= B < A again */ | 432 | /* ... so we have 0 <= B < A again */ |
409 | 433 | ||
410 | /* Since the former M is now B and the former B is now A, | 434 | /* Since the former M is now B and the former B is now A, |
411 | * (**) translates into | 435 | * (**) translates into |
412 | * sign*Y*a == D*A + B (mod |n|), | 436 | * sign*Y*a == D*A + B (mod |n|), |
@@ -425,41 +449,38 @@ BIGNUM *BN_mod_inverse(BIGNUM *in, | |||
425 | * sign*Y*a == A (mod |n|). | 449 | * sign*Y*a == A (mod |n|). |
426 | * Note that X and Y stay non-negative all the time. | 450 | * Note that X and Y stay non-negative all the time. |
427 | */ | 451 | */ |
428 | 452 | ||
429 | /* most of the time D is very small, so we can optimize tmp := D*X+Y */ | 453 | /* most of the time D is very small, so we can optimize tmp := D*X+Y */ |
430 | if (BN_is_one(D)) | 454 | if (BN_is_one(D)) { |
431 | { | 455 | if (!BN_add(tmp, X, Y)) |
432 | if (!BN_add(tmp,X,Y)) goto err; | 456 | goto err; |
433 | } | 457 | } else { |
434 | else | 458 | if (BN_is_word(D, 2)) { |
435 | { | 459 | if (!BN_lshift1(tmp, X)) |
436 | if (BN_is_word(D,2)) | 460 | goto err; |
437 | { | 461 | } else if (BN_is_word(D, 4)) { |
438 | if (!BN_lshift1(tmp,X)) goto err; | 462 | if (!BN_lshift(tmp, X, 2)) |
439 | } | 463 | goto err; |
440 | else if (BN_is_word(D,4)) | 464 | } else if (D->top == 1) { |
441 | { | 465 | if (!BN_copy(tmp, X)) |
442 | if (!BN_lshift(tmp,X,2)) goto err; | 466 | goto err; |
443 | } | 467 | if (!BN_mul_word(tmp, D->d[0])) |
444 | else if (D->top == 1) | 468 | goto err; |
445 | { | 469 | } else { |
446 | if (!BN_copy(tmp,X)) goto err; | 470 | if (!BN_mul(tmp, D,X, ctx)) |
447 | if (!BN_mul_word(tmp,D->d[0])) goto err; | 471 | goto err; |
448 | } | ||
449 | else | ||
450 | { | ||
451 | if (!BN_mul(tmp,D,X,ctx)) goto err; | ||
452 | } | ||
453 | if (!BN_add(tmp,tmp,Y)) goto err; | ||
454 | } | 472 | } |
455 | 473 | if (!BN_add(tmp, tmp, Y)) | |
456 | M=Y; /* keep the BIGNUM object, the value does not matter */ | 474 | goto err; |
457 | Y=X; | ||
458 | X=tmp; | ||
459 | sign = -sign; | ||
460 | } | 475 | } |
476 | |||
477 | M = Y; /* keep the BIGNUM object, the value does not matter */ | ||
478 | Y = X; | ||
479 | X = tmp; | ||
480 | sign = -sign; | ||
461 | } | 481 | } |
462 | 482 | } | |
483 | |||
463 | /* | 484 | /* |
464 | * The while loop (Euclid's algorithm) ends when | 485 | * The while loop (Euclid's algorithm) ends when |
465 | * A == gcd(a,n); | 486 | * A == gcd(a,n); |
@@ -468,49 +489,47 @@ BIGNUM *BN_mod_inverse(BIGNUM *in, | |||
468 | * where Y is non-negative. | 489 | * where Y is non-negative. |
469 | */ | 490 | */ |
470 | 491 | ||
471 | if (sign < 0) | 492 | if (sign < 0) { |
472 | { | 493 | if (!BN_sub(Y, n, Y)) |
473 | if (!BN_sub(Y,n,Y)) goto err; | 494 | goto err; |
474 | } | 495 | } |
475 | /* Now Y*a == A (mod |n|). */ | 496 | /* Now Y*a == A (mod |n|). */ |
476 | |||
477 | 497 | ||
478 | if (BN_is_one(A)) | 498 | if (BN_is_one(A)) { |
479 | { | ||
480 | /* Y*a == 1 (mod |n|) */ | 499 | /* Y*a == 1 (mod |n|) */ |
481 | if (!Y->neg && BN_ucmp(Y,n) < 0) | 500 | if (!Y->neg && BN_ucmp(Y, n) < 0) { |
482 | { | 501 | if (!BN_copy(R, Y)) |
483 | if (!BN_copy(R,Y)) goto err; | 502 | goto err; |
484 | } | 503 | } else { |
485 | else | 504 | if (!BN_nnmod(R, Y,n, ctx)) |
486 | { | 505 | goto err; |
487 | if (!BN_nnmod(R,Y,n,ctx)) goto err; | ||
488 | } | ||
489 | } | 506 | } |
490 | else | 507 | } else { |
491 | { | 508 | BNerr(BN_F_BN_MOD_INVERSE, BN_R_NO_INVERSE); |
492 | BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE); | ||
493 | goto err; | 509 | goto err; |
494 | } | 510 | } |
495 | ret=R; | 511 | ret = R; |
512 | |||
496 | err: | 513 | err: |
497 | if ((ret == NULL) && (in == NULL)) BN_free(R); | 514 | if ((ret == NULL) && (in == NULL)) |
515 | BN_free(R); | ||
498 | BN_CTX_end(ctx); | 516 | BN_CTX_end(ctx); |
499 | bn_check_top(ret); | 517 | bn_check_top(ret); |
500 | return(ret); | 518 | return (ret); |
501 | } | 519 | } |
502 | 520 | ||
503 | 521 | ||
504 | /* BN_mod_inverse_no_branch is a special version of BN_mod_inverse. | 522 | /* BN_mod_inverse_no_branch is a special version of BN_mod_inverse. |
505 | * It does not contain branches that may leak sensitive information. | 523 | * It does not contain branches that may leak sensitive information. |
506 | */ | 524 | */ |
507 | static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, | 525 | static BIGNUM * |
508 | const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) | 526 | BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, |
509 | { | 527 | BN_CTX *ctx) |
510 | BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL; | 528 | { |
529 | BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; | ||
511 | BIGNUM local_A, local_B; | 530 | BIGNUM local_A, local_B; |
512 | BIGNUM *pA, *pB; | 531 | BIGNUM *pA, *pB; |
513 | BIGNUM *ret=NULL; | 532 | BIGNUM *ret = NULL; |
514 | int sign; | 533 | int sign; |
515 | 534 | ||
516 | bn_check_top(a); | 535 | bn_check_top(a); |
@@ -524,29 +543,33 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, | |||
524 | M = BN_CTX_get(ctx); | 543 | M = BN_CTX_get(ctx); |
525 | Y = BN_CTX_get(ctx); | 544 | Y = BN_CTX_get(ctx); |
526 | T = BN_CTX_get(ctx); | 545 | T = BN_CTX_get(ctx); |
527 | if (T == NULL) goto err; | 546 | if (T == NULL) |
547 | goto err; | ||
528 | 548 | ||
529 | if (in == NULL) | 549 | if (in == NULL) |
530 | R=BN_new(); | 550 | R = BN_new(); |
531 | else | 551 | else |
532 | R=in; | 552 | R = in; |
533 | if (R == NULL) goto err; | 553 | if (R == NULL) |
554 | goto err; | ||
534 | 555 | ||
535 | BN_one(X); | 556 | BN_one(X); |
536 | BN_zero(Y); | 557 | BN_zero(Y); |
537 | if (BN_copy(B,a) == NULL) goto err; | 558 | if (BN_copy(B, a) == NULL) |
538 | if (BN_copy(A,n) == NULL) goto err; | 559 | goto err; |
560 | if (BN_copy(A, n) == NULL) | ||
561 | goto err; | ||
539 | A->neg = 0; | 562 | A->neg = 0; |
540 | 563 | ||
541 | if (B->neg || (BN_ucmp(B, A) >= 0)) | 564 | if (B->neg || (BN_ucmp(B, A) >= 0)) { |
542 | { | ||
543 | /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, | 565 | /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, |
544 | * BN_div_no_branch will be called eventually. | 566 | * BN_div_no_branch will be called eventually. |
545 | */ | 567 | */ |
546 | pB = &local_B; | 568 | pB = &local_B; |
547 | BN_with_flags(pB, B, BN_FLG_CONSTTIME); | 569 | BN_with_flags(pB, B, BN_FLG_CONSTTIME); |
548 | if (!BN_nnmod(B, pB, A, ctx)) goto err; | 570 | if (!BN_nnmod(B, pB, A, ctx)) |
549 | } | 571 | goto err; |
572 | } | ||
550 | sign = -1; | 573 | sign = -1; |
551 | /* From B = a mod |n|, A = |n| it follows that | 574 | /* From B = a mod |n|, A = |n| it follows that |
552 | * | 575 | * |
@@ -555,10 +578,9 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, | |||
555 | * sign*Y*a == A (mod |n|). | 578 | * sign*Y*a == A (mod |n|). |
556 | */ | 579 | */ |
557 | 580 | ||
558 | while (!BN_is_zero(B)) | 581 | while (!BN_is_zero(B)) { |
559 | { | ||
560 | BIGNUM *tmp; | 582 | BIGNUM *tmp; |
561 | 583 | ||
562 | /* | 584 | /* |
563 | * 0 < B < A, | 585 | * 0 < B < A, |
564 | * (*) -sign*X*a == B (mod |n|), | 586 | * (*) -sign*X*a == B (mod |n|), |
@@ -569,24 +591,24 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, | |||
569 | * BN_div_no_branch will be called eventually. | 591 | * BN_div_no_branch will be called eventually. |
570 | */ | 592 | */ |
571 | pA = &local_A; | 593 | pA = &local_A; |
572 | BN_with_flags(pA, A, BN_FLG_CONSTTIME); | 594 | BN_with_flags(pA, A, BN_FLG_CONSTTIME); |
573 | 595 | ||
574 | /* (D, M) := (A/B, A%B) ... */ | 596 | /* (D, M) := (A/B, A%B) ... */ |
575 | if (!BN_div(D,M,pA,B,ctx)) goto err; | 597 | if (!BN_div(D, M, pA, B, ctx)) |
576 | 598 | goto err; | |
599 | |||
577 | /* Now | 600 | /* Now |
578 | * A = D*B + M; | 601 | * A = D*B + M; |
579 | * thus we have | 602 | * thus we have |
580 | * (**) sign*Y*a == D*B + M (mod |n|). | 603 | * (**) sign*Y*a == D*B + M (mod |n|). |
581 | */ | 604 | */ |
582 | 605 | tmp = A; /* keep the BIGNUM object, the value does not matter */ | |
583 | tmp=A; /* keep the BIGNUM object, the value does not matter */ | 606 | |
584 | |||
585 | /* (A, B) := (B, A mod B) ... */ | 607 | /* (A, B) := (B, A mod B) ... */ |
586 | A=B; | 608 | A = B; |
587 | B=M; | 609 | B = M; |
588 | /* ... so we have 0 <= B < A again */ | 610 | /* ... so we have 0 <= B < A again */ |
589 | 611 | ||
590 | /* Since the former M is now B and the former B is now A, | 612 | /* Since the former M is now B and the former B is now A, |
591 | * (**) translates into | 613 | * (**) translates into |
592 | * sign*Y*a == D*A + B (mod |n|), | 614 | * sign*Y*a == D*A + B (mod |n|), |
@@ -605,16 +627,18 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, | |||
605 | * sign*Y*a == A (mod |n|). | 627 | * sign*Y*a == A (mod |n|). |
606 | * Note that X and Y stay non-negative all the time. | 628 | * Note that X and Y stay non-negative all the time. |
607 | */ | 629 | */ |
608 | |||
609 | if (!BN_mul(tmp,D,X,ctx)) goto err; | ||
610 | if (!BN_add(tmp,tmp,Y)) goto err; | ||
611 | 630 | ||
612 | M=Y; /* keep the BIGNUM object, the value does not matter */ | 631 | if (!BN_mul(tmp, D, X, ctx)) |
613 | Y=X; | 632 | goto err; |
614 | X=tmp; | 633 | if (!BN_add(tmp, tmp, Y)) |
634 | goto err; | ||
635 | |||
636 | M = Y; /* keep the BIGNUM object, the value does not matter */ | ||
637 | Y = X; | ||
638 | X = tmp; | ||
615 | sign = -sign; | 639 | sign = -sign; |
616 | } | 640 | } |
617 | 641 | ||
618 | /* | 642 | /* |
619 | * The while loop (Euclid's algorithm) ends when | 643 | * The while loop (Euclid's algorithm) ends when |
620 | * A == gcd(a,n); | 644 | * A == gcd(a,n); |
@@ -623,33 +647,31 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, | |||
623 | * where Y is non-negative. | 647 | * where Y is non-negative. |
624 | */ | 648 | */ |
625 | 649 | ||
626 | if (sign < 0) | 650 | if (sign < 0) { |
627 | { | 651 | if (!BN_sub(Y, n, Y)) |
628 | if (!BN_sub(Y,n,Y)) goto err; | 652 | goto err; |
629 | } | 653 | } |
630 | /* Now Y*a == A (mod |n|). */ | 654 | /* Now Y*a == A (mod |n|). */ |
631 | 655 | ||
632 | if (BN_is_one(A)) | 656 | if (BN_is_one(A)) { |
633 | { | ||
634 | /* Y*a == 1 (mod |n|) */ | 657 | /* Y*a == 1 (mod |n|) */ |
635 | if (!Y->neg && BN_ucmp(Y,n) < 0) | 658 | if (!Y->neg && BN_ucmp(Y, n) < 0) { |
636 | { | 659 | if (!BN_copy(R, Y)) |
637 | if (!BN_copy(R,Y)) goto err; | 660 | goto err; |
638 | } | 661 | } else { |
639 | else | 662 | if (!BN_nnmod(R, Y, n, ctx)) |
640 | { | 663 | goto err; |
641 | if (!BN_nnmod(R,Y,n,ctx)) goto err; | ||
642 | } | ||
643 | } | 664 | } |
644 | else | 665 | } else { |
645 | { | 666 | BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH, BN_R_NO_INVERSE); |
646 | BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH,BN_R_NO_INVERSE); | ||
647 | goto err; | 667 | goto err; |
648 | } | 668 | } |
649 | ret=R; | 669 | ret = R; |
670 | |||
650 | err: | 671 | err: |
651 | if ((ret == NULL) && (in == NULL)) BN_free(R); | 672 | if ((ret == NULL) && (in == NULL)) |
673 | BN_free(R); | ||
652 | BN_CTX_end(ctx); | 674 | BN_CTX_end(ctx); |
653 | bn_check_top(ret); | 675 | bn_check_top(ret); |
654 | return(ret); | 676 | return (ret); |
655 | } | 677 | } |