diff options
author | jsing <> | 2023-01-21 09:21:11 +0000 |
---|---|---|
committer | jsing <> | 2023-01-21 09:21:11 +0000 |
commit | 71fbf41bd2b9e40f88e44c107ffcde8405fa4f14 (patch) | |
tree | bb49a1d930f380fac250032d18cf02d631ca4c4c /src | |
parent | 33b8a0e11319f8cfbe896e89be1e758ff0815afa (diff) | |
download | openbsd-71fbf41bd2b9e40f88e44c107ffcde8405fa4f14.tar.gz openbsd-71fbf41bd2b9e40f88e44c107ffcde8405fa4f14.tar.bz2 openbsd-71fbf41bd2b9e40f88e44c107ffcde8405fa4f14.zip |
Reorder functions and drop unnessary static prototypes.
No functional change.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/bn/bn_gcd.c | 735 |
1 files changed, 363 insertions, 372 deletions
diff --git a/src/lib/libcrypto/bn/bn_gcd.c b/src/lib/libcrypto/bn/bn_gcd.c index 0d8bdf07eb..84c3d85850 100644 --- a/src/lib/libcrypto/bn/bn_gcd.c +++ b/src/lib/libcrypto/bn/bn_gcd.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_gcd.c,v 1.20 2022/12/26 07:18:51 jmc Exp $ */ | 1 | /* $OpenBSD: bn_gcd.c,v 1.21 2023/01/21 09:21:11 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -113,63 +113,6 @@ | |||
113 | 113 | ||
114 | #include "bn_local.h" | 114 | #include "bn_local.h" |
115 | 115 | ||
116 | static BIGNUM *euclid(BIGNUM *a, BIGNUM *b); | ||
117 | static BIGNUM *BN_gcd_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, | ||
118 | BN_CTX *ctx); | ||
119 | |||
120 | int | ||
121 | BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) | ||
122 | { | ||
123 | BIGNUM *a, *b, *t; | ||
124 | int ret = 0; | ||
125 | |||
126 | |||
127 | BN_CTX_start(ctx); | ||
128 | if ((a = BN_CTX_get(ctx)) == NULL) | ||
129 | goto err; | ||
130 | if ((b = BN_CTX_get(ctx)) == NULL) | ||
131 | goto err; | ||
132 | |||
133 | if (BN_copy(a, in_a) == NULL) | ||
134 | goto err; | ||
135 | if (BN_copy(b, in_b) == NULL) | ||
136 | goto err; | ||
137 | a->neg = 0; | ||
138 | b->neg = 0; | ||
139 | |||
140 | if (BN_cmp(a, b) < 0) { | ||
141 | t = a; | ||
142 | a = b; | ||
143 | b = t; | ||
144 | } | ||
145 | t = euclid(a, b); | ||
146 | if (t == NULL) | ||
147 | goto err; | ||
148 | |||
149 | if (BN_copy(r, t) == NULL) | ||
150 | goto err; | ||
151 | ret = 1; | ||
152 | |||
153 | err: | ||
154 | BN_CTX_end(ctx); | ||
155 | return (ret); | ||
156 | } | ||
157 | |||
158 | int | ||
159 | BN_gcd_ct(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) | ||
160 | { | ||
161 | if (BN_gcd_no_branch(r, in_a, in_b, ctx) == NULL) | ||
162 | return 0; | ||
163 | return 1; | ||
164 | } | ||
165 | |||
166 | int | ||
167 | BN_gcd_nonct(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) | ||
168 | { | ||
169 | return BN_gcd(r, in_a, in_b, ctx); | ||
170 | } | ||
171 | |||
172 | |||
173 | static BIGNUM * | 116 | static BIGNUM * |
174 | euclid(BIGNUM *a, BIGNUM *b) | 117 | euclid(BIGNUM *a, BIGNUM *b) |
175 | { | 118 | { |
@@ -237,11 +180,370 @@ err: | |||
237 | return (NULL); | 180 | return (NULL); |
238 | } | 181 | } |
239 | 182 | ||
183 | /* | ||
184 | * BN_gcd_no_branch is a special version of BN_mod_inverse_no_branch. | ||
185 | * that returns the GCD. | ||
186 | */ | ||
187 | static BIGNUM * | ||
188 | BN_gcd_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, | ||
189 | BN_CTX *ctx) | ||
190 | { | ||
191 | BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; | ||
192 | BIGNUM local_A, local_B; | ||
193 | BIGNUM *pA, *pB; | ||
194 | BIGNUM *ret = NULL; | ||
195 | int sign; | ||
240 | 196 | ||
241 | /* solves ax == 1 (mod n) */ | 197 | if (in == NULL) |
242 | static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, | 198 | goto err; |
243 | const BIGNUM *n, BN_CTX *ctx); | 199 | R = in; |
200 | |||
201 | BN_init(&local_A); | ||
202 | BN_init(&local_B); | ||
203 | |||
204 | |||
205 | BN_CTX_start(ctx); | ||
206 | if ((A = BN_CTX_get(ctx)) == NULL) | ||
207 | goto err; | ||
208 | if ((B = BN_CTX_get(ctx)) == NULL) | ||
209 | goto err; | ||
210 | if ((X = BN_CTX_get(ctx)) == NULL) | ||
211 | goto err; | ||
212 | if ((D = BN_CTX_get(ctx)) == NULL) | ||
213 | goto err; | ||
214 | if ((M = BN_CTX_get(ctx)) == NULL) | ||
215 | goto err; | ||
216 | if ((Y = BN_CTX_get(ctx)) == NULL) | ||
217 | goto err; | ||
218 | if ((T = BN_CTX_get(ctx)) == NULL) | ||
219 | goto err; | ||
220 | |||
221 | if (!BN_one(X)) | ||
222 | goto err; | ||
223 | BN_zero(Y); | ||
224 | if (BN_copy(B, a) == NULL) | ||
225 | goto err; | ||
226 | if (BN_copy(A, n) == NULL) | ||
227 | goto err; | ||
228 | A->neg = 0; | ||
229 | |||
230 | if (B->neg || (BN_ucmp(B, A) >= 0)) { | ||
231 | /* | ||
232 | * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, | ||
233 | * BN_div_no_branch will be called eventually. | ||
234 | */ | ||
235 | pB = &local_B; | ||
236 | /* BN_init() done at the top of the function. */ | ||
237 | BN_with_flags(pB, B, BN_FLG_CONSTTIME); | ||
238 | if (!BN_nnmod(B, pB, A, ctx)) | ||
239 | goto err; | ||
240 | } | ||
241 | sign = -1; | ||
242 | /* From B = a mod |n|, A = |n| it follows that | ||
243 | * | ||
244 | * 0 <= B < A, | ||
245 | * -sign*X*a == B (mod |n|), | ||
246 | * sign*Y*a == A (mod |n|). | ||
247 | */ | ||
248 | |||
249 | while (!BN_is_zero(B)) { | ||
250 | BIGNUM *tmp; | ||
251 | |||
252 | /* | ||
253 | * 0 < B < A, | ||
254 | * (*) -sign*X*a == B (mod |n|), | ||
255 | * sign*Y*a == A (mod |n|) | ||
256 | */ | ||
257 | |||
258 | /* | ||
259 | * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, | ||
260 | * BN_div_no_branch will be called eventually. | ||
261 | */ | ||
262 | pA = &local_A; | ||
263 | /* BN_init() done at the top of the function. */ | ||
264 | BN_with_flags(pA, A, BN_FLG_CONSTTIME); | ||
265 | |||
266 | /* (D, M) := (A/B, A%B) ... */ | ||
267 | if (!BN_div_ct(D, M, pA, B, ctx)) | ||
268 | goto err; | ||
269 | |||
270 | /* Now | ||
271 | * A = D*B + M; | ||
272 | * thus we have | ||
273 | * (**) sign*Y*a == D*B + M (mod |n|). | ||
274 | */ | ||
275 | tmp = A; /* keep the BIGNUM object, the value does not matter */ | ||
276 | |||
277 | /* (A, B) := (B, A mod B) ... */ | ||
278 | A = B; | ||
279 | B = M; | ||
280 | /* ... so we have 0 <= B < A again */ | ||
281 | |||
282 | /* Since the former M is now B and the former B is now A, | ||
283 | * (**) translates into | ||
284 | * sign*Y*a == D*A + B (mod |n|), | ||
285 | * i.e. | ||
286 | * sign*Y*a - D*A == B (mod |n|). | ||
287 | * Similarly, (*) translates into | ||
288 | * -sign*X*a == A (mod |n|). | ||
289 | * | ||
290 | * Thus, | ||
291 | * sign*Y*a + D*sign*X*a == B (mod |n|), | ||
292 | * i.e. | ||
293 | * sign*(Y + D*X)*a == B (mod |n|). | ||
294 | * | ||
295 | * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at | ||
296 | * -sign*X*a == B (mod |n|), | ||
297 | * sign*Y*a == A (mod |n|). | ||
298 | * Note that X and Y stay non-negative all the time. | ||
299 | */ | ||
300 | |||
301 | if (!BN_mul(tmp, D, X, ctx)) | ||
302 | goto err; | ||
303 | if (!BN_add(tmp, tmp, Y)) | ||
304 | goto err; | ||
305 | |||
306 | M = Y; /* keep the BIGNUM object, the value does not matter */ | ||
307 | Y = X; | ||
308 | X = tmp; | ||
309 | sign = -sign; | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | * The while loop (Euclid's algorithm) ends when | ||
314 | * A == gcd(a,n); | ||
315 | */ | ||
316 | |||
317 | if (!BN_copy(R, A)) | ||
318 | goto err; | ||
319 | ret = R; | ||
320 | err: | ||
321 | if ((ret == NULL) && (in == NULL)) | ||
322 | BN_free(R); | ||
323 | BN_CTX_end(ctx); | ||
324 | return (ret); | ||
325 | } | ||
326 | |||
327 | int | ||
328 | BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) | ||
329 | { | ||
330 | BIGNUM *a, *b, *t; | ||
331 | int ret = 0; | ||
332 | |||
333 | |||
334 | BN_CTX_start(ctx); | ||
335 | if ((a = BN_CTX_get(ctx)) == NULL) | ||
336 | goto err; | ||
337 | if ((b = BN_CTX_get(ctx)) == NULL) | ||
338 | goto err; | ||
339 | |||
340 | if (BN_copy(a, in_a) == NULL) | ||
341 | goto err; | ||
342 | if (BN_copy(b, in_b) == NULL) | ||
343 | goto err; | ||
344 | a->neg = 0; | ||
345 | b->neg = 0; | ||
346 | |||
347 | if (BN_cmp(a, b) < 0) { | ||
348 | t = a; | ||
349 | a = b; | ||
350 | b = t; | ||
351 | } | ||
352 | t = euclid(a, b); | ||
353 | if (t == NULL) | ||
354 | goto err; | ||
355 | |||
356 | if (BN_copy(r, t) == NULL) | ||
357 | goto err; | ||
358 | ret = 1; | ||
359 | |||
360 | err: | ||
361 | BN_CTX_end(ctx); | ||
362 | return (ret); | ||
363 | } | ||
364 | |||
365 | int | ||
366 | BN_gcd_ct(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) | ||
367 | { | ||
368 | if (BN_gcd_no_branch(r, in_a, in_b, ctx) == NULL) | ||
369 | return 0; | ||
370 | return 1; | ||
371 | } | ||
372 | |||
373 | int | ||
374 | BN_gcd_nonct(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) | ||
375 | { | ||
376 | return BN_gcd(r, in_a, in_b, ctx); | ||
377 | } | ||
378 | |||
379 | /* BN_mod_inverse_no_branch is a special version of BN_mod_inverse. | ||
380 | * It does not contain branches that may leak sensitive information. | ||
381 | */ | ||
382 | static BIGNUM * | ||
383 | BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, | ||
384 | BN_CTX *ctx) | ||
385 | { | ||
386 | BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; | ||
387 | BIGNUM local_A, local_B; | ||
388 | BIGNUM *pA, *pB; | ||
389 | BIGNUM *ret = NULL; | ||
390 | int sign; | ||
391 | |||
392 | |||
393 | BN_init(&local_A); | ||
394 | BN_init(&local_B); | ||
395 | |||
396 | BN_CTX_start(ctx); | ||
397 | if ((A = BN_CTX_get(ctx)) == NULL) | ||
398 | goto err; | ||
399 | if ((B = BN_CTX_get(ctx)) == NULL) | ||
400 | goto err; | ||
401 | if ((X = BN_CTX_get(ctx)) == NULL) | ||
402 | goto err; | ||
403 | if ((D = BN_CTX_get(ctx)) == NULL) | ||
404 | goto err; | ||
405 | if ((M = BN_CTX_get(ctx)) == NULL) | ||
406 | goto err; | ||
407 | if ((Y = BN_CTX_get(ctx)) == NULL) | ||
408 | goto err; | ||
409 | if ((T = BN_CTX_get(ctx)) == NULL) | ||
410 | goto err; | ||
411 | |||
412 | if (in == NULL) | ||
413 | R = BN_new(); | ||
414 | else | ||
415 | R = in; | ||
416 | if (R == NULL) | ||
417 | goto err; | ||
418 | |||
419 | if (!BN_one(X)) | ||
420 | goto err; | ||
421 | BN_zero(Y); | ||
422 | if (BN_copy(B, a) == NULL) | ||
423 | goto err; | ||
424 | if (BN_copy(A, n) == NULL) | ||
425 | goto err; | ||
426 | A->neg = 0; | ||
427 | |||
428 | if (B->neg || (BN_ucmp(B, A) >= 0)) { | ||
429 | /* | ||
430 | * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, | ||
431 | * BN_div_no_branch will be called eventually. | ||
432 | */ | ||
433 | pB = &local_B; | ||
434 | /* BN_init() done at the top of the function. */ | ||
435 | BN_with_flags(pB, B, BN_FLG_CONSTTIME); | ||
436 | if (!BN_nnmod(B, pB, A, ctx)) | ||
437 | goto err; | ||
438 | } | ||
439 | sign = -1; | ||
440 | /* From B = a mod |n|, A = |n| it follows that | ||
441 | * | ||
442 | * 0 <= B < A, | ||
443 | * -sign*X*a == B (mod |n|), | ||
444 | * sign*Y*a == A (mod |n|). | ||
445 | */ | ||
446 | |||
447 | while (!BN_is_zero(B)) { | ||
448 | BIGNUM *tmp; | ||
449 | |||
450 | /* | ||
451 | * 0 < B < A, | ||
452 | * (*) -sign*X*a == B (mod |n|), | ||
453 | * sign*Y*a == A (mod |n|) | ||
454 | */ | ||
455 | |||
456 | /* | ||
457 | * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, | ||
458 | * BN_div_no_branch will be called eventually. | ||
459 | */ | ||
460 | pA = &local_A; | ||
461 | /* BN_init() done at the top of the function. */ | ||
462 | BN_with_flags(pA, A, BN_FLG_CONSTTIME); | ||
463 | |||
464 | /* (D, M) := (A/B, A%B) ... */ | ||
465 | if (!BN_div_ct(D, M, pA, B, ctx)) | ||
466 | goto err; | ||
467 | |||
468 | /* Now | ||
469 | * A = D*B + M; | ||
470 | * thus we have | ||
471 | * (**) sign*Y*a == D*B + M (mod |n|). | ||
472 | */ | ||
473 | tmp = A; /* keep the BIGNUM object, the value does not matter */ | ||
474 | |||
475 | /* (A, B) := (B, A mod B) ... */ | ||
476 | A = B; | ||
477 | B = M; | ||
478 | /* ... so we have 0 <= B < A again */ | ||
479 | |||
480 | /* Since the former M is now B and the former B is now A, | ||
481 | * (**) translates into | ||
482 | * sign*Y*a == D*A + B (mod |n|), | ||
483 | * i.e. | ||
484 | * sign*Y*a - D*A == B (mod |n|). | ||
485 | * Similarly, (*) translates into | ||
486 | * -sign*X*a == A (mod |n|). | ||
487 | * | ||
488 | * Thus, | ||
489 | * sign*Y*a + D*sign*X*a == B (mod |n|), | ||
490 | * i.e. | ||
491 | * sign*(Y + D*X)*a == B (mod |n|). | ||
492 | * | ||
493 | * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at | ||
494 | * -sign*X*a == B (mod |n|), | ||
495 | * sign*Y*a == A (mod |n|). | ||
496 | * Note that X and Y stay non-negative all the time. | ||
497 | */ | ||
498 | |||
499 | if (!BN_mul(tmp, D, X, ctx)) | ||
500 | goto err; | ||
501 | if (!BN_add(tmp, tmp, Y)) | ||
502 | goto err; | ||
503 | |||
504 | M = Y; /* keep the BIGNUM object, the value does not matter */ | ||
505 | Y = X; | ||
506 | X = tmp; | ||
507 | sign = -sign; | ||
508 | } | ||
509 | |||
510 | /* | ||
511 | * The while loop (Euclid's algorithm) ends when | ||
512 | * A == gcd(a,n); | ||
513 | * we have | ||
514 | * sign*Y*a == A (mod |n|), | ||
515 | * where Y is non-negative. | ||
516 | */ | ||
517 | |||
518 | if (sign < 0) { | ||
519 | if (!BN_sub(Y, n, Y)) | ||
520 | goto err; | ||
521 | } | ||
522 | /* Now Y*a == A (mod |n|). */ | ||
244 | 523 | ||
524 | if (BN_is_one(A)) { | ||
525 | /* Y*a == 1 (mod |n|) */ | ||
526 | if (!Y->neg && BN_ucmp(Y, n) < 0) { | ||
527 | if (!BN_copy(R, Y)) | ||
528 | goto err; | ||
529 | } else { | ||
530 | if (!BN_nnmod(R, Y, n, ctx)) | ||
531 | goto err; | ||
532 | } | ||
533 | } else { | ||
534 | BNerror(BN_R_NO_INVERSE); | ||
535 | goto err; | ||
536 | } | ||
537 | ret = R; | ||
538 | |||
539 | err: | ||
540 | if ((ret == NULL) && (in == NULL)) | ||
541 | BN_free(R); | ||
542 | BN_CTX_end(ctx); | ||
543 | return (ret); | ||
544 | } | ||
545 | |||
546 | /* solves ax == 1 (mod n) */ | ||
245 | static BIGNUM * | 547 | static BIGNUM * |
246 | BN_mod_inverse_internal(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx, | 548 | BN_mod_inverse_internal(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx, |
247 | int ct) | 549 | int ct) |
@@ -551,314 +853,3 @@ BN_mod_inverse_ct(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) | |||
551 | { | 853 | { |
552 | return BN_mod_inverse_internal(in, a, n, ctx, 1); | 854 | return BN_mod_inverse_internal(in, a, n, ctx, 1); |
553 | } | 855 | } |
554 | |||
555 | /* BN_mod_inverse_no_branch is a special version of BN_mod_inverse. | ||
556 | * It does not contain branches that may leak sensitive information. | ||
557 | */ | ||
558 | static BIGNUM * | ||
559 | BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, | ||
560 | BN_CTX *ctx) | ||
561 | { | ||
562 | BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; | ||
563 | BIGNUM local_A, local_B; | ||
564 | BIGNUM *pA, *pB; | ||
565 | BIGNUM *ret = NULL; | ||
566 | int sign; | ||
567 | |||
568 | |||
569 | BN_init(&local_A); | ||
570 | BN_init(&local_B); | ||
571 | |||
572 | BN_CTX_start(ctx); | ||
573 | if ((A = BN_CTX_get(ctx)) == NULL) | ||
574 | goto err; | ||
575 | if ((B = BN_CTX_get(ctx)) == NULL) | ||
576 | goto err; | ||
577 | if ((X = BN_CTX_get(ctx)) == NULL) | ||
578 | goto err; | ||
579 | if ((D = BN_CTX_get(ctx)) == NULL) | ||
580 | goto err; | ||
581 | if ((M = BN_CTX_get(ctx)) == NULL) | ||
582 | goto err; | ||
583 | if ((Y = BN_CTX_get(ctx)) == NULL) | ||
584 | goto err; | ||
585 | if ((T = BN_CTX_get(ctx)) == NULL) | ||
586 | goto err; | ||
587 | |||
588 | if (in == NULL) | ||
589 | R = BN_new(); | ||
590 | else | ||
591 | R = in; | ||
592 | if (R == NULL) | ||
593 | goto err; | ||
594 | |||
595 | if (!BN_one(X)) | ||
596 | goto err; | ||
597 | BN_zero(Y); | ||
598 | if (BN_copy(B, a) == NULL) | ||
599 | goto err; | ||
600 | if (BN_copy(A, n) == NULL) | ||
601 | goto err; | ||
602 | A->neg = 0; | ||
603 | |||
604 | if (B->neg || (BN_ucmp(B, A) >= 0)) { | ||
605 | /* | ||
606 | * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, | ||
607 | * BN_div_no_branch will be called eventually. | ||
608 | */ | ||
609 | pB = &local_B; | ||
610 | /* BN_init() done at the top of the function. */ | ||
611 | BN_with_flags(pB, B, BN_FLG_CONSTTIME); | ||
612 | if (!BN_nnmod(B, pB, A, ctx)) | ||
613 | goto err; | ||
614 | } | ||
615 | sign = -1; | ||
616 | /* From B = a mod |n|, A = |n| it follows that | ||
617 | * | ||
618 | * 0 <= B < A, | ||
619 | * -sign*X*a == B (mod |n|), | ||
620 | * sign*Y*a == A (mod |n|). | ||
621 | */ | ||
622 | |||
623 | while (!BN_is_zero(B)) { | ||
624 | BIGNUM *tmp; | ||
625 | |||
626 | /* | ||
627 | * 0 < B < A, | ||
628 | * (*) -sign*X*a == B (mod |n|), | ||
629 | * sign*Y*a == A (mod |n|) | ||
630 | */ | ||
631 | |||
632 | /* | ||
633 | * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, | ||
634 | * BN_div_no_branch will be called eventually. | ||
635 | */ | ||
636 | pA = &local_A; | ||
637 | /* BN_init() done at the top of the function. */ | ||
638 | BN_with_flags(pA, A, BN_FLG_CONSTTIME); | ||
639 | |||
640 | /* (D, M) := (A/B, A%B) ... */ | ||
641 | if (!BN_div_ct(D, M, pA, B, ctx)) | ||
642 | goto err; | ||
643 | |||
644 | /* Now | ||
645 | * A = D*B + M; | ||
646 | * thus we have | ||
647 | * (**) sign*Y*a == D*B + M (mod |n|). | ||
648 | */ | ||
649 | tmp = A; /* keep the BIGNUM object, the value does not matter */ | ||
650 | |||
651 | /* (A, B) := (B, A mod B) ... */ | ||
652 | A = B; | ||
653 | B = M; | ||
654 | /* ... so we have 0 <= B < A again */ | ||
655 | |||
656 | /* Since the former M is now B and the former B is now A, | ||
657 | * (**) translates into | ||
658 | * sign*Y*a == D*A + B (mod |n|), | ||
659 | * i.e. | ||
660 | * sign*Y*a - D*A == B (mod |n|). | ||
661 | * Similarly, (*) translates into | ||
662 | * -sign*X*a == A (mod |n|). | ||
663 | * | ||
664 | * Thus, | ||
665 | * sign*Y*a + D*sign*X*a == B (mod |n|), | ||
666 | * i.e. | ||
667 | * sign*(Y + D*X)*a == B (mod |n|). | ||
668 | * | ||
669 | * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at | ||
670 | * -sign*X*a == B (mod |n|), | ||
671 | * sign*Y*a == A (mod |n|). | ||
672 | * Note that X and Y stay non-negative all the time. | ||
673 | */ | ||
674 | |||
675 | if (!BN_mul(tmp, D, X, ctx)) | ||
676 | goto err; | ||
677 | if (!BN_add(tmp, tmp, Y)) | ||
678 | goto err; | ||
679 | |||
680 | M = Y; /* keep the BIGNUM object, the value does not matter */ | ||
681 | Y = X; | ||
682 | X = tmp; | ||
683 | sign = -sign; | ||
684 | } | ||
685 | |||
686 | /* | ||
687 | * The while loop (Euclid's algorithm) ends when | ||
688 | * A == gcd(a,n); | ||
689 | * we have | ||
690 | * sign*Y*a == A (mod |n|), | ||
691 | * where Y is non-negative. | ||
692 | */ | ||
693 | |||
694 | if (sign < 0) { | ||
695 | if (!BN_sub(Y, n, Y)) | ||
696 | goto err; | ||
697 | } | ||
698 | /* Now Y*a == A (mod |n|). */ | ||
699 | |||
700 | if (BN_is_one(A)) { | ||
701 | /* Y*a == 1 (mod |n|) */ | ||
702 | if (!Y->neg && BN_ucmp(Y, n) < 0) { | ||
703 | if (!BN_copy(R, Y)) | ||
704 | goto err; | ||
705 | } else { | ||
706 | if (!BN_nnmod(R, Y, n, ctx)) | ||
707 | goto err; | ||
708 | } | ||
709 | } else { | ||
710 | BNerror(BN_R_NO_INVERSE); | ||
711 | goto err; | ||
712 | } | ||
713 | ret = R; | ||
714 | |||
715 | err: | ||
716 | if ((ret == NULL) && (in == NULL)) | ||
717 | BN_free(R); | ||
718 | BN_CTX_end(ctx); | ||
719 | return (ret); | ||
720 | } | ||
721 | |||
722 | /* | ||
723 | * BN_gcd_no_branch is a special version of BN_mod_inverse_no_branch. | ||
724 | * that returns the GCD. | ||
725 | */ | ||
726 | static BIGNUM * | ||
727 | BN_gcd_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, | ||
728 | BN_CTX *ctx) | ||
729 | { | ||
730 | BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; | ||
731 | BIGNUM local_A, local_B; | ||
732 | BIGNUM *pA, *pB; | ||
733 | BIGNUM *ret = NULL; | ||
734 | int sign; | ||
735 | |||
736 | if (in == NULL) | ||
737 | goto err; | ||
738 | R = in; | ||
739 | |||
740 | BN_init(&local_A); | ||
741 | BN_init(&local_B); | ||
742 | |||
743 | |||
744 | BN_CTX_start(ctx); | ||
745 | if ((A = BN_CTX_get(ctx)) == NULL) | ||
746 | goto err; | ||
747 | if ((B = BN_CTX_get(ctx)) == NULL) | ||
748 | goto err; | ||
749 | if ((X = BN_CTX_get(ctx)) == NULL) | ||
750 | goto err; | ||
751 | if ((D = BN_CTX_get(ctx)) == NULL) | ||
752 | goto err; | ||
753 | if ((M = BN_CTX_get(ctx)) == NULL) | ||
754 | goto err; | ||
755 | if ((Y = BN_CTX_get(ctx)) == NULL) | ||
756 | goto err; | ||
757 | if ((T = BN_CTX_get(ctx)) == NULL) | ||
758 | goto err; | ||
759 | |||
760 | if (!BN_one(X)) | ||
761 | goto err; | ||
762 | BN_zero(Y); | ||
763 | if (BN_copy(B, a) == NULL) | ||
764 | goto err; | ||
765 | if (BN_copy(A, n) == NULL) | ||
766 | goto err; | ||
767 | A->neg = 0; | ||
768 | |||
769 | if (B->neg || (BN_ucmp(B, A) >= 0)) { | ||
770 | /* | ||
771 | * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, | ||
772 | * BN_div_no_branch will be called eventually. | ||
773 | */ | ||
774 | pB = &local_B; | ||
775 | /* BN_init() done at the top of the function. */ | ||
776 | BN_with_flags(pB, B, BN_FLG_CONSTTIME); | ||
777 | if (!BN_nnmod(B, pB, A, ctx)) | ||
778 | goto err; | ||
779 | } | ||
780 | sign = -1; | ||
781 | /* From B = a mod |n|, A = |n| it follows that | ||
782 | * | ||
783 | * 0 <= B < A, | ||
784 | * -sign*X*a == B (mod |n|), | ||
785 | * sign*Y*a == A (mod |n|). | ||
786 | */ | ||
787 | |||
788 | while (!BN_is_zero(B)) { | ||
789 | BIGNUM *tmp; | ||
790 | |||
791 | /* | ||
792 | * 0 < B < A, | ||
793 | * (*) -sign*X*a == B (mod |n|), | ||
794 | * sign*Y*a == A (mod |n|) | ||
795 | */ | ||
796 | |||
797 | /* | ||
798 | * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, | ||
799 | * BN_div_no_branch will be called eventually. | ||
800 | */ | ||
801 | pA = &local_A; | ||
802 | /* BN_init() done at the top of the function. */ | ||
803 | BN_with_flags(pA, A, BN_FLG_CONSTTIME); | ||
804 | |||
805 | /* (D, M) := (A/B, A%B) ... */ | ||
806 | if (!BN_div_ct(D, M, pA, B, ctx)) | ||
807 | goto err; | ||
808 | |||
809 | /* Now | ||
810 | * A = D*B + M; | ||
811 | * thus we have | ||
812 | * (**) sign*Y*a == D*B + M (mod |n|). | ||
813 | */ | ||
814 | tmp = A; /* keep the BIGNUM object, the value does not matter */ | ||
815 | |||
816 | /* (A, B) := (B, A mod B) ... */ | ||
817 | A = B; | ||
818 | B = M; | ||
819 | /* ... so we have 0 <= B < A again */ | ||
820 | |||
821 | /* Since the former M is now B and the former B is now A, | ||
822 | * (**) translates into | ||
823 | * sign*Y*a == D*A + B (mod |n|), | ||
824 | * i.e. | ||
825 | * sign*Y*a - D*A == B (mod |n|). | ||
826 | * Similarly, (*) translates into | ||
827 | * -sign*X*a == A (mod |n|). | ||
828 | * | ||
829 | * Thus, | ||
830 | * sign*Y*a + D*sign*X*a == B (mod |n|), | ||
831 | * i.e. | ||
832 | * sign*(Y + D*X)*a == B (mod |n|). | ||
833 | * | ||
834 | * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at | ||
835 | * -sign*X*a == B (mod |n|), | ||
836 | * sign*Y*a == A (mod |n|). | ||
837 | * Note that X and Y stay non-negative all the time. | ||
838 | */ | ||
839 | |||
840 | if (!BN_mul(tmp, D, X, ctx)) | ||
841 | goto err; | ||
842 | if (!BN_add(tmp, tmp, Y)) | ||
843 | goto err; | ||
844 | |||
845 | M = Y; /* keep the BIGNUM object, the value does not matter */ | ||
846 | Y = X; | ||
847 | X = tmp; | ||
848 | sign = -sign; | ||
849 | } | ||
850 | |||
851 | /* | ||
852 | * The while loop (Euclid's algorithm) ends when | ||
853 | * A == gcd(a,n); | ||
854 | */ | ||
855 | |||
856 | if (!BN_copy(R, A)) | ||
857 | goto err; | ||
858 | ret = R; | ||
859 | err: | ||
860 | if ((ret == NULL) && (in == NULL)) | ||
861 | BN_free(R); | ||
862 | BN_CTX_end(ctx); | ||
863 | return (ret); | ||
864 | } | ||