ret=1;
err:
BN_CTX_end(ctx);
+ bn_check_top(r);
return(ret);
}
{
if (!BN_lshift(a,a,shifts)) goto err;
}
+ bn_check_top(a);
return(a);
err:
return(NULL);
* sign*Y*a == A (mod |n|).
*/
- if (BN_is_odd(n) && (BN_num_bits(n) <= 400))
+ if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048)))
{
/* Binary inversion algorithm; requires odd modulus.
* This is faster than the general algorithm if the modulus
- * is sufficiently small. */
+ * is sufficiently small (about 400 .. 500 bits on 32-bit
+ * sytems, but much more on 64-bit systems) */
int shift;
while (!BN_is_zero(B))
{
/*
- * 0 < B < A <= |n|,
+ * 0 < B < |n|,
+ * 0 < A <= |n|,
* (1) -sign*X*a == B (mod |n|),
* (2) sign*Y*a == A (mod |n|)
*/
}
- /* We still have (1) and (2), but A may no longer be larger than B.
+ /* We still have (1) and (2).
* Both A and B are odd.
* The following computations ensure that
*
- * 0 =< B < A = |n|,
+ * 0 <= B < |n|,
+ * 0 < A < |n|,
* (1) -sign*X*a == B (mod |n|),
- * (2) sign*Y*a == A (mod |n|)
+ * (2) sign*Y*a == A (mod |n|),
+ *
+ * and that either A or B is even in the next iteration.
*/
if (BN_ucmp(B, A) >= 0)
{
}
else
{
- /* general inversion algorithm (less efficient than binary inversion) */
+ /* general inversion algorithm */
while (!BN_is_zero(B))
{
err:
if ((ret == NULL) && (in == NULL)) BN_free(R);
BN_CTX_end(ctx);
+ if (ret)
+ bn_check_top(ret);
return(ret);
}