1*6dd041f3Sbeck /* $OpenBSD: bn_gcd.c,v 1.29 2024/04/10 14:58:06 beck Exp $ */
25b37fcf3Sryker /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
35b37fcf3Sryker * All rights reserved.
45b37fcf3Sryker *
55b37fcf3Sryker * This package is an SSL implementation written
65b37fcf3Sryker * by Eric Young (eay@cryptsoft.com).
75b37fcf3Sryker * The implementation was written so as to conform with Netscapes SSL.
85b37fcf3Sryker *
95b37fcf3Sryker * This library is free for commercial and non-commercial use as long as
105b37fcf3Sryker * the following conditions are aheared to. The following conditions
115b37fcf3Sryker * apply to all code found in this distribution, be it the RC4, RSA,
125b37fcf3Sryker * lhash, DES, etc., code; not just the SSL code. The SSL documentation
135b37fcf3Sryker * included with this distribution is covered by the same copyright terms
145b37fcf3Sryker * except that the holder is Tim Hudson (tjh@cryptsoft.com).
155b37fcf3Sryker *
165b37fcf3Sryker * Copyright remains Eric Young's, and as such any Copyright notices in
175b37fcf3Sryker * the code are not to be removed.
185b37fcf3Sryker * If this package is used in a product, Eric Young should be given attribution
195b37fcf3Sryker * as the author of the parts of the library used.
205b37fcf3Sryker * This can be in the form of a textual message at program startup or
215b37fcf3Sryker * in documentation (online or textual) provided with the package.
225b37fcf3Sryker *
235b37fcf3Sryker * Redistribution and use in source and binary forms, with or without
245b37fcf3Sryker * modification, are permitted provided that the following conditions
255b37fcf3Sryker * are met:
265b37fcf3Sryker * 1. Redistributions of source code must retain the copyright
275b37fcf3Sryker * notice, this list of conditions and the following disclaimer.
285b37fcf3Sryker * 2. Redistributions in binary form must reproduce the above copyright
295b37fcf3Sryker * notice, this list of conditions and the following disclaimer in the
305b37fcf3Sryker * documentation and/or other materials provided with the distribution.
315b37fcf3Sryker * 3. All advertising materials mentioning features or use of this software
325b37fcf3Sryker * must display the following acknowledgement:
335b37fcf3Sryker * "This product includes cryptographic software written by
345b37fcf3Sryker * Eric Young (eay@cryptsoft.com)"
355b37fcf3Sryker * The word 'cryptographic' can be left out if the rouines from the library
365b37fcf3Sryker * being used are not cryptographic related :-).
375b37fcf3Sryker * 4. If you include any Windows specific code (or a derivative thereof) from
385b37fcf3Sryker * the apps directory (application code) you must include an acknowledgement:
395b37fcf3Sryker * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
405b37fcf3Sryker *
415b37fcf3Sryker * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
425b37fcf3Sryker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
435b37fcf3Sryker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
445b37fcf3Sryker * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
455b37fcf3Sryker * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
465b37fcf3Sryker * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
475b37fcf3Sryker * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
485b37fcf3Sryker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
495b37fcf3Sryker * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
505b37fcf3Sryker * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
515b37fcf3Sryker * SUCH DAMAGE.
525b37fcf3Sryker *
535b37fcf3Sryker * The licence and distribution terms for any publically available version or
545b37fcf3Sryker * derivative of this code cannot be changed. i.e. this code cannot simply be
555b37fcf3Sryker * copied and put under another distribution licence
565b37fcf3Sryker * [including the GNU Public Licence.]
575b37fcf3Sryker */
58da347917Sbeck /* ====================================================================
59da347917Sbeck * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60da347917Sbeck *
61da347917Sbeck * Redistribution and use in source and binary forms, with or without
62da347917Sbeck * modification, are permitted provided that the following conditions
63da347917Sbeck * are met:
64da347917Sbeck *
65da347917Sbeck * 1. Redistributions of source code must retain the above copyright
66da347917Sbeck * notice, this list of conditions and the following disclaimer.
67da347917Sbeck *
68da347917Sbeck * 2. Redistributions in binary form must reproduce the above copyright
69da347917Sbeck * notice, this list of conditions and the following disclaimer in
70da347917Sbeck * the documentation and/or other materials provided with the
71da347917Sbeck * distribution.
72da347917Sbeck *
73da347917Sbeck * 3. All advertising materials mentioning features or use of this
74da347917Sbeck * software must display the following acknowledgment:
75da347917Sbeck * "This product includes software developed by the OpenSSL Project
76da347917Sbeck * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77da347917Sbeck *
78da347917Sbeck * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79da347917Sbeck * endorse or promote products derived from this software without
80da347917Sbeck * prior written permission. For written permission, please contact
81da347917Sbeck * openssl-core@openssl.org.
82da347917Sbeck *
83da347917Sbeck * 5. Products derived from this software may not be called "OpenSSL"
84da347917Sbeck * nor may "OpenSSL" appear in their names without prior written
85da347917Sbeck * permission of the OpenSSL Project.
86da347917Sbeck *
87da347917Sbeck * 6. Redistributions of any form whatsoever must retain the following
88da347917Sbeck * acknowledgment:
89da347917Sbeck * "This product includes software developed by the OpenSSL Project
90da347917Sbeck * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91da347917Sbeck *
92da347917Sbeck * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93da347917Sbeck * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94da347917Sbeck * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95da347917Sbeck * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96da347917Sbeck * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97da347917Sbeck * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98da347917Sbeck * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99da347917Sbeck * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100da347917Sbeck * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101da347917Sbeck * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102da347917Sbeck * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103da347917Sbeck * OF THE POSSIBILITY OF SUCH DAMAGE.
104da347917Sbeck * ====================================================================
105da347917Sbeck *
106da347917Sbeck * This product includes cryptographic software written by Eric Young
107da347917Sbeck * (eay@cryptsoft.com). This product includes software written by Tim
108da347917Sbeck * Hudson (tjh@cryptsoft.com).
109da347917Sbeck *
110da347917Sbeck */
1115b37fcf3Sryker
112b6ab114eSjsing #include <openssl/err.h>
113b6ab114eSjsing
114c9675a23Stb #include "bn_local.h"
1155b37fcf3Sryker
1162bd9bb84Sjsing static BIGNUM *
euclid(BIGNUM * a,BIGNUM * b)1172bd9bb84Sjsing euclid(BIGNUM *a, BIGNUM *b)
1185b37fcf3Sryker {
1195b37fcf3Sryker BIGNUM *t;
1205b37fcf3Sryker int shifts = 0;
1215b37fcf3Sryker
1221f279c5eStb /* Loop invariant: 0 <= b <= a. */
1232bd9bb84Sjsing while (!BN_is_zero(b)) {
1241f279c5eStb if (BN_is_odd(a) && BN_is_odd(b)) {
1252bd9bb84Sjsing if (!BN_sub(a, a, b))
1262bd9bb84Sjsing goto err;
1272bd9bb84Sjsing if (!BN_rshift1(a, a))
1282bd9bb84Sjsing goto err;
1291f279c5eStb } else if (BN_is_odd(a) && !BN_is_odd(b)) {
1302bd9bb84Sjsing if (!BN_rshift1(b, b))
1312bd9bb84Sjsing goto err;
1321f279c5eStb } else if (!BN_is_odd(a) && BN_is_odd(b)) {
1332bd9bb84Sjsing if (!BN_rshift1(a, a))
1342bd9bb84Sjsing goto err;
1351f279c5eStb } else {
1362bd9bb84Sjsing if (!BN_rshift1(a, a))
1372bd9bb84Sjsing goto err;
1382bd9bb84Sjsing if (!BN_rshift1(b, b))
1392bd9bb84Sjsing goto err;
1405b37fcf3Sryker shifts++;
1411f279c5eStb continue;
1425b37fcf3Sryker }
1431f279c5eStb
1441f279c5eStb if (BN_cmp(a, b) < 0) {
1451f279c5eStb t = a;
1461f279c5eStb a = b;
1471f279c5eStb b = t;
1485b37fcf3Sryker }
1495b37fcf3Sryker }
150da347917Sbeck
1512bd9bb84Sjsing if (shifts) {
1522bd9bb84Sjsing if (!BN_lshift(a, a, shifts))
1532bd9bb84Sjsing goto err;
1545b37fcf3Sryker }
1551f279c5eStb
1561f279c5eStb return a;
1572bd9bb84Sjsing
1585b37fcf3Sryker err:
1591f279c5eStb return NULL;
1605b37fcf3Sryker }
1615b37fcf3Sryker
162b6886925Stb int
BN_gcd(BIGNUM * r,const BIGNUM * in_a,const BIGNUM * in_b,BN_CTX * ctx)163b6886925Stb BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
164b6886925Stb {
165b6886925Stb BIGNUM *a, *b, *t;
166b6886925Stb int ret = 0;
167b6886925Stb
168b6886925Stb BN_CTX_start(ctx);
169b6886925Stb if ((a = BN_CTX_get(ctx)) == NULL)
170b6886925Stb goto err;
171b6886925Stb if ((b = BN_CTX_get(ctx)) == NULL)
172b6886925Stb goto err;
173b6886925Stb
174b6886925Stb if (!bn_copy(a, in_a))
175b6886925Stb goto err;
176b6886925Stb if (!bn_copy(b, in_b))
177b6886925Stb goto err;
178b6886925Stb a->neg = 0;
179b6886925Stb b->neg = 0;
180b6886925Stb
181b6886925Stb if (BN_cmp(a, b) < 0) {
182b6886925Stb t = a;
183b6886925Stb a = b;
184b6886925Stb b = t;
185b6886925Stb }
186b6886925Stb t = euclid(a, b);
187b6886925Stb if (t == NULL)
188b6886925Stb goto err;
189b6886925Stb
190b6886925Stb if (!bn_copy(r, t))
191b6886925Stb goto err;
192b6886925Stb ret = 1;
193b6886925Stb
194b6886925Stb err:
195b6886925Stb BN_CTX_end(ctx);
196b6886925Stb return (ret);
197b6886925Stb }
198*6dd041f3Sbeck LCRYPTO_ALIAS(BN_gcd);
199b6886925Stb
2003decc9a1Sjsing /*
2013decc9a1Sjsing * BN_gcd_no_branch is a special version of BN_mod_inverse_no_branch.
2023decc9a1Sjsing * that returns the GCD.
2033decc9a1Sjsing */
2043decc9a1Sjsing static BIGNUM *
BN_gcd_no_branch(BIGNUM * in,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx)2053decc9a1Sjsing BN_gcd_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n,
2063decc9a1Sjsing BN_CTX *ctx)
2073decc9a1Sjsing {
2083decc9a1Sjsing BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
2093decc9a1Sjsing BIGNUM local_A, local_B;
2103decc9a1Sjsing BIGNUM *pA, *pB;
2113decc9a1Sjsing BIGNUM *ret = NULL;
2123decc9a1Sjsing int sign;
2133decc9a1Sjsing
2143decc9a1Sjsing if (in == NULL)
2153decc9a1Sjsing goto err;
2163decc9a1Sjsing R = in;
2173decc9a1Sjsing
2183decc9a1Sjsing BN_init(&local_A);
2193decc9a1Sjsing BN_init(&local_B);
2203decc9a1Sjsing
2213decc9a1Sjsing BN_CTX_start(ctx);
2223decc9a1Sjsing if ((A = BN_CTX_get(ctx)) == NULL)
2233decc9a1Sjsing goto err;
2243decc9a1Sjsing if ((B = BN_CTX_get(ctx)) == NULL)
2253decc9a1Sjsing goto err;
2263decc9a1Sjsing if ((X = BN_CTX_get(ctx)) == NULL)
2273decc9a1Sjsing goto err;
2283decc9a1Sjsing if ((D = BN_CTX_get(ctx)) == NULL)
2293decc9a1Sjsing goto err;
2303decc9a1Sjsing if ((M = BN_CTX_get(ctx)) == NULL)
2313decc9a1Sjsing goto err;
2323decc9a1Sjsing if ((Y = BN_CTX_get(ctx)) == NULL)
2333decc9a1Sjsing goto err;
2343decc9a1Sjsing if ((T = BN_CTX_get(ctx)) == NULL)
2353decc9a1Sjsing goto err;
2363decc9a1Sjsing
2373decc9a1Sjsing if (!BN_one(X))
2383decc9a1Sjsing goto err;
2393decc9a1Sjsing BN_zero(Y);
24058460d4fStb if (!bn_copy(B, a))
2413decc9a1Sjsing goto err;
24258460d4fStb if (!bn_copy(A, n))
2433decc9a1Sjsing goto err;
2443decc9a1Sjsing A->neg = 0;
2453decc9a1Sjsing
2463decc9a1Sjsing if (B->neg || (BN_ucmp(B, A) >= 0)) {
2473decc9a1Sjsing /*
2483decc9a1Sjsing * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
2493decc9a1Sjsing * BN_div_no_branch will be called eventually.
2503decc9a1Sjsing */
2513decc9a1Sjsing pB = &local_B;
2523decc9a1Sjsing /* BN_init() done at the top of the function. */
2533decc9a1Sjsing BN_with_flags(pB, B, BN_FLG_CONSTTIME);
2543decc9a1Sjsing if (!BN_nnmod(B, pB, A, ctx))
2553decc9a1Sjsing goto err;
2563decc9a1Sjsing }
2573decc9a1Sjsing sign = -1;
2583decc9a1Sjsing /* From B = a mod |n|, A = |n| it follows that
2593decc9a1Sjsing *
2603decc9a1Sjsing * 0 <= B < A,
2613decc9a1Sjsing * -sign*X*a == B (mod |n|),
2623decc9a1Sjsing * sign*Y*a == A (mod |n|).
2633decc9a1Sjsing */
2643decc9a1Sjsing
2653decc9a1Sjsing while (!BN_is_zero(B)) {
2663decc9a1Sjsing BIGNUM *tmp;
2673decc9a1Sjsing
2683decc9a1Sjsing /*
2693decc9a1Sjsing * 0 < B < A,
2703decc9a1Sjsing * (*) -sign*X*a == B (mod |n|),
2713decc9a1Sjsing * sign*Y*a == A (mod |n|)
2723decc9a1Sjsing */
2733decc9a1Sjsing
2743decc9a1Sjsing /*
2753decc9a1Sjsing * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
2763decc9a1Sjsing * BN_div_no_branch will be called eventually.
2773decc9a1Sjsing */
2783decc9a1Sjsing pA = &local_A;
2793decc9a1Sjsing /* BN_init() done at the top of the function. */
2803decc9a1Sjsing BN_with_flags(pA, A, BN_FLG_CONSTTIME);
2813decc9a1Sjsing
2823decc9a1Sjsing /* (D, M) := (A/B, A%B) ... */
2833decc9a1Sjsing if (!BN_div_ct(D, M, pA, B, ctx))
2843decc9a1Sjsing goto err;
2853decc9a1Sjsing
2863decc9a1Sjsing /* Now
2873decc9a1Sjsing * A = D*B + M;
2883decc9a1Sjsing * thus we have
2893decc9a1Sjsing * (**) sign*Y*a == D*B + M (mod |n|).
2903decc9a1Sjsing */
2913decc9a1Sjsing tmp = A; /* keep the BIGNUM object, the value does not matter */
2923decc9a1Sjsing
2933decc9a1Sjsing /* (A, B) := (B, A mod B) ... */
2943decc9a1Sjsing A = B;
2953decc9a1Sjsing B = M;
2963decc9a1Sjsing /* ... so we have 0 <= B < A again */
2973decc9a1Sjsing
2983decc9a1Sjsing /* Since the former M is now B and the former B is now A,
2993decc9a1Sjsing * (**) translates into
3003decc9a1Sjsing * sign*Y*a == D*A + B (mod |n|),
3013decc9a1Sjsing * i.e.
3023decc9a1Sjsing * sign*Y*a - D*A == B (mod |n|).
3033decc9a1Sjsing * Similarly, (*) translates into
3043decc9a1Sjsing * -sign*X*a == A (mod |n|).
3053decc9a1Sjsing *
3063decc9a1Sjsing * Thus,
3073decc9a1Sjsing * sign*Y*a + D*sign*X*a == B (mod |n|),
3083decc9a1Sjsing * i.e.
3093decc9a1Sjsing * sign*(Y + D*X)*a == B (mod |n|).
3103decc9a1Sjsing *
3113decc9a1Sjsing * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
3123decc9a1Sjsing * -sign*X*a == B (mod |n|),
3133decc9a1Sjsing * sign*Y*a == A (mod |n|).
3143decc9a1Sjsing * Note that X and Y stay non-negative all the time.
3153decc9a1Sjsing */
3163decc9a1Sjsing
3173decc9a1Sjsing if (!BN_mul(tmp, D, X, ctx))
3183decc9a1Sjsing goto err;
3193decc9a1Sjsing if (!BN_add(tmp, tmp, Y))
3203decc9a1Sjsing goto err;
3213decc9a1Sjsing
3223decc9a1Sjsing M = Y; /* keep the BIGNUM object, the value does not matter */
3233decc9a1Sjsing Y = X;
3243decc9a1Sjsing X = tmp;
3253decc9a1Sjsing sign = -sign;
3263decc9a1Sjsing }
3273decc9a1Sjsing
3283decc9a1Sjsing /*
3293decc9a1Sjsing * The while loop (Euclid's algorithm) ends when
3303decc9a1Sjsing * A == gcd(a,n);
3313decc9a1Sjsing */
3323decc9a1Sjsing
333cef8f41dStb if (!bn_copy(R, A))
3343decc9a1Sjsing goto err;
3353decc9a1Sjsing ret = R;
3363decc9a1Sjsing err:
3373decc9a1Sjsing if ((ret == NULL) && (in == NULL))
3383decc9a1Sjsing BN_free(R);
3393decc9a1Sjsing BN_CTX_end(ctx);
3403decc9a1Sjsing return (ret);
3413decc9a1Sjsing }
3423decc9a1Sjsing
3433decc9a1Sjsing int
BN_gcd_ct(BIGNUM * r,const BIGNUM * in_a,const BIGNUM * in_b,BN_CTX * ctx)3443decc9a1Sjsing BN_gcd_ct(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
3453decc9a1Sjsing {
3463decc9a1Sjsing if (BN_gcd_no_branch(r, in_a, in_b, ctx) == NULL)
3473decc9a1Sjsing return 0;
3483decc9a1Sjsing return 1;
3493decc9a1Sjsing }
3503decc9a1Sjsing
3513decc9a1Sjsing /* BN_mod_inverse_no_branch is a special version of BN_mod_inverse.
3523decc9a1Sjsing * It does not contain branches that may leak sensitive information.
3533decc9a1Sjsing */
3543decc9a1Sjsing static BIGNUM *
BN_mod_inverse_no_branch(BIGNUM * in,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx)3553decc9a1Sjsing BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n,
3563decc9a1Sjsing BN_CTX *ctx)
3573decc9a1Sjsing {
3583decc9a1Sjsing BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
3593decc9a1Sjsing BIGNUM local_A, local_B;
3603decc9a1Sjsing BIGNUM *pA, *pB;
3613decc9a1Sjsing BIGNUM *ret = NULL;
3623decc9a1Sjsing int sign;
3633decc9a1Sjsing
3643decc9a1Sjsing BN_init(&local_A);
3653decc9a1Sjsing BN_init(&local_B);
3663decc9a1Sjsing
3673decc9a1Sjsing BN_CTX_start(ctx);
3683decc9a1Sjsing if ((A = BN_CTX_get(ctx)) == NULL)
3693decc9a1Sjsing goto err;
3703decc9a1Sjsing if ((B = BN_CTX_get(ctx)) == NULL)
3713decc9a1Sjsing goto err;
3723decc9a1Sjsing if ((X = BN_CTX_get(ctx)) == NULL)
3733decc9a1Sjsing goto err;
3743decc9a1Sjsing if ((D = BN_CTX_get(ctx)) == NULL)
3753decc9a1Sjsing goto err;
3763decc9a1Sjsing if ((M = BN_CTX_get(ctx)) == NULL)
3773decc9a1Sjsing goto err;
3783decc9a1Sjsing if ((Y = BN_CTX_get(ctx)) == NULL)
3793decc9a1Sjsing goto err;
3803decc9a1Sjsing if ((T = BN_CTX_get(ctx)) == NULL)
3813decc9a1Sjsing goto err;
3823decc9a1Sjsing
3833decc9a1Sjsing if (in == NULL)
3843decc9a1Sjsing R = BN_new();
3853decc9a1Sjsing else
3863decc9a1Sjsing R = in;
3873decc9a1Sjsing if (R == NULL)
3883decc9a1Sjsing goto err;
3893decc9a1Sjsing
3903decc9a1Sjsing if (!BN_one(X))
3913decc9a1Sjsing goto err;
3923decc9a1Sjsing BN_zero(Y);
39358460d4fStb if (!bn_copy(B, a))
3943decc9a1Sjsing goto err;
39558460d4fStb if (!bn_copy(A, n))
3963decc9a1Sjsing goto err;
3973decc9a1Sjsing A->neg = 0;
3983decc9a1Sjsing
3993decc9a1Sjsing if (B->neg || (BN_ucmp(B, A) >= 0)) {
4003decc9a1Sjsing /*
4013decc9a1Sjsing * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
4023decc9a1Sjsing * BN_div_no_branch will be called eventually.
4033decc9a1Sjsing */
4043decc9a1Sjsing pB = &local_B;
4053decc9a1Sjsing /* BN_init() done at the top of the function. */
4063decc9a1Sjsing BN_with_flags(pB, B, BN_FLG_CONSTTIME);
4073decc9a1Sjsing if (!BN_nnmod(B, pB, A, ctx))
4083decc9a1Sjsing goto err;
4093decc9a1Sjsing }
4103decc9a1Sjsing sign = -1;
4113decc9a1Sjsing /* From B = a mod |n|, A = |n| it follows that
4123decc9a1Sjsing *
4133decc9a1Sjsing * 0 <= B < A,
4143decc9a1Sjsing * -sign*X*a == B (mod |n|),
4153decc9a1Sjsing * sign*Y*a == A (mod |n|).
4163decc9a1Sjsing */
4173decc9a1Sjsing
4183decc9a1Sjsing while (!BN_is_zero(B)) {
4193decc9a1Sjsing BIGNUM *tmp;
4203decc9a1Sjsing
4213decc9a1Sjsing /*
4223decc9a1Sjsing * 0 < B < A,
4233decc9a1Sjsing * (*) -sign*X*a == B (mod |n|),
4243decc9a1Sjsing * sign*Y*a == A (mod |n|)
4253decc9a1Sjsing */
4263decc9a1Sjsing
4273decc9a1Sjsing /*
4283decc9a1Sjsing * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
4293decc9a1Sjsing * BN_div_no_branch will be called eventually.
4303decc9a1Sjsing */
4313decc9a1Sjsing pA = &local_A;
4323decc9a1Sjsing /* BN_init() done at the top of the function. */
4333decc9a1Sjsing BN_with_flags(pA, A, BN_FLG_CONSTTIME);
4343decc9a1Sjsing
4353decc9a1Sjsing /* (D, M) := (A/B, A%B) ... */
4363decc9a1Sjsing if (!BN_div_ct(D, M, pA, B, ctx))
4373decc9a1Sjsing goto err;
4383decc9a1Sjsing
4393decc9a1Sjsing /* Now
4403decc9a1Sjsing * A = D*B + M;
4413decc9a1Sjsing * thus we have
4423decc9a1Sjsing * (**) sign*Y*a == D*B + M (mod |n|).
4433decc9a1Sjsing */
4443decc9a1Sjsing tmp = A; /* keep the BIGNUM object, the value does not matter */
4453decc9a1Sjsing
4463decc9a1Sjsing /* (A, B) := (B, A mod B) ... */
4473decc9a1Sjsing A = B;
4483decc9a1Sjsing B = M;
4493decc9a1Sjsing /* ... so we have 0 <= B < A again */
4503decc9a1Sjsing
4513decc9a1Sjsing /* Since the former M is now B and the former B is now A,
4523decc9a1Sjsing * (**) translates into
4533decc9a1Sjsing * sign*Y*a == D*A + B (mod |n|),
4543decc9a1Sjsing * i.e.
4553decc9a1Sjsing * sign*Y*a - D*A == B (mod |n|).
4563decc9a1Sjsing * Similarly, (*) translates into
4573decc9a1Sjsing * -sign*X*a == A (mod |n|).
4583decc9a1Sjsing *
4593decc9a1Sjsing * Thus,
4603decc9a1Sjsing * sign*Y*a + D*sign*X*a == B (mod |n|),
4613decc9a1Sjsing * i.e.
4623decc9a1Sjsing * sign*(Y + D*X)*a == B (mod |n|).
4633decc9a1Sjsing *
4643decc9a1Sjsing * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
4653decc9a1Sjsing * -sign*X*a == B (mod |n|),
4663decc9a1Sjsing * sign*Y*a == A (mod |n|).
4673decc9a1Sjsing * Note that X and Y stay non-negative all the time.
4683decc9a1Sjsing */
4693decc9a1Sjsing
4703decc9a1Sjsing if (!BN_mul(tmp, D, X, ctx))
4713decc9a1Sjsing goto err;
4723decc9a1Sjsing if (!BN_add(tmp, tmp, Y))
4733decc9a1Sjsing goto err;
4743decc9a1Sjsing
4753decc9a1Sjsing M = Y; /* keep the BIGNUM object, the value does not matter */
4763decc9a1Sjsing Y = X;
4773decc9a1Sjsing X = tmp;
4783decc9a1Sjsing sign = -sign;
4793decc9a1Sjsing }
4803decc9a1Sjsing
4813decc9a1Sjsing /*
4823decc9a1Sjsing * The while loop (Euclid's algorithm) ends when
4833decc9a1Sjsing * A == gcd(a,n);
4843decc9a1Sjsing * we have
4853decc9a1Sjsing * sign*Y*a == A (mod |n|),
4863decc9a1Sjsing * where Y is non-negative.
4873decc9a1Sjsing */
4883decc9a1Sjsing
4893decc9a1Sjsing if (sign < 0) {
4903decc9a1Sjsing if (!BN_sub(Y, n, Y))
4913decc9a1Sjsing goto err;
4923decc9a1Sjsing }
4933decc9a1Sjsing /* Now Y*a == A (mod |n|). */
4943decc9a1Sjsing
49576a537bbStb if (!BN_is_one(A)) {
4963decc9a1Sjsing BNerror(BN_R_NO_INVERSE);
4973decc9a1Sjsing goto err;
4983decc9a1Sjsing }
49976a537bbStb
50076a537bbStb if (!BN_nnmod(Y, Y, n, ctx))
50176a537bbStb goto err;
50276a537bbStb if (!bn_copy(R, Y))
50376a537bbStb goto err;
50476a537bbStb
5053decc9a1Sjsing ret = R;
5063decc9a1Sjsing
5073decc9a1Sjsing err:
5083decc9a1Sjsing if ((ret == NULL) && (in == NULL))
5093decc9a1Sjsing BN_free(R);
5103decc9a1Sjsing BN_CTX_end(ctx);
5113decc9a1Sjsing return (ret);
5123decc9a1Sjsing }
513da347917Sbeck
5145b37fcf3Sryker /* solves ax == 1 (mod n) */
515b0f5cbc3Sbeck static BIGNUM *
BN_mod_inverse_internal(BIGNUM * in,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx,int ct)516b0f5cbc3Sbeck BN_mod_inverse_internal(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx,
517b0f5cbc3Sbeck int ct)
5185b37fcf3Sryker {
519da347917Sbeck BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
520da347917Sbeck BIGNUM *ret = NULL;
5215b37fcf3Sryker int sign;
5225b37fcf3Sryker
523b0f5cbc3Sbeck if (ct)
5244fcf65c5Sdjm return BN_mod_inverse_no_branch(in, a, n, ctx);
5254fcf65c5Sdjm
526ba5406e9Sbeck BN_CTX_start(ctx);
527aa389b8cSjsing if ((A = BN_CTX_get(ctx)) == NULL)
528aa389b8cSjsing goto err;
529aa389b8cSjsing if ((B = BN_CTX_get(ctx)) == NULL)
530aa389b8cSjsing goto err;
531aa389b8cSjsing if ((X = BN_CTX_get(ctx)) == NULL)
532aa389b8cSjsing goto err;
533aa389b8cSjsing if ((D = BN_CTX_get(ctx)) == NULL)
534aa389b8cSjsing goto err;
535aa389b8cSjsing if ((M = BN_CTX_get(ctx)) == NULL)
536aa389b8cSjsing goto err;
537aa389b8cSjsing if ((Y = BN_CTX_get(ctx)) == NULL)
538aa389b8cSjsing goto err;
539aa389b8cSjsing if ((T = BN_CTX_get(ctx)) == NULL)
5402bd9bb84Sjsing goto err;
541ba5406e9Sbeck
542913ec974Sbeck if (in == NULL)
5435b37fcf3Sryker R = BN_new();
544913ec974Sbeck else
545913ec974Sbeck R = in;
5462bd9bb84Sjsing if (R == NULL)
5472bd9bb84Sjsing goto err;
5485b37fcf3Sryker
549dd1a6ee8Sjsing if (!BN_one(X))
550dd1a6ee8Sjsing goto err;
551da347917Sbeck BN_zero(Y);
55258460d4fStb if (!bn_copy(B, a))
5532bd9bb84Sjsing goto err;
55458460d4fStb if (!bn_copy(A, n))
5552bd9bb84Sjsing goto err;
556da347917Sbeck A->neg = 0;
5572bd9bb84Sjsing if (B->neg || (BN_ucmp(B, A) >= 0)) {
5582bd9bb84Sjsing if (!BN_nnmod(B, B, A, ctx))
5592bd9bb84Sjsing goto err;
560da347917Sbeck }
561da347917Sbeck sign = -1;
562da347917Sbeck /* From B = a mod |n|, A = |n| it follows that
563da347917Sbeck *
564da347917Sbeck * 0 <= B < A,
565da347917Sbeck * -sign*X*a == B (mod |n|),
566da347917Sbeck * sign*Y*a == A (mod |n|).
567da347917Sbeck */
568da347917Sbeck
5692bd9bb84Sjsing if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) {
570da347917Sbeck /* Binary inversion algorithm; requires odd modulus.
571da347917Sbeck * This is faster than the general algorithm if the modulus
572da347917Sbeck * is sufficiently small (about 400 .. 500 bits on 32-bit
57371743258Sjmc * systems, but much more on 64-bit systems) */
574da347917Sbeck int shift;
5755b37fcf3Sryker
5762bd9bb84Sjsing while (!BN_is_zero(B)) {
577da347917Sbeck /*
578da347917Sbeck * 0 < B < |n|,
579da347917Sbeck * 0 < A <= |n|,
580da347917Sbeck * (1) -sign*X*a == B (mod |n|),
581da347917Sbeck * (2) sign*Y*a == A (mod |n|)
582da347917Sbeck */
583da347917Sbeck
584da347917Sbeck /* Now divide B by the maximum possible power of two in the integers,
585da347917Sbeck * and divide X by the same value mod |n|.
586da347917Sbeck * When we're done, (1) still holds. */
587da347917Sbeck shift = 0;
588da347917Sbeck while (!BN_is_bit_set(B, shift)) /* note that 0 < B */
589da347917Sbeck {
590da347917Sbeck shift++;
591da347917Sbeck
5922bd9bb84Sjsing if (BN_is_odd(X)) {
5932bd9bb84Sjsing if (!BN_uadd(X, X, n))
5942bd9bb84Sjsing goto err;
595da347917Sbeck }
596da347917Sbeck /* now X is even, so we can easily divide it by two */
5972bd9bb84Sjsing if (!BN_rshift1(X, X))
5982bd9bb84Sjsing goto err;
599da347917Sbeck }
6002bd9bb84Sjsing if (shift > 0) {
6012bd9bb84Sjsing if (!BN_rshift(B, B, shift))
6022bd9bb84Sjsing goto err;
603da347917Sbeck }
604da347917Sbeck
605da347917Sbeck /* Same for A and Y. Afterwards, (2) still holds. */
606da347917Sbeck shift = 0;
607da347917Sbeck while (!BN_is_bit_set(A, shift)) /* note that 0 < A */
608da347917Sbeck {
609da347917Sbeck shift++;
610da347917Sbeck
6112bd9bb84Sjsing if (BN_is_odd(Y)) {
6122bd9bb84Sjsing if (!BN_uadd(Y, Y, n))
6132bd9bb84Sjsing goto err;
614da347917Sbeck }
615da347917Sbeck /* now Y is even */
6162bd9bb84Sjsing if (!BN_rshift1(Y, Y))
6172bd9bb84Sjsing goto err;
618da347917Sbeck }
6192bd9bb84Sjsing if (shift > 0) {
6202bd9bb84Sjsing if (!BN_rshift(A, A, shift))
6212bd9bb84Sjsing goto err;
622da347917Sbeck }
623da347917Sbeck
624da347917Sbeck /* We still have (1) and (2).
625da347917Sbeck * Both A and B are odd.
626da347917Sbeck * The following computations ensure that
627da347917Sbeck *
628da347917Sbeck * 0 <= B < |n|,
629da347917Sbeck * 0 < A < |n|,
630da347917Sbeck * (1) -sign*X*a == B (mod |n|),
631da347917Sbeck * (2) sign*Y*a == A (mod |n|),
632da347917Sbeck *
633da347917Sbeck * and that either A or B is even in the next iteration.
634da347917Sbeck */
6352bd9bb84Sjsing if (BN_ucmp(B, A) >= 0) {
636da347917Sbeck /* -sign*(X + Y)*a == B - A (mod |n|) */
6372bd9bb84Sjsing if (!BN_uadd(X, X, Y))
6382bd9bb84Sjsing goto err;
639da347917Sbeck /* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
640da347917Sbeck * actually makes the algorithm slower */
6412bd9bb84Sjsing if (!BN_usub(B, B, A))
6422bd9bb84Sjsing goto err;
6432bd9bb84Sjsing } else {
644da347917Sbeck /* sign*(X + Y)*a == A - B (mod |n|) */
6452bd9bb84Sjsing if (!BN_uadd(Y, Y, X))
6462bd9bb84Sjsing goto err;
647da347917Sbeck /* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
6482bd9bb84Sjsing if (!BN_usub(A, A, B))
6492bd9bb84Sjsing goto err;
650da347917Sbeck }
651da347917Sbeck }
6522bd9bb84Sjsing } else {
653da347917Sbeck /* general inversion algorithm */
654da347917Sbeck
6552bd9bb84Sjsing while (!BN_is_zero(B)) {
656da347917Sbeck BIGNUM *tmp;
657da347917Sbeck
658da347917Sbeck /*
659da347917Sbeck * 0 < B < A,
660da347917Sbeck * (*) -sign*X*a == B (mod |n|),
661da347917Sbeck * sign*Y*a == A (mod |n|)
662da347917Sbeck */
663da347917Sbeck
664da347917Sbeck /* (D, M) := (A/B, A%B) ... */
6652bd9bb84Sjsing if (BN_num_bits(A) == BN_num_bits(B)) {
6662bd9bb84Sjsing if (!BN_one(D))
6672bd9bb84Sjsing goto err;
6682bd9bb84Sjsing if (!BN_sub(M, A, B))
6692bd9bb84Sjsing goto err;
6702bd9bb84Sjsing } else if (BN_num_bits(A) == BN_num_bits(B) + 1) {
671da347917Sbeck /* A/B is 1, 2, or 3 */
6722bd9bb84Sjsing if (!BN_lshift1(T, B))
6732bd9bb84Sjsing goto err;
6742bd9bb84Sjsing if (BN_ucmp(A, T) < 0) {
675da347917Sbeck /* A < 2*B, so D=1 */
6762bd9bb84Sjsing if (!BN_one(D))
6772bd9bb84Sjsing goto err;
6782bd9bb84Sjsing if (!BN_sub(M, A, B))
6792bd9bb84Sjsing goto err;
6802bd9bb84Sjsing } else {
681da347917Sbeck /* A >= 2*B, so D=2 or D=3 */
6822bd9bb84Sjsing if (!BN_sub(M, A, T))
6832bd9bb84Sjsing goto err;
684da347917Sbeck if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */
6852bd9bb84Sjsing if (BN_ucmp(A, D) < 0) {
686da347917Sbeck /* A < 3*B, so D=2 */
6872bd9bb84Sjsing if (!BN_set_word(D, 2))
6882bd9bb84Sjsing goto err;
689da347917Sbeck /* M (= A - 2*B) already has the correct value */
6902bd9bb84Sjsing } else {
691da347917Sbeck /* only D=3 remains */
6922bd9bb84Sjsing if (!BN_set_word(D, 3))
6932bd9bb84Sjsing goto err;
694da347917Sbeck /* currently M = A - 2*B, but we need M = A - 3*B */
6952bd9bb84Sjsing if (!BN_sub(M, M, B))
6962bd9bb84Sjsing goto err;
697da347917Sbeck }
698da347917Sbeck }
6992bd9bb84Sjsing } else {
700923a8ed2Sbeck if (!BN_div_nonct(D, M, A, B, ctx))
7012bd9bb84Sjsing goto err;
702da347917Sbeck }
703da347917Sbeck
704da347917Sbeck /* Now
705da347917Sbeck * A = D*B + M;
706da347917Sbeck * thus we have
707da347917Sbeck * (**) sign*Y*a == D*B + M (mod |n|).
708da347917Sbeck */
709da347917Sbeck tmp = A; /* keep the BIGNUM object, the value does not matter */
710da347917Sbeck
711da347917Sbeck /* (A, B) := (B, A mod B) ... */
7125b37fcf3Sryker A = B;
7135b37fcf3Sryker B = M;
714da347917Sbeck /* ... so we have 0 <= B < A again */
7155b37fcf3Sryker
716da347917Sbeck /* Since the former M is now B and the former B is now A,
717da347917Sbeck * (**) translates into
718da347917Sbeck * sign*Y*a == D*A + B (mod |n|),
719da347917Sbeck * i.e.
720da347917Sbeck * sign*Y*a - D*A == B (mod |n|).
721da347917Sbeck * Similarly, (*) translates into
722da347917Sbeck * -sign*X*a == A (mod |n|).
723da347917Sbeck *
724da347917Sbeck * Thus,
725da347917Sbeck * sign*Y*a + D*sign*X*a == B (mod |n|),
726da347917Sbeck * i.e.
727da347917Sbeck * sign*(Y + D*X)*a == B (mod |n|).
728da347917Sbeck *
729da347917Sbeck * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
730da347917Sbeck * -sign*X*a == B (mod |n|),
731da347917Sbeck * sign*Y*a == A (mod |n|).
732da347917Sbeck * Note that X and Y stay non-negative all the time.
733da347917Sbeck */
734da347917Sbeck
735da347917Sbeck /* most of the time D is very small, so we can optimize tmp := D*X+Y */
7362bd9bb84Sjsing if (BN_is_one(D)) {
7372bd9bb84Sjsing if (!BN_add(tmp, X, Y))
7382bd9bb84Sjsing goto err;
7392bd9bb84Sjsing } else {
7402bd9bb84Sjsing if (BN_is_word(D, 2)) {
7412bd9bb84Sjsing if (!BN_lshift1(tmp, X))
7422bd9bb84Sjsing goto err;
7432bd9bb84Sjsing } else if (BN_is_word(D, 4)) {
7442bd9bb84Sjsing if (!BN_lshift(tmp, X, 2))
7452bd9bb84Sjsing goto err;
7462bd9bb84Sjsing } else if (D->top == 1) {
747cef8f41dStb if (!bn_copy(tmp, X))
7482bd9bb84Sjsing goto err;
7492bd9bb84Sjsing if (!BN_mul_word(tmp, D->d[0]))
7502bd9bb84Sjsing goto err;
7512bd9bb84Sjsing } else {
7522bd9bb84Sjsing if (!BN_mul(tmp, D,X, ctx))
7532bd9bb84Sjsing goto err;
754da347917Sbeck }
7552bd9bb84Sjsing if (!BN_add(tmp, tmp, Y))
7562bd9bb84Sjsing goto err;
757da347917Sbeck }
758da347917Sbeck
759da347917Sbeck M = Y; /* keep the BIGNUM object, the value does not matter */
7605b37fcf3Sryker Y = X;
761da347917Sbeck X = tmp;
7625b37fcf3Sryker sign = -sign;
7635b37fcf3Sryker }
764da347917Sbeck }
765da347917Sbeck
766da347917Sbeck /*
767da347917Sbeck * The while loop (Euclid's algorithm) ends when
768da347917Sbeck * A == gcd(a,n);
769da347917Sbeck * we have
770da347917Sbeck * sign*Y*a == A (mod |n|),
771da347917Sbeck * where Y is non-negative.
772da347917Sbeck */
773da347917Sbeck
7742bd9bb84Sjsing if (sign < 0) {
7752bd9bb84Sjsing if (!BN_sub(Y, n, Y))
7762bd9bb84Sjsing goto err;
7775b37fcf3Sryker }
778da347917Sbeck /* Now Y*a == A (mod |n|). */
779da347917Sbeck
78076a537bbStb if (!BN_is_one(A)) {
7815067ae9fSbeck BNerror(BN_R_NO_INVERSE);
7825b37fcf3Sryker goto err;
7835b37fcf3Sryker }
78476a537bbStb
78576a537bbStb if (!BN_nnmod(Y, Y, n, ctx))
78676a537bbStb goto err;
78776a537bbStb if (!bn_copy(R, Y))
78876a537bbStb goto err;
78976a537bbStb
7905b37fcf3Sryker ret = R;
7912bd9bb84Sjsing
7925b37fcf3Sryker err:
7932bd9bb84Sjsing if ((ret == NULL) && (in == NULL))
7942bd9bb84Sjsing BN_free(R);
795ba5406e9Sbeck BN_CTX_end(ctx);
7964fcf65c5Sdjm return (ret);
7974fcf65c5Sdjm }
7984fcf65c5Sdjm
799b0f5cbc3Sbeck BIGNUM *
BN_mod_inverse(BIGNUM * in,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx)800b0f5cbc3Sbeck BN_mod_inverse(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
801b0f5cbc3Sbeck {
802b0f5cbc3Sbeck int ct = ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) ||
803b0f5cbc3Sbeck (BN_get_flags(n, BN_FLG_CONSTTIME) != 0));
804b0f5cbc3Sbeck return BN_mod_inverse_internal(in, a, n, ctx, ct);
805b0f5cbc3Sbeck }
806*6dd041f3Sbeck LCRYPTO_ALIAS(BN_mod_inverse);
807b0f5cbc3Sbeck
808b0f5cbc3Sbeck BIGNUM *
BN_mod_inverse_nonct(BIGNUM * in,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx)809b0f5cbc3Sbeck BN_mod_inverse_nonct(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
810b0f5cbc3Sbeck {
811b0f5cbc3Sbeck return BN_mod_inverse_internal(in, a, n, ctx, 0);
812b0f5cbc3Sbeck }
813b0f5cbc3Sbeck
814b0f5cbc3Sbeck BIGNUM *
BN_mod_inverse_ct(BIGNUM * in,const BIGNUM * a,const BIGNUM * n,BN_CTX * ctx)815b0f5cbc3Sbeck BN_mod_inverse_ct(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
816b0f5cbc3Sbeck {
817b0f5cbc3Sbeck return BN_mod_inverse_internal(in, a, n, ctx, 1);
818b0f5cbc3Sbeck }
819