1*12347e81Stb /* $OpenBSD: bn_mod_sqrt.c,v 1.3 2023/08/03 18:53:55 tb Exp $ */
25290b413Stb
35290b413Stb /*
45290b413Stb * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
55290b413Stb *
65290b413Stb * Permission to use, copy, modify, and distribute this software for any
75290b413Stb * purpose with or without fee is hereby granted, provided that the above
85290b413Stb * copyright notice and this permission notice appear in all copies.
95290b413Stb *
105290b413Stb * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
115290b413Stb * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
125290b413Stb * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
135290b413Stb * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
145290b413Stb * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
155290b413Stb * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
165290b413Stb * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
175290b413Stb */
185290b413Stb
195290b413Stb #include <openssl/err.h>
205290b413Stb
215290b413Stb #include "bn_local.h"
225290b413Stb
235290b413Stb /*
245290b413Stb * Tonelli-Shanks according to H. Cohen "A Course in Computational Algebraic
255290b413Stb * Number Theory", Section 1.5.1, Springer GTM volume 138, Berlin, 1996.
265290b413Stb *
275290b413Stb * Under the assumption that p is prime and a is a quadratic residue, we know:
285290b413Stb *
295290b413Stb * a^[(p-1)/2] = 1 (mod p). (*)
305290b413Stb *
315290b413Stb * To find a square root of a (mod p), we handle three cases of increasing
325290b413Stb * complexity. In the first two cases, we can compute a square root using an
335290b413Stb * explicit formula, thus avoiding the probabilistic nature of Tonelli-Shanks.
345290b413Stb *
355290b413Stb * 1. p = 3 (mod 4).
365290b413Stb *
375290b413Stb * Set n = (p+1)/4. Then 2n = 1 + (p-1)/2 and (*) shows that x = a^n (mod p)
385290b413Stb * is a square root of a: x^2 = a^(2n) = a * a^[(p-1)/2] = a (mod p).
395290b413Stb *
405290b413Stb * 2. p = 5 (mod 8).
415290b413Stb *
425290b413Stb * This uses a simplification due to Atkin. By Theorem 1.4.7 and 1.4.9, the
435290b413Stb * Kronecker symbol (2/p) evaluates to (-1)^[(p^2-1)/8]. From p = 5 (mod 8)
445290b413Stb * we get (p^2-1)/8 = 1 (mod 2), so (2/p) = -1, and thus
455290b413Stb *
465290b413Stb * 2^[(p-1)/2] = -1 (mod p). (**)
475290b413Stb *
485290b413Stb * Set b = (2a)^[(p-5)/8]. With (p-1)/2 = 2 + (p-5)/2, (*) and (**) show
495290b413Stb *
505290b413Stb * i = 2 a b^2 is a square root of -1 (mod p).
515290b413Stb *
525290b413Stb * Indeed, i^2 = 2^2 a^2 b^4 = 2^[(p-1)/2] a^[(p-1)/2] = -1 (mod p). Because
535290b413Stb * of (i-1)^2 = -2i (mod p) and i (-i) = 1 (mod p), a square root of a is
545290b413Stb *
555290b413Stb * x = a b (i-1)
565290b413Stb *
575290b413Stb * as x^2 = a^2 b^2 (-2i) = a (2 a b^2) (-i) = a (mod p).
585290b413Stb *
595290b413Stb * 3. p = 1 (mod 8).
605290b413Stb *
615290b413Stb * This is the Tonelli-Shanks algorithm. For a prime p, the multiplicative
625290b413Stb * group of GF(p) is cyclic of order p - 1 = 2^s q, with odd q. Denote its
635290b413Stb * 2-Sylow subgroup by S. It is cyclic of order 2^s. The squares in S have
645290b413Stb * order dividing 2^(s-1). They are the even powers of any generator z of S.
655290b413Stb * If a is a quadratic residue, 1 = a^[(p-1)/2] = (a^q)^[2^(s-1)], so b = a^q
665290b413Stb * is a square in S. Therefore there is an integer k such that b z^(2k) = 1.
675290b413Stb * Set x = a^[(q+1)/2] z^k, and find x^2 = a (mod p).
685290b413Stb *
695290b413Stb * The problem is thus reduced to finding a generator z of the 2-Sylow
705290b413Stb * subgroup S of GF(p)* and finding k. An iterative constructions avoids
715290b413Stb * the need for an explicit k, a generator is found by a randomized search.
725290b413Stb *
735290b413Stb * While we do not actually know that p is a prime number, we can still apply
745290b413Stb * the formulas in cases 1 and 2 and verify that we have indeed found a square
755290b413Stb * root of p. Similarly, in case 3, we can try to find a quadratic non-residue,
765290b413Stb * which will fail for example if p is a square. The iterative construction
775290b413Stb * may or may not find a candidate square root which we can then validate.
785290b413Stb */
795290b413Stb
805290b413Stb /*
815290b413Stb * Handle the cases where p is 2, p isn't odd or p is one. Since BN_mod_sqrt()
825290b413Stb * can run on untrusted data, a primality check is too expensive. Also treat
835290b413Stb * the obvious cases where a is 0 or 1.
845290b413Stb */
855290b413Stb
865290b413Stb static int
bn_mod_sqrt_trivial_cases(int * done,BIGNUM * out_sqrt,const BIGNUM * a,const BIGNUM * p,BN_CTX * ctx)875290b413Stb bn_mod_sqrt_trivial_cases(int *done, BIGNUM *out_sqrt, const BIGNUM *a,
885290b413Stb const BIGNUM *p, BN_CTX *ctx)
895290b413Stb {
905290b413Stb *done = 1;
915290b413Stb
925290b413Stb if (BN_abs_is_word(p, 2))
935290b413Stb return BN_set_word(out_sqrt, BN_is_odd(a));
945290b413Stb
955290b413Stb if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) {
965290b413Stb BNerror(BN_R_P_IS_NOT_PRIME);
975290b413Stb return 0;
985290b413Stb }
995290b413Stb
1005290b413Stb if (BN_is_zero(a) || BN_is_one(a))
1015290b413Stb return BN_set_word(out_sqrt, BN_is_one(a));
1025290b413Stb
1035290b413Stb *done = 0;
1045290b413Stb
1055290b413Stb return 1;
1065290b413Stb }
1075290b413Stb
1085290b413Stb /*
1095290b413Stb * Case 1. We know that (a/p) = 1 and that p = 3 (mod 4).
1105290b413Stb */
1115290b413Stb
1125290b413Stb static int
bn_mod_sqrt_p_is_3_mod_4(BIGNUM * out_sqrt,const BIGNUM * a,const BIGNUM * p,BN_CTX * ctx)1135290b413Stb bn_mod_sqrt_p_is_3_mod_4(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p,
1145290b413Stb BN_CTX *ctx)
1155290b413Stb {
1165290b413Stb BIGNUM *n;
1175290b413Stb int ret = 0;
1185290b413Stb
1195290b413Stb BN_CTX_start(ctx);
1205290b413Stb
1215290b413Stb if ((n = BN_CTX_get(ctx)) == NULL)
1225290b413Stb goto err;
1235290b413Stb
1245290b413Stb /* Calculate n = (|p| + 1) / 4. */
1255290b413Stb if (!BN_uadd(n, p, BN_value_one()))
1265290b413Stb goto err;
1275290b413Stb if (!BN_rshift(n, n, 2))
1285290b413Stb goto err;
1295290b413Stb
1305290b413Stb /* By case 1 above, out_sqrt = a^n is a square root of a (mod p). */
1315290b413Stb if (!BN_mod_exp_ct(out_sqrt, a, n, p, ctx))
1325290b413Stb goto err;
1335290b413Stb
1345290b413Stb ret = 1;
1355290b413Stb
1365290b413Stb err:
1375290b413Stb BN_CTX_end(ctx);
1385290b413Stb
1395290b413Stb return ret;
1405290b413Stb }
1415290b413Stb
1425290b413Stb /*
1435290b413Stb * Case 2. We know that (a/p) = 1 and that p = 5 (mod 8).
1445290b413Stb */
1455290b413Stb
1465290b413Stb static int
bn_mod_sqrt_p_is_5_mod_8(BIGNUM * out_sqrt,const BIGNUM * a,const BIGNUM * p,BN_CTX * ctx)1475290b413Stb bn_mod_sqrt_p_is_5_mod_8(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p,
1485290b413Stb BN_CTX *ctx)
1495290b413Stb {
1505290b413Stb BIGNUM *b, *i, *n, *tmp;
1515290b413Stb int ret = 0;
1525290b413Stb
1535290b413Stb BN_CTX_start(ctx);
1545290b413Stb
1555290b413Stb if ((b = BN_CTX_get(ctx)) == NULL)
1565290b413Stb goto err;
1575290b413Stb if ((i = BN_CTX_get(ctx)) == NULL)
1585290b413Stb goto err;
1595290b413Stb if ((n = BN_CTX_get(ctx)) == NULL)
1605290b413Stb goto err;
1615290b413Stb if ((tmp = BN_CTX_get(ctx)) == NULL)
1625290b413Stb goto err;
1635290b413Stb
1645290b413Stb /* Calculate n = (|p| - 5) / 8. Since p = 5 (mod 8), simply shift. */
1655290b413Stb if (!BN_rshift(n, p, 3))
1665290b413Stb goto err;
1675290b413Stb BN_set_negative(n, 0);
1685290b413Stb
1695290b413Stb /* Compute tmp = 2a (mod p) for later use. */
1705290b413Stb if (!BN_mod_lshift1(tmp, a, p, ctx))
1715290b413Stb goto err;
1725290b413Stb
1735290b413Stb /* Calculate b = (2a)^n (mod p). */
1745290b413Stb if (!BN_mod_exp_ct(b, tmp, n, p, ctx))
1755290b413Stb goto err;
1765290b413Stb
1775290b413Stb /* Calculate i = 2 a b^2 (mod p). */
1785290b413Stb if (!BN_mod_sqr(i, b, p, ctx))
1795290b413Stb goto err;
1805290b413Stb if (!BN_mod_mul(i, tmp, i, p, ctx))
1815290b413Stb goto err;
1825290b413Stb
1835290b413Stb /* A square root is out_sqrt = a b (i-1) (mod p). */
1845290b413Stb if (!BN_sub_word(i, 1))
1855290b413Stb goto err;
1865290b413Stb if (!BN_mod_mul(out_sqrt, a, b, p, ctx))
1875290b413Stb goto err;
1885290b413Stb if (!BN_mod_mul(out_sqrt, out_sqrt, i, p, ctx))
1895290b413Stb goto err;
1905290b413Stb
1915290b413Stb ret = 1;
1925290b413Stb
1935290b413Stb err:
1945290b413Stb BN_CTX_end(ctx);
1955290b413Stb
1965290b413Stb return ret;
1975290b413Stb }
1985290b413Stb
1995290b413Stb /*
2005290b413Stb * Case 3. We know that (a/p) = 1 and that p = 1 (mod 8).
2015290b413Stb */
2025290b413Stb
2035290b413Stb /*
2045290b413Stb * Simple helper. To find a generator of the 2-Sylow subgroup of GF(p)*, we
2055290b413Stb * need to find a quadratic non-residue of p, i.e., n such that (n/p) = -1.
2065290b413Stb */
2075290b413Stb
2085290b413Stb static int
bn_mod_sqrt_n_is_non_residue(int * is_non_residue,const BIGNUM * n,const BIGNUM * p,BN_CTX * ctx)2095290b413Stb bn_mod_sqrt_n_is_non_residue(int *is_non_residue, const BIGNUM *n,
2105290b413Stb const BIGNUM *p, BN_CTX *ctx)
2115290b413Stb {
2125290b413Stb switch (BN_kronecker(n, p, ctx)) {
2135290b413Stb case -1:
2145290b413Stb *is_non_residue = 1;
2155290b413Stb return 1;
2165290b413Stb case 1:
2175290b413Stb *is_non_residue = 0;
2185290b413Stb return 1;
2195290b413Stb case 0:
2205290b413Stb /* n divides p, so ... */
2215290b413Stb BNerror(BN_R_P_IS_NOT_PRIME);
2225290b413Stb return 0;
2235290b413Stb default:
2245290b413Stb return 0;
2255290b413Stb }
2265290b413Stb }
2275290b413Stb
2285290b413Stb /*
2295290b413Stb * The following is the only non-deterministic part preparing Tonelli-Shanks.
2305290b413Stb *
2315290b413Stb * If we find n such that (n/p) = -1, then n^q (mod p) is a generator of the
2325290b413Stb * 2-Sylow subgroup of GF(p)*. To find such n, first try some small numbers,
2335290b413Stb * then random ones.
2345290b413Stb */
2355290b413Stb
2365290b413Stb static int
bn_mod_sqrt_find_sylow_generator(BIGNUM * out_generator,const BIGNUM * p,const BIGNUM * q,BN_CTX * ctx)2375290b413Stb bn_mod_sqrt_find_sylow_generator(BIGNUM *out_generator, const BIGNUM *p,
2385290b413Stb const BIGNUM *q, BN_CTX *ctx)
2395290b413Stb {
240*12347e81Stb BIGNUM *n, *p_abs;
2415290b413Stb int i, is_non_residue;
2425290b413Stb int ret = 0;
2435290b413Stb
2445290b413Stb BN_CTX_start(ctx);
2455290b413Stb
2465290b413Stb if ((n = BN_CTX_get(ctx)) == NULL)
2475290b413Stb goto err;
2485290b413Stb if ((p_abs = BN_CTX_get(ctx)) == NULL)
2495290b413Stb goto err;
2505290b413Stb
2515290b413Stb for (i = 2; i < 32; i++) {
2525290b413Stb if (!BN_set_word(n, i))
2535290b413Stb goto err;
2545290b413Stb if (!bn_mod_sqrt_n_is_non_residue(&is_non_residue, n, p, ctx))
2555290b413Stb goto err;
2565290b413Stb if (is_non_residue)
2575290b413Stb goto found;
2585290b413Stb }
2595290b413Stb
2605290b413Stb if (!bn_copy(p_abs, p))
2615290b413Stb goto err;
2625290b413Stb BN_set_negative(p_abs, 0);
2635290b413Stb
2645290b413Stb for (i = 0; i < 128; i++) {
265*12347e81Stb if (!bn_rand_interval(n, 32, p_abs))
2665290b413Stb goto err;
2675290b413Stb if (!bn_mod_sqrt_n_is_non_residue(&is_non_residue, n, p, ctx))
2685290b413Stb goto err;
2695290b413Stb if (is_non_residue)
2705290b413Stb goto found;
2715290b413Stb }
2725290b413Stb
2735290b413Stb /*
2745290b413Stb * The probability to get here is < 2^(-128) for prime p. For squares
2755290b413Stb * it is easy: for p = 1369 = 37^2 this happens in ~3% of runs.
2765290b413Stb */
2775290b413Stb
2785290b413Stb BNerror(BN_R_TOO_MANY_ITERATIONS);
2795290b413Stb goto err;
2805290b413Stb
2815290b413Stb found:
2825290b413Stb /*
2835290b413Stb * If p is prime, n^q generates the 2-Sylow subgroup S of GF(p)*.
2845290b413Stb */
2855290b413Stb
2865290b413Stb if (!BN_mod_exp_ct(out_generator, n, q, p, ctx))
2875290b413Stb goto err;
2885290b413Stb
2895290b413Stb /* Sanity: p is not necessarily prime, so we could have found 0 or 1. */
2905290b413Stb if (BN_is_zero(out_generator) || BN_is_one(out_generator)) {
2915290b413Stb BNerror(BN_R_P_IS_NOT_PRIME);
2925290b413Stb goto err;
2935290b413Stb }
2945290b413Stb
2955290b413Stb ret = 1;
2965290b413Stb
2975290b413Stb err:
2985290b413Stb BN_CTX_end(ctx);
2995290b413Stb
3005290b413Stb return ret;
3015290b413Stb }
3025290b413Stb
3035290b413Stb /*
3045290b413Stb * Initialization step for Tonelli-Shanks.
3055290b413Stb *
3065290b413Stb * In the end, b = a^q (mod p) and x = a^[(q+1)/2] (mod p). Cohen optimizes this
3075290b413Stb * to minimize taking powers of a. This is a bit confusing and distracting, so
3085290b413Stb * factor this into a separate function.
3095290b413Stb */
3105290b413Stb
3115290b413Stb static int
bn_mod_sqrt_tonelli_shanks_initialize(BIGNUM * b,BIGNUM * x,const BIGNUM * a,const BIGNUM * p,const BIGNUM * q,BN_CTX * ctx)3125290b413Stb bn_mod_sqrt_tonelli_shanks_initialize(BIGNUM *b, BIGNUM *x, const BIGNUM *a,
3135290b413Stb const BIGNUM *p, const BIGNUM *q, BN_CTX *ctx)
3145290b413Stb {
3155290b413Stb BIGNUM *k;
3165290b413Stb int ret = 0;
3175290b413Stb
3185290b413Stb BN_CTX_start(ctx);
3195290b413Stb
3205290b413Stb if ((k = BN_CTX_get(ctx)) == NULL)
3215290b413Stb goto err;
3225290b413Stb
3235290b413Stb /* k = (q-1)/2. Since q is odd, we can shift. */
3245290b413Stb if (!BN_rshift1(k, q))
3255290b413Stb goto err;
3265290b413Stb
3275290b413Stb /* x = a^[(q-1)/2] (mod p). */
3285290b413Stb if (!BN_mod_exp_ct(x, a, k, p, ctx))
3295290b413Stb goto err;
3305290b413Stb
3315290b413Stb /* b = ax^2 = a^q (mod p). */
3325290b413Stb if (!BN_mod_sqr(b, x, p, ctx))
3335290b413Stb goto err;
3345290b413Stb if (!BN_mod_mul(b, a, b, p, ctx))
3355290b413Stb goto err;
3365290b413Stb
3375290b413Stb /* x = ax = a^[(q+1)/2] (mod p). */
3385290b413Stb if (!BN_mod_mul(x, a, x, p, ctx))
3395290b413Stb goto err;
3405290b413Stb
3415290b413Stb ret = 1;
3425290b413Stb
3435290b413Stb err:
3445290b413Stb BN_CTX_end(ctx);
3455290b413Stb
3465290b413Stb return ret;
3475290b413Stb }
3485290b413Stb
3495290b413Stb /*
3505290b413Stb * Find smallest exponent m such that b^(2^m) = 1 (mod p). Assuming that a
3515290b413Stb * is a quadratic residue and p is a prime, we know that 1 <= m < r.
3525290b413Stb */
3535290b413Stb
3545290b413Stb static int
bn_mod_sqrt_tonelli_shanks_find_exponent(int * out_exponent,const BIGNUM * b,const BIGNUM * p,int r,BN_CTX * ctx)3555290b413Stb bn_mod_sqrt_tonelli_shanks_find_exponent(int *out_exponent, const BIGNUM *b,
3565290b413Stb const BIGNUM *p, int r, BN_CTX *ctx)
3575290b413Stb {
3585290b413Stb BIGNUM *x;
3595290b413Stb int m;
3605290b413Stb int ret = 0;
3615290b413Stb
3625290b413Stb BN_CTX_start(ctx);
3635290b413Stb
3645290b413Stb if ((x = BN_CTX_get(ctx)) == NULL)
3655290b413Stb goto err;
3665290b413Stb
3675290b413Stb /*
3685290b413Stb * If r <= 1, the Tonelli-Shanks iteration should have terminated as
3695290b413Stb * r == 1 implies b == 1.
3705290b413Stb */
3715290b413Stb if (r <= 1) {
3725290b413Stb BNerror(BN_R_P_IS_NOT_PRIME);
3735290b413Stb goto err;
3745290b413Stb }
3755290b413Stb
3765290b413Stb /*
3775290b413Stb * Sanity check to ensure taking squares actually does something:
3785290b413Stb * If b is 1, the Tonelli-Shanks iteration should have terminated.
3795290b413Stb * If b is 0, something's very wrong, in particular p can't be prime.
3805290b413Stb */
3815290b413Stb if (BN_is_zero(b) || BN_is_one(b)) {
3825290b413Stb BNerror(BN_R_P_IS_NOT_PRIME);
3835290b413Stb goto err;
3845290b413Stb }
3855290b413Stb
3865290b413Stb if (!bn_copy(x, b))
3875290b413Stb goto err;
3885290b413Stb
3895290b413Stb for (m = 1; m < r; m++) {
3905290b413Stb if (!BN_mod_sqr(x, x, p, ctx))
3915290b413Stb goto err;
3925290b413Stb if (BN_is_one(x))
3935290b413Stb break;
3945290b413Stb }
3955290b413Stb
3965290b413Stb if (m >= r) {
3975290b413Stb /* This means a is not a quadratic residue. As (a/p) = 1, ... */
3985290b413Stb BNerror(BN_R_P_IS_NOT_PRIME);
3995290b413Stb goto err;
4005290b413Stb }
4015290b413Stb
4025290b413Stb *out_exponent = m;
4035290b413Stb
4045290b413Stb ret = 1;
4055290b413Stb
4065290b413Stb err:
4075290b413Stb BN_CTX_end(ctx);
4085290b413Stb
4095290b413Stb return ret;
4105290b413Stb }
4115290b413Stb
4125290b413Stb /*
4135290b413Stb * The update step. With the minimal m such that b^(2^m) = 1 (mod m),
4145290b413Stb * set t = y^[2^(r-m-1)] (mod p) and update x = xt, y = t^2, b = by.
4155290b413Stb * This preserves the loop invariants a b = x^2, y^[2^(r-1)] = -1 and
4165290b413Stb * b^[2^(r-1)] = 1.
4175290b413Stb */
4185290b413Stb
4195290b413Stb static int
bn_mod_sqrt_tonelli_shanks_update(BIGNUM * b,BIGNUM * x,BIGNUM * y,const BIGNUM * p,int m,int r,BN_CTX * ctx)4205290b413Stb bn_mod_sqrt_tonelli_shanks_update(BIGNUM *b, BIGNUM *x, BIGNUM *y,
4215290b413Stb const BIGNUM *p, int m, int r, BN_CTX *ctx)
4225290b413Stb {
4235290b413Stb BIGNUM *t;
4245290b413Stb int ret = 0;
4255290b413Stb
4265290b413Stb BN_CTX_start(ctx);
4275290b413Stb
4285290b413Stb if ((t = BN_CTX_get(ctx)) == NULL)
4295290b413Stb goto err;
4305290b413Stb
4315290b413Stb /* t = y^[2^(r-m-1)] (mod p). */
4325290b413Stb if (!BN_set_bit(t, r - m - 1))
4335290b413Stb goto err;
4345290b413Stb if (!BN_mod_exp_ct(t, y, t, p, ctx))
4355290b413Stb goto err;
4365290b413Stb
4375290b413Stb /* x = xt (mod p). */
4385290b413Stb if (!BN_mod_mul(x, x, t, p, ctx))
4395290b413Stb goto err;
4405290b413Stb
4415290b413Stb /* y = t^2 = y^[2^(r-m)] (mod p). */
4425290b413Stb if (!BN_mod_sqr(y, t, p, ctx))
4435290b413Stb goto err;
4445290b413Stb
4455290b413Stb /* b = by (mod p). */
4465290b413Stb if (!BN_mod_mul(b, b, y, p, ctx))
4475290b413Stb goto err;
4485290b413Stb
4495290b413Stb ret = 1;
4505290b413Stb
4515290b413Stb err:
4525290b413Stb BN_CTX_end(ctx);
4535290b413Stb
4545290b413Stb return ret;
4555290b413Stb }
4565290b413Stb
4575290b413Stb static int
bn_mod_sqrt_p_is_1_mod_8(BIGNUM * out_sqrt,const BIGNUM * a,const BIGNUM * p,BN_CTX * ctx)4585290b413Stb bn_mod_sqrt_p_is_1_mod_8(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p,
4595290b413Stb BN_CTX *ctx)
4605290b413Stb {
4615290b413Stb BIGNUM *b, *q, *x, *y;
4625290b413Stb int e, m, r;
4635290b413Stb int ret = 0;
4645290b413Stb
4655290b413Stb BN_CTX_start(ctx);
4665290b413Stb
4675290b413Stb if ((b = BN_CTX_get(ctx)) == NULL)
4685290b413Stb goto err;
4695290b413Stb if ((q = BN_CTX_get(ctx)) == NULL)
4705290b413Stb goto err;
4715290b413Stb if ((x = BN_CTX_get(ctx)) == NULL)
4725290b413Stb goto err;
4735290b413Stb if ((y = BN_CTX_get(ctx)) == NULL)
4745290b413Stb goto err;
4755290b413Stb
4765290b413Stb /*
4775290b413Stb * Factor p - 1 = 2^e q with odd q. Since p = 1 (mod 8), we know e >= 3.
4785290b413Stb */
4795290b413Stb
4805290b413Stb e = 1;
4815290b413Stb while (!BN_is_bit_set(p, e))
4825290b413Stb e++;
4835290b413Stb if (!BN_rshift(q, p, e))
4845290b413Stb goto err;
4855290b413Stb
4865290b413Stb if (!bn_mod_sqrt_find_sylow_generator(y, p, q, ctx))
4875290b413Stb goto err;
4885290b413Stb
4895290b413Stb /*
4905290b413Stb * Set b = a^q (mod p) and x = a^[(q+1)/2] (mod p).
4915290b413Stb */
4925290b413Stb if (!bn_mod_sqrt_tonelli_shanks_initialize(b, x, a, p, q, ctx))
4935290b413Stb goto err;
4945290b413Stb
4955290b413Stb /*
4965290b413Stb * The Tonelli-Shanks iteration. Starting with r = e, the following loop
4975290b413Stb * invariants hold at the start of the loop.
4985290b413Stb *
4995290b413Stb * a b = x^2 (mod p)
5005290b413Stb * y^[2^(r-1)] = -1 (mod p)
5015290b413Stb * b^[2^(r-1)] = 1 (mod p)
5025290b413Stb *
5035290b413Stb * In particular, if b = 1 (mod p), x is a square root of a.
5045290b413Stb *
5055290b413Stb * Since p - 1 = 2^e q, we have 2^(e-1) q = (p - 1) / 2, so in the first
5065290b413Stb * iteration this follows from (a/p) = 1, (n/p) = -1, y = n^q, b = a^q.
5075290b413Stb *
5085290b413Stb * In subsequent iterations, t = y^[2^(r-m-1)], where m is the smallest
5095290b413Stb * m such that b^(2^m) = 1. With x = xt (mod p) and b = bt^2 (mod p) the
5105290b413Stb * first invariant is preserved, the second and third follow from
5115290b413Stb * y = t^2 (mod p) and r = m as well as the choice of m.
5125290b413Stb *
5135290b413Stb * Finally, r is strictly decreasing in each iteration. If p is prime,
5145290b413Stb * let S be the 2-Sylow subgroup of GF(p)*. We can prove the algorithm
5155290b413Stb * stops: Let S_r be the subgroup of S consisting of elements of order
5165290b413Stb * dividing 2^r. Then S_r = <y> and b is in S_(r-1). The S_r form a
5175290b413Stb * descending filtration of S and when r = 1, then b = 1.
5185290b413Stb */
5195290b413Stb
5205290b413Stb for (r = e; r >= 1; r = m) {
5215290b413Stb /*
5225290b413Stb * Termination condition. If b == 1 then x is a square root.
5235290b413Stb */
5245290b413Stb if (BN_is_one(b))
5255290b413Stb goto done;
5265290b413Stb
5275290b413Stb /* Find smallest exponent 1 <= m < r such that b^(2^m) == 1. */
5285290b413Stb if (!bn_mod_sqrt_tonelli_shanks_find_exponent(&m, b, p, r, ctx))
5295290b413Stb goto err;
5305290b413Stb
5315290b413Stb /*
5325290b413Stb * With t = y^[2^(r-m-1)], update x = xt, y = t^2, b = by.
5335290b413Stb */
5345290b413Stb if (!bn_mod_sqrt_tonelli_shanks_update(b, x, y, p, m, r, ctx))
5355290b413Stb goto err;
5365290b413Stb
5375290b413Stb /*
5385290b413Stb * Sanity check to make sure we don't loop indefinitely.
5395290b413Stb * bn_mod_sqrt_tonelli_shanks_find_exponent() ensures m < r.
5405290b413Stb */
5415290b413Stb if (r <= m)
5425290b413Stb goto err;
5435290b413Stb }
5445290b413Stb
5455290b413Stb /*
5465290b413Stb * If p is prime, we should not get here.
5475290b413Stb */
5485290b413Stb
5495290b413Stb BNerror(BN_R_NOT_A_SQUARE);
5505290b413Stb goto err;
5515290b413Stb
5525290b413Stb done:
5535290b413Stb if (!bn_copy(out_sqrt, x))
5545290b413Stb goto err;
5555290b413Stb
5565290b413Stb ret = 1;
5575290b413Stb
5585290b413Stb err:
5595290b413Stb BN_CTX_end(ctx);
5605290b413Stb
5615290b413Stb return ret;
5625290b413Stb }
5635290b413Stb
5645290b413Stb /*
5655290b413Stb * Choose the smaller of sqrt and |p| - sqrt.
5665290b413Stb */
5675290b413Stb
5685290b413Stb static int
bn_mod_sqrt_normalize(BIGNUM * sqrt,const BIGNUM * p,BN_CTX * ctx)5695290b413Stb bn_mod_sqrt_normalize(BIGNUM *sqrt, const BIGNUM *p, BN_CTX *ctx)
5705290b413Stb {
5715290b413Stb BIGNUM *x;
5725290b413Stb int ret = 0;
5735290b413Stb
5745290b413Stb BN_CTX_start(ctx);
5755290b413Stb
5765290b413Stb if ((x = BN_CTX_get(ctx)) == NULL)
5775290b413Stb goto err;
5785290b413Stb
5795290b413Stb if (!BN_lshift1(x, sqrt))
5805290b413Stb goto err;
5815290b413Stb
5825290b413Stb if (BN_ucmp(x, p) > 0) {
5835290b413Stb if (!BN_usub(sqrt, p, sqrt))
5845290b413Stb goto err;
5855290b413Stb }
5865290b413Stb
5875290b413Stb ret = 1;
5885290b413Stb
5895290b413Stb err:
5905290b413Stb BN_CTX_end(ctx);
5915290b413Stb
5925290b413Stb return ret;
5935290b413Stb }
5945290b413Stb
5955290b413Stb /*
5965290b413Stb * Verify that a = (sqrt_a)^2 (mod p). Requires that a is reduced (mod p).
5975290b413Stb */
5985290b413Stb
5995290b413Stb static int
bn_mod_sqrt_verify(const BIGNUM * a,const BIGNUM * sqrt_a,const BIGNUM * p,BN_CTX * ctx)6005290b413Stb bn_mod_sqrt_verify(const BIGNUM *a, const BIGNUM *sqrt_a, const BIGNUM *p,
6015290b413Stb BN_CTX *ctx)
6025290b413Stb {
6035290b413Stb BIGNUM *x;
6045290b413Stb int ret = 0;
6055290b413Stb
6065290b413Stb BN_CTX_start(ctx);
6075290b413Stb
6085290b413Stb if ((x = BN_CTX_get(ctx)) == NULL)
6095290b413Stb goto err;
6105290b413Stb
6115290b413Stb if (!BN_mod_sqr(x, sqrt_a, p, ctx))
6125290b413Stb goto err;
6135290b413Stb
6145290b413Stb if (BN_cmp(x, a) != 0) {
6155290b413Stb BNerror(BN_R_NOT_A_SQUARE);
6165290b413Stb goto err;
6175290b413Stb }
6185290b413Stb
6195290b413Stb ret = 1;
6205290b413Stb
6215290b413Stb err:
6225290b413Stb BN_CTX_end(ctx);
6235290b413Stb
6245290b413Stb return ret;
6255290b413Stb }
6265290b413Stb
6275290b413Stb static int
bn_mod_sqrt_internal(BIGNUM * out_sqrt,const BIGNUM * a,const BIGNUM * p,BN_CTX * ctx)6285290b413Stb bn_mod_sqrt_internal(BIGNUM *out_sqrt, const BIGNUM *a, const BIGNUM *p,
6295290b413Stb BN_CTX *ctx)
6305290b413Stb {
6315290b413Stb BIGNUM *a_mod_p, *sqrt;
6325290b413Stb BN_ULONG lsw;
6335290b413Stb int done;
6345290b413Stb int kronecker;
6355290b413Stb int ret = 0;
6365290b413Stb
6375290b413Stb BN_CTX_start(ctx);
6385290b413Stb
6395290b413Stb if ((a_mod_p = BN_CTX_get(ctx)) == NULL)
6405290b413Stb goto err;
6415290b413Stb if ((sqrt = BN_CTX_get(ctx)) == NULL)
6425290b413Stb goto err;
6435290b413Stb
6445290b413Stb if (!BN_nnmod(a_mod_p, a, p, ctx))
6455290b413Stb goto err;
6465290b413Stb
6475290b413Stb if (!bn_mod_sqrt_trivial_cases(&done, sqrt, a_mod_p, p, ctx))
6485290b413Stb goto err;
6495290b413Stb if (done)
6505290b413Stb goto verify;
6515290b413Stb
6525290b413Stb /*
6535290b413Stb * Make sure that the Kronecker symbol (a/p) == 1. In case p is prime
6545290b413Stb * this is equivalent to a having a square root (mod p). The cost of
6555290b413Stb * BN_kronecker() is O(log^2(n)). This is small compared to the cost
6565290b413Stb * O(log^4(n)) of Tonelli-Shanks.
6575290b413Stb */
6585290b413Stb
6595290b413Stb if ((kronecker = BN_kronecker(a_mod_p, p, ctx)) == -2)
6605290b413Stb goto err;
6615290b413Stb if (kronecker <= 0) {
6625290b413Stb /* This error is only accurate if p is known to be a prime. */
6635290b413Stb BNerror(BN_R_NOT_A_SQUARE);
6645290b413Stb goto err;
6655290b413Stb }
6665290b413Stb
6675290b413Stb lsw = BN_lsw(p);
6685290b413Stb
6695290b413Stb if (lsw % 4 == 3) {
6705290b413Stb if (!bn_mod_sqrt_p_is_3_mod_4(sqrt, a_mod_p, p, ctx))
6715290b413Stb goto err;
6725290b413Stb } else if (lsw % 8 == 5) {
6735290b413Stb if (!bn_mod_sqrt_p_is_5_mod_8(sqrt, a_mod_p, p, ctx))
6745290b413Stb goto err;
6755290b413Stb } else if (lsw % 8 == 1) {
6765290b413Stb if (!bn_mod_sqrt_p_is_1_mod_8(sqrt, a_mod_p, p, ctx))
6775290b413Stb goto err;
6785290b413Stb } else {
6795290b413Stb /* Impossible to hit since the trivial cases ensure p is odd. */
6805290b413Stb BNerror(BN_R_P_IS_NOT_PRIME);
6815290b413Stb goto err;
6825290b413Stb }
6835290b413Stb
6845290b413Stb if (!bn_mod_sqrt_normalize(sqrt, p, ctx))
6855290b413Stb goto err;
6865290b413Stb
6875290b413Stb verify:
6885290b413Stb if (!bn_mod_sqrt_verify(a_mod_p, sqrt, p, ctx))
6895290b413Stb goto err;
6905290b413Stb
6915290b413Stb if (!bn_copy(out_sqrt, sqrt))
6925290b413Stb goto err;
6935290b413Stb
6945290b413Stb ret = 1;
6955290b413Stb
6965290b413Stb err:
6975290b413Stb BN_CTX_end(ctx);
6985290b413Stb
6995290b413Stb return ret;
7005290b413Stb }
7015290b413Stb
7025290b413Stb BIGNUM *
BN_mod_sqrt(BIGNUM * in,const BIGNUM * a,const BIGNUM * p,BN_CTX * ctx)7035290b413Stb BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
7045290b413Stb {
7055290b413Stb BIGNUM *out_sqrt;
7065290b413Stb
7075290b413Stb if ((out_sqrt = in) == NULL)
7085290b413Stb out_sqrt = BN_new();
7095290b413Stb if (out_sqrt == NULL)
7105290b413Stb goto err;
7115290b413Stb
7125290b413Stb if (!bn_mod_sqrt_internal(out_sqrt, a, p, ctx))
7135290b413Stb goto err;
7145290b413Stb
7155290b413Stb return out_sqrt;
7165290b413Stb
7175290b413Stb err:
7185290b413Stb if (out_sqrt != in)
7195290b413Stb BN_free(out_sqrt);
7205290b413Stb
7215290b413Stb return NULL;
7225290b413Stb }
723ca1d80d6Sbeck LCRYPTO_ALIAS(BN_mod_sqrt);
724