ssl/libcrypto/src/crypto/bn/bn_gcd.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* crypto/bn/bn_gcd.c */
       
     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 "cryptlib.h"
       
   113 #include "bn_lcl.h"
       
   114 
       
   115 static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
       
   116 
       
   117 EXPORT_C int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
       
   118 	{
       
   119 	BIGNUM *a,*b,*t;
       
   120 	int ret=0;
       
   121 
       
   122 	bn_check_top(in_a);
       
   123 	bn_check_top(in_b);
       
   124 
       
   125 	BN_CTX_start(ctx);
       
   126 	a = BN_CTX_get(ctx);
       
   127 	b = BN_CTX_get(ctx);
       
   128 	if (a == NULL || b == NULL) goto err;
       
   129 
       
   130 	if (BN_copy(a,in_a) == NULL) goto err;
       
   131 	if (BN_copy(b,in_b) == NULL) goto err;
       
   132 	a->neg = 0;
       
   133 	b->neg = 0;
       
   134 
       
   135 	if (BN_cmp(a,b) < 0) { t=a; a=b; b=t; }
       
   136 	t=euclid(a,b);
       
   137 	if (t == NULL) goto err;
       
   138 
       
   139 	if (BN_copy(r,t) == NULL) goto err;
       
   140 	ret=1;
       
   141 err:
       
   142 	BN_CTX_end(ctx);
       
   143 	bn_check_top(r);
       
   144 	return(ret);
       
   145 	}
       
   146 
       
   147 static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
       
   148 	{
       
   149 	BIGNUM *t;
       
   150 	int shifts=0;
       
   151 
       
   152 	bn_check_top(a);
       
   153 	bn_check_top(b);
       
   154 
       
   155 	/* 0 <= b <= a */
       
   156 	while (!BN_is_zero(b))
       
   157 		{
       
   158 		/* 0 < b <= a */
       
   159 
       
   160 		if (BN_is_odd(a))
       
   161 			{
       
   162 			if (BN_is_odd(b))
       
   163 				{
       
   164 				if (!BN_sub(a,a,b)) goto err;
       
   165 				if (!BN_rshift1(a,a)) goto err;
       
   166 				if (BN_cmp(a,b) < 0)
       
   167 					{ t=a; a=b; b=t; }
       
   168 				}
       
   169 			else		/* a odd - b even */
       
   170 				{
       
   171 				if (!BN_rshift1(b,b)) goto err;
       
   172 				if (BN_cmp(a,b) < 0)
       
   173 					{ t=a; a=b; b=t; }
       
   174 				}
       
   175 			}
       
   176 		else			/* a is even */
       
   177 			{
       
   178 			if (BN_is_odd(b))
       
   179 				{
       
   180 				if (!BN_rshift1(a,a)) goto err;
       
   181 				if (BN_cmp(a,b) < 0)
       
   182 					{ t=a; a=b; b=t; }
       
   183 				}
       
   184 			else		/* a even - b even */
       
   185 				{
       
   186 				if (!BN_rshift1(a,a)) goto err;
       
   187 				if (!BN_rshift1(b,b)) goto err;
       
   188 				shifts++;
       
   189 				}
       
   190 			}
       
   191 		/* 0 <= b <= a */
       
   192 		}
       
   193 
       
   194 	if (shifts)
       
   195 		{
       
   196 		if (!BN_lshift(a,a,shifts)) goto err;
       
   197 		}
       
   198 	bn_check_top(a);
       
   199 	return(a);
       
   200 err:
       
   201 	return(NULL);
       
   202 	}
       
   203 
       
   204 
       
   205 /* solves ax == 1 (mod n) */
       
   206 static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
       
   207         const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
       
   208 EXPORT_C BIGNUM *BN_mod_inverse(BIGNUM *in,
       
   209 	const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
       
   210 	{
       
   211 	BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
       
   212 	BIGNUM *ret=NULL;
       
   213 	int sign;
       
   214 	if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0))
       
   215 		{
       
   216 		return BN_mod_inverse_no_branch(in, a, n, ctx);
       
   217 		}
       
   218 
       
   219 	bn_check_top(a);
       
   220 	bn_check_top(n);
       
   221 
       
   222 	BN_CTX_start(ctx);
       
   223 	A = BN_CTX_get(ctx);
       
   224 	B = BN_CTX_get(ctx);
       
   225 	X = BN_CTX_get(ctx);
       
   226 	D = BN_CTX_get(ctx);
       
   227 	M = BN_CTX_get(ctx);
       
   228 	Y = BN_CTX_get(ctx);
       
   229 	T = BN_CTX_get(ctx);
       
   230 	if (T == NULL) goto err;
       
   231 
       
   232 	if (in == NULL)
       
   233 		R=BN_new();
       
   234 	else
       
   235 		R=in;
       
   236 	if (R == NULL) goto err;
       
   237 
       
   238 	BN_one(X);
       
   239 	BN_zero(Y);
       
   240 	if (BN_copy(B,a) == NULL) goto err;
       
   241 	if (BN_copy(A,n) == NULL) goto err;
       
   242 	A->neg = 0;
       
   243 	if (B->neg || (BN_ucmp(B, A) >= 0))
       
   244 		{
       
   245 		if (!BN_nnmod(B, B, A, ctx)) goto err;
       
   246 		}
       
   247 	sign = -1;
       
   248 	/* From  B = a mod |n|,  A = |n|  it follows that
       
   249 	 *
       
   250 	 *      0 <= B < A,
       
   251 	 *     -sign*X*a  ==  B   (mod |n|),
       
   252 	 *      sign*Y*a  ==  A   (mod |n|).
       
   253 	 */
       
   254 
       
   255 	if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048)))
       
   256 		{
       
   257 		/* Binary inversion algorithm; requires odd modulus.
       
   258 		 * This is faster than the general algorithm if the modulus
       
   259 		 * is sufficiently small (about 400 .. 500 bits on 32-bit
       
   260 		 * sytems, but much more on 64-bit systems) */
       
   261 		int shift;
       
   262 		
       
   263 		while (!BN_is_zero(B))
       
   264 			{
       
   265 			/*
       
   266 			 *      0 < B < |n|,
       
   267 			 *      0 < A <= |n|,
       
   268 			 * (1) -sign*X*a  ==  B   (mod |n|),
       
   269 			 * (2)  sign*Y*a  ==  A   (mod |n|)
       
   270 			 */
       
   271 
       
   272 			/* Now divide  B  by the maximum possible power of two in the integers,
       
   273 			 * and divide  X  by the same value mod |n|.
       
   274 			 * When we're done, (1) still holds. */
       
   275 			shift = 0;
       
   276 			while (!BN_is_bit_set(B, shift)) /* note that 0 < B */
       
   277 				{
       
   278 				shift++;
       
   279 				
       
   280 				if (BN_is_odd(X))
       
   281 					{
       
   282 					if (!BN_uadd(X, X, n)) goto err;
       
   283 					}
       
   284 				/* now X is even, so we can easily divide it by two */
       
   285 				if (!BN_rshift1(X, X)) goto err;
       
   286 				}
       
   287 			if (shift > 0)
       
   288 				{
       
   289 				if (!BN_rshift(B, B, shift)) goto err;
       
   290 				}
       
   291 
       
   292 
       
   293 			/* Same for  A  and  Y.  Afterwards, (2) still holds. */
       
   294 			shift = 0;
       
   295 			while (!BN_is_bit_set(A, shift)) /* note that 0 < A */
       
   296 				{
       
   297 				shift++;
       
   298 				
       
   299 				if (BN_is_odd(Y))
       
   300 					{
       
   301 					if (!BN_uadd(Y, Y, n)) goto err;
       
   302 					}
       
   303 				/* now Y is even */
       
   304 				if (!BN_rshift1(Y, Y)) goto err;
       
   305 				}
       
   306 			if (shift > 0)
       
   307 				{
       
   308 				if (!BN_rshift(A, A, shift)) goto err;
       
   309 				}
       
   310 
       
   311 			
       
   312 			/* We still have (1) and (2).
       
   313 			 * Both  A  and  B  are odd.
       
   314 			 * The following computations ensure that
       
   315 			 *
       
   316 			 *     0 <= B < |n|,
       
   317 			 *      0 < A < |n|,
       
   318 			 * (1) -sign*X*a  ==  B   (mod |n|),
       
   319 			 * (2)  sign*Y*a  ==  A   (mod |n|),
       
   320 			 *
       
   321 			 * and that either  A  or  B  is even in the next iteration.
       
   322 			 */
       
   323 			if (BN_ucmp(B, A) >= 0)
       
   324 				{
       
   325 				/* -sign*(X + Y)*a == B - A  (mod |n|) */
       
   326 				if (!BN_uadd(X, X, Y)) goto err;
       
   327 				/* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
       
   328 				 * actually makes the algorithm slower */
       
   329 				if (!BN_usub(B, B, A)) goto err;
       
   330 				}
       
   331 			else
       
   332 				{
       
   333 				/*  sign*(X + Y)*a == A - B  (mod |n|) */
       
   334 				if (!BN_uadd(Y, Y, X)) goto err;
       
   335 				/* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
       
   336 				if (!BN_usub(A, A, B)) goto err;
       
   337 				}
       
   338 			}
       
   339 		}
       
   340 	else
       
   341 		{
       
   342 		/* general inversion algorithm */
       
   343 
       
   344 		while (!BN_is_zero(B))
       
   345 			{
       
   346 			BIGNUM *tmp;
       
   347 			
       
   348 			/*
       
   349 			 *      0 < B < A,
       
   350 			 * (*) -sign*X*a  ==  B   (mod |n|),
       
   351 			 *      sign*Y*a  ==  A   (mod |n|)
       
   352 			 */
       
   353 			
       
   354 			/* (D, M) := (A/B, A%B) ... */
       
   355 			if (BN_num_bits(A) == BN_num_bits(B))
       
   356 				{
       
   357 				if (!BN_one(D)) goto err;
       
   358 				if (!BN_sub(M,A,B)) goto err;
       
   359 				}
       
   360 			else if (BN_num_bits(A) == BN_num_bits(B) + 1)
       
   361 				{
       
   362 				/* A/B is 1, 2, or 3 */
       
   363 				if (!BN_lshift1(T,B)) goto err;
       
   364 				if (BN_ucmp(A,T) < 0)
       
   365 					{
       
   366 					/* A < 2*B, so D=1 */
       
   367 					if (!BN_one(D)) goto err;
       
   368 					if (!BN_sub(M,A,B)) goto err;
       
   369 					}
       
   370 				else
       
   371 					{
       
   372 					/* A >= 2*B, so D=2 or D=3 */
       
   373 					if (!BN_sub(M,A,T)) goto err;
       
   374 					if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */
       
   375 					if (BN_ucmp(A,D) < 0)
       
   376 						{
       
   377 						/* A < 3*B, so D=2 */
       
   378 						if (!BN_set_word(D,2)) goto err;
       
   379 						/* M (= A - 2*B) already has the correct value */
       
   380 						}
       
   381 					else
       
   382 						{
       
   383 						/* only D=3 remains */
       
   384 						if (!BN_set_word(D,3)) goto err;
       
   385 						/* currently  M = A - 2*B,  but we need  M = A - 3*B */
       
   386 						if (!BN_sub(M,M,B)) goto err;
       
   387 						}
       
   388 					}
       
   389 				}
       
   390 			else
       
   391 				{
       
   392 				if (!BN_div(D,M,A,B,ctx)) goto err;
       
   393 				}
       
   394 			
       
   395 			/* Now
       
   396 			 *      A = D*B + M;
       
   397 			 * thus we have
       
   398 			 * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
       
   399 			 */
       
   400 			
       
   401 			tmp=A; /* keep the BIGNUM object, the value does not matter */
       
   402 			
       
   403 			/* (A, B) := (B, A mod B) ... */
       
   404 			A=B;
       
   405 			B=M;
       
   406 			/* ... so we have  0 <= B < A  again */
       
   407 			
       
   408 			/* Since the former  M  is now  B  and the former  B  is now  A,
       
   409 			 * (**) translates into
       
   410 			 *       sign*Y*a  ==  D*A + B    (mod |n|),
       
   411 			 * i.e.
       
   412 			 *       sign*Y*a - D*A  ==  B    (mod |n|).
       
   413 			 * Similarly, (*) translates into
       
   414 			 *      -sign*X*a  ==  A          (mod |n|).
       
   415 			 *
       
   416 			 * Thus,
       
   417 			 *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
       
   418 			 * i.e.
       
   419 			 *        sign*(Y + D*X)*a  ==  B  (mod |n|).
       
   420 			 *
       
   421 			 * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
       
   422 			 *      -sign*X*a  ==  B   (mod |n|),
       
   423 			 *       sign*Y*a  ==  A   (mod |n|).
       
   424 			 * Note that  X  and  Y  stay non-negative all the time.
       
   425 			 */
       
   426 			
       
   427 			/* most of the time D is very small, so we can optimize tmp := D*X+Y */
       
   428 			if (BN_is_one(D))
       
   429 				{
       
   430 				if (!BN_add(tmp,X,Y)) goto err;
       
   431 				}
       
   432 			else
       
   433 				{
       
   434 				if (BN_is_word(D,2))
       
   435 					{
       
   436 					if (!BN_lshift1(tmp,X)) goto err;
       
   437 					}
       
   438 				else if (BN_is_word(D,4))
       
   439 					{
       
   440 					if (!BN_lshift(tmp,X,2)) goto err;
       
   441 					}
       
   442 				else if (D->top == 1)
       
   443 					{
       
   444 					if (!BN_copy(tmp,X)) goto err;
       
   445 					if (!BN_mul_word(tmp,D->d[0])) goto err;
       
   446 					}
       
   447 				else
       
   448 					{
       
   449 					if (!BN_mul(tmp,D,X,ctx)) goto err;
       
   450 					}
       
   451 				if (!BN_add(tmp,tmp,Y)) goto err;
       
   452 				}
       
   453 			
       
   454 			M=Y; /* keep the BIGNUM object, the value does not matter */
       
   455 			Y=X;
       
   456 			X=tmp;
       
   457 			sign = -sign;
       
   458 			}
       
   459 		}
       
   460 		
       
   461 	/*
       
   462 	 * The while loop (Euclid's algorithm) ends when
       
   463 	 *      A == gcd(a,n);
       
   464 	 * we have
       
   465 	 *       sign*Y*a  ==  A  (mod |n|),
       
   466 	 * where  Y  is non-negative.
       
   467 	 */
       
   468 
       
   469 	if (sign < 0)
       
   470 		{
       
   471 		if (!BN_sub(Y,n,Y)) goto err;
       
   472 		}
       
   473 	/* Now  Y*a  ==  A  (mod |n|).  */
       
   474 	
       
   475 
       
   476 	if (BN_is_one(A))
       
   477 		{
       
   478 		/* Y*a == 1  (mod |n|) */
       
   479 		if (!Y->neg && BN_ucmp(Y,n) < 0)
       
   480 			{
       
   481 			if (!BN_copy(R,Y)) goto err;
       
   482 			}
       
   483 		else
       
   484 			{
       
   485 			if (!BN_nnmod(R,Y,n,ctx)) goto err;
       
   486 			}
       
   487 		}
       
   488 	else
       
   489 		{
       
   490 		BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE);
       
   491 		goto err;
       
   492 		}
       
   493 	ret=R;
       
   494 err:
       
   495 	if ((ret == NULL) && (in == NULL)) BN_free(R);
       
   496 	BN_CTX_end(ctx);
       
   497 	bn_check_top(ret);
       
   498 	return(ret);
       
   499 	}
       
   500 
       
   501 
       
   502 /* BN_mod_inverse_no_branch is a special version of BN_mod_inverse. 
       
   503  * It does not contain branches that may leak sensitive information.
       
   504  */
       
   505 static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
       
   506 	const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
       
   507 	{
       
   508 	BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
       
   509 	BIGNUM local_A, local_B;
       
   510 	BIGNUM *pA, *pB;
       
   511 	BIGNUM *ret=NULL;
       
   512 	int sign;
       
   513 
       
   514 	bn_check_top(a);
       
   515 	bn_check_top(n);
       
   516 
       
   517 	BN_CTX_start(ctx);
       
   518 	A = BN_CTX_get(ctx);
       
   519 	B = BN_CTX_get(ctx);
       
   520 	X = BN_CTX_get(ctx);
       
   521 	D = BN_CTX_get(ctx);
       
   522 	M = BN_CTX_get(ctx);
       
   523 	Y = BN_CTX_get(ctx);
       
   524 	T = BN_CTX_get(ctx);
       
   525 	if (T == NULL) goto err;
       
   526 
       
   527 	if (in == NULL)
       
   528 		R=BN_new();
       
   529 	else
       
   530 		R=in;
       
   531 	if (R == NULL) goto err;
       
   532 
       
   533 	BN_one(X);
       
   534 	BN_zero(Y);
       
   535 	if (BN_copy(B,a) == NULL) goto err;
       
   536 	if (BN_copy(A,n) == NULL) goto err;
       
   537 	A->neg = 0;
       
   538 
       
   539 	if (B->neg || (BN_ucmp(B, A) >= 0))
       
   540 		{
       
   541 		/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
       
   542 	 	 * BN_div_no_branch will be called eventually.
       
   543 	 	 */
       
   544 		pB = &local_B;
       
   545 		BN_with_flags(pB, B, BN_FLG_CONSTTIME);	
       
   546 		if (!BN_nnmod(B, pB, A, ctx)) goto err;
       
   547 		}
       
   548 	sign = -1;
       
   549 	/* From  B = a mod |n|,  A = |n|  it follows that
       
   550 	 *
       
   551 	 *      0 <= B < A,
       
   552 	 *     -sign*X*a  ==  B   (mod |n|),
       
   553 	 *      sign*Y*a  ==  A   (mod |n|).
       
   554 	 */
       
   555 
       
   556 	while (!BN_is_zero(B))
       
   557 		{
       
   558 		BIGNUM *tmp;
       
   559 		
       
   560 		/*
       
   561 		 *      0 < B < A,
       
   562 		 * (*) -sign*X*a  ==  B   (mod |n|),
       
   563 		 *      sign*Y*a  ==  A   (mod |n|)
       
   564 		 */
       
   565 
       
   566 		/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
       
   567 	 	 * BN_div_no_branch will be called eventually.
       
   568 	 	 */
       
   569 		pA = &local_A;
       
   570 		BN_with_flags(pA, A, BN_FLG_CONSTTIME);	
       
   571 		
       
   572 		/* (D, M) := (A/B, A%B) ... */		
       
   573 		if (!BN_div(D,M,pA,B,ctx)) goto err;
       
   574 		
       
   575 		/* Now
       
   576 		 *      A = D*B + M;
       
   577 		 * thus we have
       
   578 		 * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
       
   579 		 */
       
   580 		
       
   581 		tmp=A; /* keep the BIGNUM object, the value does not matter */
       
   582 		
       
   583 		/* (A, B) := (B, A mod B) ... */
       
   584 		A=B;
       
   585 		B=M;
       
   586 		/* ... so we have  0 <= B < A  again */
       
   587 		
       
   588 		/* Since the former  M  is now  B  and the former  B  is now  A,
       
   589 		 * (**) translates into
       
   590 		 *       sign*Y*a  ==  D*A + B    (mod |n|),
       
   591 		 * i.e.
       
   592 		 *       sign*Y*a - D*A  ==  B    (mod |n|).
       
   593 		 * Similarly, (*) translates into
       
   594 		 *      -sign*X*a  ==  A          (mod |n|).
       
   595 		 *
       
   596 		 * Thus,
       
   597 		 *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
       
   598 		 * i.e.
       
   599 		 *        sign*(Y + D*X)*a  ==  B  (mod |n|).
       
   600 		 *
       
   601 		 * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
       
   602 		 *      -sign*X*a  ==  B   (mod |n|),
       
   603 		 *       sign*Y*a  ==  A   (mod |n|).
       
   604 		 * Note that  X  and  Y  stay non-negative all the time.
       
   605 		 */
       
   606 			
       
   607 		if (!BN_mul(tmp,D,X,ctx)) goto err;
       
   608 		if (!BN_add(tmp,tmp,Y)) goto err;
       
   609 
       
   610 		M=Y; /* keep the BIGNUM object, the value does not matter */
       
   611 		Y=X;
       
   612 		X=tmp;
       
   613 		sign = -sign;
       
   614 		}
       
   615 		
       
   616 	/*
       
   617 	 * The while loop (Euclid's algorithm) ends when
       
   618 	 *      A == gcd(a,n);
       
   619 	 * we have
       
   620 	 *       sign*Y*a  ==  A  (mod |n|),
       
   621 	 * where  Y  is non-negative.
       
   622 	 */
       
   623 
       
   624 	if (sign < 0)
       
   625 		{
       
   626 		if (!BN_sub(Y,n,Y)) goto err;
       
   627 		}
       
   628 	/* Now  Y*a  ==  A  (mod |n|).  */
       
   629 
       
   630 	if (BN_is_one(A))
       
   631 		{
       
   632 		/* Y*a == 1  (mod |n|) */
       
   633 		if (!Y->neg && BN_ucmp(Y,n) < 0)
       
   634 			{
       
   635 			if (!BN_copy(R,Y)) goto err;
       
   636 			}
       
   637 		else
       
   638 			{
       
   639 			if (!BN_nnmod(R,Y,n,ctx)) goto err;
       
   640 			}
       
   641 		}
       
   642 	else
       
   643 		{
       
   644 		BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH,BN_R_NO_INVERSE);
       
   645 		goto err;
       
   646 		}
       
   647 	ret=R;
       
   648 err:
       
   649 	if ((ret == NULL) && (in == NULL)) BN_free(R);
       
   650 	BN_CTX_end(ctx);
       
   651 	bn_check_top(ret);
       
   652 	return(ret);
       
   653 	}