1 /* $OpenBSD: bn_gcd.c,v 1.29 2024/04/10 14:58:06 beck Exp $ */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
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
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
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.
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.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
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:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
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
51 * SUCH DAMAGE.
52 *
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
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58 /* ====================================================================
59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111
112 #include <openssl/err.h>
113
114 #include "bn_local.h"
115
116 static BIGNUM *
euclid(BIGNUM * a,BIGNUM * b)117 euclid(BIGNUM *a, BIGNUM *b)
118 {
119 BIGNUM *t;
120 int shifts = 0;
121
122 /* Loop invariant: 0 <= b <= a. */
123 while (!BN_is_zero(b)) {
124 if (BN_is_odd(a) && BN_is_odd(b)) {
125 if (!BN_sub(a, a, b))
126 goto err;
127 if (!BN_rshift1(a, a))
128 goto err;
129 } else if (BN_is_odd(a) && !BN_is_odd(b)) {
130 if (!BN_rshift1(b, b))
131 goto err;
132 } else if (!BN_is_odd(a) && BN_is_odd(b)) {
133 if (!BN_rshift1(a, a))
134 goto err;
135 } else {
136 if (!BN_rshift1(a, a))
137 goto err;
138 if (!BN_rshift1(b, b))
139 goto err;
140 shifts++;
141 continue;
142 }
143
144 if (BN_cmp(a, b) < 0) {
145 t = a;
146 a = b;
147 b = t;
148 }
149 }
150
151 if (shifts) {
152 if (!BN_lshift(a, a, shifts))
153 goto err;
154 }
155
156 return a;
157
158 err:
159 return NULL;
160 }
161
162 int
BN_gcd(BIGNUM * r,const BIGNUM * in_a,const BIGNUM * in_b,BN_CTX * ctx)163 BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
164 {
165 BIGNUM *a, *b, *t;
166 int ret = 0;
167
168 BN_CTX_start(ctx);
169 if ((a = BN_CTX_get(ctx)) == NULL)
170 goto err;
171 if ((b = BN_CTX_get(ctx)) == NULL)
172 goto err;
173
174 if (!bn_copy(a, in_a))
175 goto err;
176 if (!bn_copy(b, in_b))
177 goto err;
178 a->neg = 0;
179 b->neg = 0;
180
181 if (BN_cmp(a, b) < 0) {
182 t = a;
183 a = b;
184 b = t;
185 }
186 t = euclid(a, b);
187 if (t == NULL)
188 goto err;
189
190 if (!bn_copy(r, t))
191 goto err;
192 ret = 1;
193
194 err:
195 BN_CTX_end(ctx);
196 return (ret);
197 }
198 LCRYPTO_ALIAS(BN_gcd);
199
200 /*
201 * BN_gcd_no_branch is a special version of BN_mod_inverse_no_branch.
202 * that returns the GCD.
203 */
204 static BIGNUM *
BN_gcd_no_branch(BIGNUM * in,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx)205 BN_gcd_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n,
206 BN_CTX *ctx)
207 {
208 BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
209 BIGNUM local_A, local_B;
210 BIGNUM *pA, *pB;
211 BIGNUM *ret = NULL;
212 int sign;
213
214 if (in == NULL)
215 goto err;
216 R = in;
217
218 BN_init(&local_A);
219 BN_init(&local_B);
220
221 BN_CTX_start(ctx);
222 if ((A = BN_CTX_get(ctx)) == NULL)
223 goto err;
224 if ((B = BN_CTX_get(ctx)) == NULL)
225 goto err;
226 if ((X = BN_CTX_get(ctx)) == NULL)
227 goto err;
228 if ((D = BN_CTX_get(ctx)) == NULL)
229 goto err;
230 if ((M = BN_CTX_get(ctx)) == NULL)
231 goto err;
232 if ((Y = BN_CTX_get(ctx)) == NULL)
233 goto err;
234 if ((T = BN_CTX_get(ctx)) == NULL)
235 goto err;
236
237 if (!BN_one(X))
238 goto err;
239 BN_zero(Y);
240 if (!bn_copy(B, a))
241 goto err;
242 if (!bn_copy(A, n))
243 goto err;
244 A->neg = 0;
245
246 if (B->neg || (BN_ucmp(B, A) >= 0)) {
247 /*
248 * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
249 * BN_div_no_branch will be called eventually.
250 */
251 pB = &local_B;
252 /* BN_init() done at the top of the function. */
253 BN_with_flags(pB, B, BN_FLG_CONSTTIME);
254 if (!BN_nnmod(B, pB, A, ctx))
255 goto err;
256 }
257 sign = -1;
258 /* From B = a mod |n|, A = |n| it follows that
259 *
260 * 0 <= B < A,
261 * -sign*X*a == B (mod |n|),
262 * sign*Y*a == A (mod |n|).
263 */
264
265 while (!BN_is_zero(B)) {
266 BIGNUM *tmp;
267
268 /*
269 * 0 < B < A,
270 * (*) -sign*X*a == B (mod |n|),
271 * sign*Y*a == A (mod |n|)
272 */
273
274 /*
275 * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
276 * BN_div_no_branch will be called eventually.
277 */
278 pA = &local_A;
279 /* BN_init() done at the top of the function. */
280 BN_with_flags(pA, A, BN_FLG_CONSTTIME);
281
282 /* (D, M) := (A/B, A%B) ... */
283 if (!BN_div_ct(D, M, pA, B, ctx))
284 goto err;
285
286 /* Now
287 * A = D*B + M;
288 * thus we have
289 * (**) sign*Y*a == D*B + M (mod |n|).
290 */
291 tmp = A; /* keep the BIGNUM object, the value does not matter */
292
293 /* (A, B) := (B, A mod B) ... */
294 A = B;
295 B = M;
296 /* ... so we have 0 <= B < A again */
297
298 /* Since the former M is now B and the former B is now A,
299 * (**) translates into
300 * sign*Y*a == D*A + B (mod |n|),
301 * i.e.
302 * sign*Y*a - D*A == B (mod |n|).
303 * Similarly, (*) translates into
304 * -sign*X*a == A (mod |n|).
305 *
306 * Thus,
307 * sign*Y*a + D*sign*X*a == B (mod |n|),
308 * i.e.
309 * sign*(Y + D*X)*a == B (mod |n|).
310 *
311 * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
312 * -sign*X*a == B (mod |n|),
313 * sign*Y*a == A (mod |n|).
314 * Note that X and Y stay non-negative all the time.
315 */
316
317 if (!BN_mul(tmp, D, X, ctx))
318 goto err;
319 if (!BN_add(tmp, tmp, Y))
320 goto err;
321
322 M = Y; /* keep the BIGNUM object, the value does not matter */
323 Y = X;
324 X = tmp;
325 sign = -sign;
326 }
327
328 /*
329 * The while loop (Euclid's algorithm) ends when
330 * A == gcd(a,n);
331 */
332
333 if (!bn_copy(R, A))
334 goto err;
335 ret = R;
336 err:
337 if ((ret == NULL) && (in == NULL))
338 BN_free(R);
339 BN_CTX_end(ctx);
340 return (ret);
341 }
342
343 int
BN_gcd_ct(BIGNUM * r,const BIGNUM * in_a,const BIGNUM * in_b,BN_CTX * ctx)344 BN_gcd_ct(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
345 {
346 if (BN_gcd_no_branch(r, in_a, in_b, ctx) == NULL)
347 return 0;
348 return 1;
349 }
350
351 /* BN_mod_inverse_no_branch is a special version of BN_mod_inverse.
352 * It does not contain branches that may leak sensitive information.
353 */
354 static BIGNUM *
BN_mod_inverse_no_branch(BIGNUM * in,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx)355 BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n,
356 BN_CTX *ctx)
357 {
358 BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
359 BIGNUM local_A, local_B;
360 BIGNUM *pA, *pB;
361 BIGNUM *ret = NULL;
362 int sign;
363
364 BN_init(&local_A);
365 BN_init(&local_B);
366
367 BN_CTX_start(ctx);
368 if ((A = BN_CTX_get(ctx)) == NULL)
369 goto err;
370 if ((B = BN_CTX_get(ctx)) == NULL)
371 goto err;
372 if ((X = BN_CTX_get(ctx)) == NULL)
373 goto err;
374 if ((D = BN_CTX_get(ctx)) == NULL)
375 goto err;
376 if ((M = BN_CTX_get(ctx)) == NULL)
377 goto err;
378 if ((Y = BN_CTX_get(ctx)) == NULL)
379 goto err;
380 if ((T = BN_CTX_get(ctx)) == NULL)
381 goto err;
382
383 if (in == NULL)
384 R = BN_new();
385 else
386 R = in;
387 if (R == NULL)
388 goto err;
389
390 if (!BN_one(X))
391 goto err;
392 BN_zero(Y);
393 if (!bn_copy(B, a))
394 goto err;
395 if (!bn_copy(A, n))
396 goto err;
397 A->neg = 0;
398
399 if (B->neg || (BN_ucmp(B, A) >= 0)) {
400 /*
401 * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
402 * BN_div_no_branch will be called eventually.
403 */
404 pB = &local_B;
405 /* BN_init() done at the top of the function. */
406 BN_with_flags(pB, B, BN_FLG_CONSTTIME);
407 if (!BN_nnmod(B, pB, A, ctx))
408 goto err;
409 }
410 sign = -1;
411 /* From B = a mod |n|, A = |n| it follows that
412 *
413 * 0 <= B < A,
414 * -sign*X*a == B (mod |n|),
415 * sign*Y*a == A (mod |n|).
416 */
417
418 while (!BN_is_zero(B)) {
419 BIGNUM *tmp;
420
421 /*
422 * 0 < B < A,
423 * (*) -sign*X*a == B (mod |n|),
424 * sign*Y*a == A (mod |n|)
425 */
426
427 /*
428 * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
429 * BN_div_no_branch will be called eventually.
430 */
431 pA = &local_A;
432 /* BN_init() done at the top of the function. */
433 BN_with_flags(pA, A, BN_FLG_CONSTTIME);
434
435 /* (D, M) := (A/B, A%B) ... */
436 if (!BN_div_ct(D, M, pA, B, ctx))
437 goto err;
438
439 /* Now
440 * A = D*B + M;
441 * thus we have
442 * (**) sign*Y*a == D*B + M (mod |n|).
443 */
444 tmp = A; /* keep the BIGNUM object, the value does not matter */
445
446 /* (A, B) := (B, A mod B) ... */
447 A = B;
448 B = M;
449 /* ... so we have 0 <= B < A again */
450
451 /* Since the former M is now B and the former B is now A,
452 * (**) translates into
453 * sign*Y*a == D*A + B (mod |n|),
454 * i.e.
455 * sign*Y*a - D*A == B (mod |n|).
456 * Similarly, (*) translates into
457 * -sign*X*a == A (mod |n|).
458 *
459 * Thus,
460 * sign*Y*a + D*sign*X*a == B (mod |n|),
461 * i.e.
462 * sign*(Y + D*X)*a == B (mod |n|).
463 *
464 * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
465 * -sign*X*a == B (mod |n|),
466 * sign*Y*a == A (mod |n|).
467 * Note that X and Y stay non-negative all the time.
468 */
469
470 if (!BN_mul(tmp, D, X, ctx))
471 goto err;
472 if (!BN_add(tmp, tmp, Y))
473 goto err;
474
475 M = Y; /* keep the BIGNUM object, the value does not matter */
476 Y = X;
477 X = tmp;
478 sign = -sign;
479 }
480
481 /*
482 * The while loop (Euclid's algorithm) ends when
483 * A == gcd(a,n);
484 * we have
485 * sign*Y*a == A (mod |n|),
486 * where Y is non-negative.
487 */
488
489 if (sign < 0) {
490 if (!BN_sub(Y, n, Y))
491 goto err;
492 }
493 /* Now Y*a == A (mod |n|). */
494
495 if (!BN_is_one(A)) {
496 BNerror(BN_R_NO_INVERSE);
497 goto err;
498 }
499
500 if (!BN_nnmod(Y, Y, n, ctx))
501 goto err;
502 if (!bn_copy(R, Y))
503 goto err;
504
505 ret = R;
506
507 err:
508 if ((ret == NULL) && (in == NULL))
509 BN_free(R);
510 BN_CTX_end(ctx);
511 return (ret);
512 }
513
514 /* solves ax == 1 (mod n) */
515 static BIGNUM *
BN_mod_inverse_internal(BIGNUM * in,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx,int ct)516 BN_mod_inverse_internal(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx,
517 int ct)
518 {
519 BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
520 BIGNUM *ret = NULL;
521 int sign;
522
523 if (ct)
524 return BN_mod_inverse_no_branch(in, a, n, ctx);
525
526 BN_CTX_start(ctx);
527 if ((A = BN_CTX_get(ctx)) == NULL)
528 goto err;
529 if ((B = BN_CTX_get(ctx)) == NULL)
530 goto err;
531 if ((X = BN_CTX_get(ctx)) == NULL)
532 goto err;
533 if ((D = BN_CTX_get(ctx)) == NULL)
534 goto err;
535 if ((M = BN_CTX_get(ctx)) == NULL)
536 goto err;
537 if ((Y = BN_CTX_get(ctx)) == NULL)
538 goto err;
539 if ((T = BN_CTX_get(ctx)) == NULL)
540 goto err;
541
542 if (in == NULL)
543 R = BN_new();
544 else
545 R = in;
546 if (R == NULL)
547 goto err;
548
549 if (!BN_one(X))
550 goto err;
551 BN_zero(Y);
552 if (!bn_copy(B, a))
553 goto err;
554 if (!bn_copy(A, n))
555 goto err;
556 A->neg = 0;
557 if (B->neg || (BN_ucmp(B, A) >= 0)) {
558 if (!BN_nnmod(B, B, A, ctx))
559 goto err;
560 }
561 sign = -1;
562 /* From B = a mod |n|, A = |n| it follows that
563 *
564 * 0 <= B < A,
565 * -sign*X*a == B (mod |n|),
566 * sign*Y*a == A (mod |n|).
567 */
568
569 if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) {
570 /* Binary inversion algorithm; requires odd modulus.
571 * This is faster than the general algorithm if the modulus
572 * is sufficiently small (about 400 .. 500 bits on 32-bit
573 * systems, but much more on 64-bit systems) */
574 int shift;
575
576 while (!BN_is_zero(B)) {
577 /*
578 * 0 < B < |n|,
579 * 0 < A <= |n|,
580 * (1) -sign*X*a == B (mod |n|),
581 * (2) sign*Y*a == A (mod |n|)
582 */
583
584 /* Now divide B by the maximum possible power of two in the integers,
585 * and divide X by the same value mod |n|.
586 * When we're done, (1) still holds. */
587 shift = 0;
588 while (!BN_is_bit_set(B, shift)) /* note that 0 < B */
589 {
590 shift++;
591
592 if (BN_is_odd(X)) {
593 if (!BN_uadd(X, X, n))
594 goto err;
595 }
596 /* now X is even, so we can easily divide it by two */
597 if (!BN_rshift1(X, X))
598 goto err;
599 }
600 if (shift > 0) {
601 if (!BN_rshift(B, B, shift))
602 goto err;
603 }
604
605 /* Same for A and Y. Afterwards, (2) still holds. */
606 shift = 0;
607 while (!BN_is_bit_set(A, shift)) /* note that 0 < A */
608 {
609 shift++;
610
611 if (BN_is_odd(Y)) {
612 if (!BN_uadd(Y, Y, n))
613 goto err;
614 }
615 /* now Y is even */
616 if (!BN_rshift1(Y, Y))
617 goto err;
618 }
619 if (shift > 0) {
620 if (!BN_rshift(A, A, shift))
621 goto err;
622 }
623
624 /* We still have (1) and (2).
625 * Both A and B are odd.
626 * The following computations ensure that
627 *
628 * 0 <= B < |n|,
629 * 0 < A < |n|,
630 * (1) -sign*X*a == B (mod |n|),
631 * (2) sign*Y*a == A (mod |n|),
632 *
633 * and that either A or B is even in the next iteration.
634 */
635 if (BN_ucmp(B, A) >= 0) {
636 /* -sign*(X + Y)*a == B - A (mod |n|) */
637 if (!BN_uadd(X, X, Y))
638 goto err;
639 /* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
640 * actually makes the algorithm slower */
641 if (!BN_usub(B, B, A))
642 goto err;
643 } else {
644 /* sign*(X + Y)*a == A - B (mod |n|) */
645 if (!BN_uadd(Y, Y, X))
646 goto err;
647 /* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
648 if (!BN_usub(A, A, B))
649 goto err;
650 }
651 }
652 } else {
653 /* general inversion algorithm */
654
655 while (!BN_is_zero(B)) {
656 BIGNUM *tmp;
657
658 /*
659 * 0 < B < A,
660 * (*) -sign*X*a == B (mod |n|),
661 * sign*Y*a == A (mod |n|)
662 */
663
664 /* (D, M) := (A/B, A%B) ... */
665 if (BN_num_bits(A) == BN_num_bits(B)) {
666 if (!BN_one(D))
667 goto err;
668 if (!BN_sub(M, A, B))
669 goto err;
670 } else if (BN_num_bits(A) == BN_num_bits(B) + 1) {
671 /* A/B is 1, 2, or 3 */
672 if (!BN_lshift1(T, B))
673 goto err;
674 if (BN_ucmp(A, T) < 0) {
675 /* A < 2*B, so D=1 */
676 if (!BN_one(D))
677 goto err;
678 if (!BN_sub(M, A, B))
679 goto err;
680 } else {
681 /* A >= 2*B, so D=2 or D=3 */
682 if (!BN_sub(M, A, T))
683 goto err;
684 if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */
685 if (BN_ucmp(A, D) < 0) {
686 /* A < 3*B, so D=2 */
687 if (!BN_set_word(D, 2))
688 goto err;
689 /* M (= A - 2*B) already has the correct value */
690 } else {
691 /* only D=3 remains */
692 if (!BN_set_word(D, 3))
693 goto err;
694 /* currently M = A - 2*B, but we need M = A - 3*B */
695 if (!BN_sub(M, M, B))
696 goto err;
697 }
698 }
699 } else {
700 if (!BN_div_nonct(D, M, A, B, ctx))
701 goto err;
702 }
703
704 /* Now
705 * A = D*B + M;
706 * thus we have
707 * (**) sign*Y*a == D*B + M (mod |n|).
708 */
709 tmp = A; /* keep the BIGNUM object, the value does not matter */
710
711 /* (A, B) := (B, A mod B) ... */
712 A = B;
713 B = M;
714 /* ... so we have 0 <= B < A again */
715
716 /* Since the former M is now B and the former B is now A,
717 * (**) translates into
718 * sign*Y*a == D*A + B (mod |n|),
719 * i.e.
720 * sign*Y*a - D*A == B (mod |n|).
721 * Similarly, (*) translates into
722 * -sign*X*a == A (mod |n|).
723 *
724 * Thus,
725 * sign*Y*a + D*sign*X*a == B (mod |n|),
726 * i.e.
727 * sign*(Y + D*X)*a == B (mod |n|).
728 *
729 * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
730 * -sign*X*a == B (mod |n|),
731 * sign*Y*a == A (mod |n|).
732 * Note that X and Y stay non-negative all the time.
733 */
734
735 /* most of the time D is very small, so we can optimize tmp := D*X+Y */
736 if (BN_is_one(D)) {
737 if (!BN_add(tmp, X, Y))
738 goto err;
739 } else {
740 if (BN_is_word(D, 2)) {
741 if (!BN_lshift1(tmp, X))
742 goto err;
743 } else if (BN_is_word(D, 4)) {
744 if (!BN_lshift(tmp, X, 2))
745 goto err;
746 } else if (D->top == 1) {
747 if (!bn_copy(tmp, X))
748 goto err;
749 if (!BN_mul_word(tmp, D->d[0]))
750 goto err;
751 } else {
752 if (!BN_mul(tmp, D,X, ctx))
753 goto err;
754 }
755 if (!BN_add(tmp, tmp, Y))
756 goto err;
757 }
758
759 M = Y; /* keep the BIGNUM object, the value does not matter */
760 Y = X;
761 X = tmp;
762 sign = -sign;
763 }
764 }
765
766 /*
767 * The while loop (Euclid's algorithm) ends when
768 * A == gcd(a,n);
769 * we have
770 * sign*Y*a == A (mod |n|),
771 * where Y is non-negative.
772 */
773
774 if (sign < 0) {
775 if (!BN_sub(Y, n, Y))
776 goto err;
777 }
778 /* Now Y*a == A (mod |n|). */
779
780 if (!BN_is_one(A)) {
781 BNerror(BN_R_NO_INVERSE);
782 goto err;
783 }
784
785 if (!BN_nnmod(Y, Y, n, ctx))
786 goto err;
787 if (!bn_copy(R, Y))
788 goto err;
789
790 ret = R;
791
792 err:
793 if ((ret == NULL) && (in == NULL))
794 BN_free(R);
795 BN_CTX_end(ctx);
796 return (ret);
797 }
798
799 BIGNUM *
BN_mod_inverse(BIGNUM * in,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx)800 BN_mod_inverse(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
801 {
802 int ct = ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) ||
803 (BN_get_flags(n, BN_FLG_CONSTTIME) != 0));
804 return BN_mod_inverse_internal(in, a, n, ctx, ct);
805 }
806 LCRYPTO_ALIAS(BN_mod_inverse);
807
808 BIGNUM *
BN_mod_inverse_nonct(BIGNUM * in,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx)809 BN_mod_inverse_nonct(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
810 {
811 return BN_mod_inverse_internal(in, a, n, ctx, 0);
812 }
813
814 BIGNUM *
BN_mod_inverse_ct(BIGNUM * in,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx)815 BN_mod_inverse_ct(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
816 {
817 return BN_mod_inverse_internal(in, a, n, ctx, 1);
818 }
819