-/* crypto/bn/bn_mod.c */
+/* crypto/bn/bn_sqrt.c */
/* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
* and Bodo Moeller for the OpenSSL project. */
/* ====================================================================
* using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course
* in Algebraic Computational Number Theory", algorithm 1.5.1).
* 'p' must be prime!
- * If 'a' is not a square, this is not necessarily detected by
- * the algorithms; a bogus result must be expected in this case.
*/
{
BIGNUM *ret = in;
goto end;
if (!BN_set_word(ret, BN_is_bit_set(a, 0)))
{
- BN_free(ret);
+ if (ret != in)
+ BN_free(ret);
return NULL;
}
+ bn_check_top(ret);
return ret;
}
goto end;
if (!BN_set_word(ret, BN_is_one(a)))
{
- BN_free(ret);
+ if (ret != in)
+ BN_free(ret);
return NULL;
}
+ bn_check_top(ret);
return ret;
}
-#if 0 /* if BN_mod_sqrt is used with correct input, this just wastes time */
- r = BN_kronecker(a, p, ctx);
- if (r < -1) return NULL;
- if (r == -1)
- {
- BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
- return(NULL);
- }
-#endif
-
BN_CTX_start(ctx);
A = BN_CTX_get(ctx);
b = BN_CTX_get(ctx);
if (e == 1)
{
- /* The easy case: (|p|-1)/2 is odd, so 2 has an inverse
+ /*-
+ * The easy case: (|p|-1)/2 is odd, so 2 has an inverse
* modulo (|p|-1)/2, and square roots can be computed
* directly by modular exponentiation.
* We have
if (e == 2)
{
- /* |p| == 5 (mod 8)
+ /*-
+ * |p| == 5 (mod 8)
*
* In this case 2 is always a non-square since
* Legendre(2,p) = (-1)^((p^2-1)/8) for any odd prime.
goto end;
}
- /* Now we know that (if p is indeed prime) there is an integer
+ /*-
+ * Now we know that (if p is indeed prime) there is an integer
* k, 0 <= k < 2^e, such that
*
* a^q * y^k == 1 (mod p).
if (BN_is_zero(t))
{
/* special case: a == 0 (mod p) */
- if (!BN_zero(ret)) goto end;
+ BN_zero(ret);
err = 0;
goto end;
}
if (BN_is_zero(x))
{
/* special case: a == 0 (mod p) */
- if (!BN_zero(ret)) goto end;
+ BN_zero(ret);
err = 0;
goto end;
}
while (1)
{
- /* Now b is a^q * y^k for some even k (0 <= k < 2^E
+ /*-
+ * Now b is a^q * y^k for some even k (0 <= k < 2^E
* where E refers to the original value of e, which we
* don't keep in a variable), and x is a^((q+1)/2) * y^(k/2).
*
ret = NULL;
}
BN_CTX_end(ctx);
+ bn_check_top(ret);
return ret;
}