SAE: Move sqrt() implementation into a helper function
This implementation within SSWU can be helpful for other users of the dragonfly design, so move it into a shared helper function. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
41c7f3f20e
commit
8ebd8aacc2
3 changed files with 38 additions and 12 deletions
|
@ -213,3 +213,37 @@ int dragonfly_generate_scalar(const struct crypto_bignum *order,
|
||||||
"dragonfly: Unable to get randomness for own scalar");
|
"dragonfly: Unable to get randomness for own scalar");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* res = sqrt(val) */
|
||||||
|
int dragonfly_sqrt(struct crypto_ec *ec, const struct crypto_bignum *val,
|
||||||
|
struct crypto_bignum *res)
|
||||||
|
{
|
||||||
|
const struct crypto_bignum *prime;
|
||||||
|
struct crypto_bignum *tmp, *one;
|
||||||
|
int ret = 0;
|
||||||
|
u8 prime_bin[DRAGONFLY_MAX_ECC_PRIME_LEN];
|
||||||
|
size_t prime_len;
|
||||||
|
|
||||||
|
/* For prime p such that p = 3 mod 4, sqrt(w) = w^((p+1)/4) mod p */
|
||||||
|
|
||||||
|
prime = crypto_ec_get_prime(ec);
|
||||||
|
prime_len = crypto_ec_prime_len(ec);
|
||||||
|
tmp = crypto_bignum_init();
|
||||||
|
one = crypto_bignum_init_uint(1);
|
||||||
|
|
||||||
|
if (crypto_bignum_to_bin(prime, prime_bin, sizeof(prime_bin),
|
||||||
|
prime_len) < 0 ||
|
||||||
|
(prime_bin[prime_len - 1] & 0x03) != 3 ||
|
||||||
|
!tmp || !one ||
|
||||||
|
/* tmp = (p+1)/4 */
|
||||||
|
crypto_bignum_add(prime, one, tmp) < 0 ||
|
||||||
|
crypto_bignum_rshift(tmp, 2, tmp) < 0 ||
|
||||||
|
/* res = sqrt(val) */
|
||||||
|
crypto_bignum_exptmod(val, tmp, prime, res) < 0)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
crypto_bignum_deinit(tmp, 0);
|
||||||
|
crypto_bignum_deinit(one, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -27,5 +27,7 @@ int dragonfly_generate_scalar(const struct crypto_bignum *order,
|
||||||
struct crypto_bignum *_rand,
|
struct crypto_bignum *_rand,
|
||||||
struct crypto_bignum *_mask,
|
struct crypto_bignum *_mask,
|
||||||
struct crypto_bignum *scalar);
|
struct crypto_bignum *scalar);
|
||||||
|
int dragonfly_sqrt(struct crypto_ec *ec, const struct crypto_bignum *val,
|
||||||
|
struct crypto_bignum *res);
|
||||||
|
|
||||||
#endif /* DRAGONFLY_H */
|
#endif /* DRAGONFLY_H */
|
||||||
|
|
|
@ -747,19 +747,9 @@ static struct crypto_ec_point * sswu(struct crypto_ec *ec, int group,
|
||||||
const_time_select_bin(is_qr, bin1, bin2, prime_len, x_y);
|
const_time_select_bin(is_qr, bin1, bin2, prime_len, x_y);
|
||||||
wpa_hexdump_key(MSG_DEBUG, "SSWU: x = CSEL(l, x1, x2)", x_y, prime_len);
|
wpa_hexdump_key(MSG_DEBUG, "SSWU: x = CSEL(l, x1, x2)", x_y, prime_len);
|
||||||
|
|
||||||
/* y = sqrt(v)
|
/* y = sqrt(v) */
|
||||||
* For prime p such that p = 3 mod 4 --> v^((p+1)/4) */
|
|
||||||
if (crypto_bignum_to_bin(prime, bin1, sizeof(bin1), prime_len) < 0)
|
|
||||||
goto fail;
|
|
||||||
if ((bin1[prime_len - 1] & 0x03) != 3) {
|
|
||||||
wpa_printf(MSG_DEBUG, "SSWU: prime does not have p = 3 mod 4");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
y = crypto_bignum_init();
|
y = crypto_bignum_init();
|
||||||
if (!y ||
|
if (!y || dragonfly_sqrt(ec, v, y) < 0)
|
||||||
crypto_bignum_add(prime, one, t1) < 0 ||
|
|
||||||
crypto_bignum_rshift(t1, 2, t1) < 0 ||
|
|
||||||
crypto_bignum_exptmod(v, t1, prime, y) < 0)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
debug_print_bignum("SSWU: y = sqrt(v)", y, prime_len);
|
debug_print_bignum("SSWU: y = sqrt(v)", y, prime_len);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue