"dragonfly: Unable to get randomness for own scalar");
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;
+}
struct crypto_bignum *_rand,
struct crypto_bignum *_mask,
struct crypto_bignum *scalar);
+int dragonfly_sqrt(struct crypto_ec *ec, const struct crypto_bignum *val,
+ struct crypto_bignum *res);
#endif /* DRAGONFLY_H */
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);
- /* 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 = sqrt(v) */
y = crypto_bignum_init();
- if (!y ||
- crypto_bignum_add(prime, one, t1) < 0 ||
- crypto_bignum_rshift(t1, 2, t1) < 0 ||
- crypto_bignum_exptmod(v, t1, prime, y) < 0)
+ if (!y || dragonfly_sqrt(ec, v, y) < 0)
goto fail;
debug_print_bignum("SSWU: y = sqrt(v)", y, prime_len);