return st;
}
+static int file_modsqr(STANZA *s)
+{
+ BIGNUM *a = NULL, *m = NULL, *mod_sqr = NULL, *ret = NULL;
+ int st = 0;
+
+ if (!TEST_ptr(a = getBN(s, "A"))
+ || !TEST_ptr(m = getBN(s, "M"))
+ || !TEST_ptr(mod_sqr = getBN(s, "ModSqr"))
+ || !TEST_ptr(ret = BN_new()))
+ goto err;
+
+ if (!TEST_true(BN_mod_sqr(ret, a, m, ctx))
+ || !equalBN("A^2 (mod M)", mod_sqr, ret))
+ goto err;
+
+ if (BN_is_odd(m)) {
+ /* Reduce |a| and test the Montgomery version. */
+ BN_MONT_CTX *mont = BN_MONT_CTX_new();
+ BIGNUM *a_tmp = BN_new();
+
+ if (mont == NULL || a_tmp == NULL
+ || !TEST_true(BN_MONT_CTX_set(mont, m, ctx))
+ || !TEST_true(BN_nnmod(a_tmp, a, m, ctx))
+ || !TEST_true(BN_to_montgomery(a_tmp, a_tmp, mont, ctx))
+ || !TEST_true(BN_mod_mul_montgomery(ret, a_tmp, a_tmp,
+ mont, ctx))
+ || !TEST_true(BN_from_montgomery(ret, ret, mont, ctx))
+ || !equalBN("A^2 (mod M) (mont)", mod_sqr, ret))
+ st = 0;
+ else
+ st = 1;
+ BN_MONT_CTX_free(mont);
+ BN_free(a_tmp);
+ if (st == 0)
+ goto err;
+ }
+
+ st = 1;
+err:
+ BN_free(a);
+ BN_free(m);
+ BN_free(mod_sqr);
+ BN_free(ret);
+ return st;
+}
+
static int file_modexp(STANZA *s)
{
BIGNUM *a = NULL, *e = NULL, *m = NULL, *mod_exp = NULL, *ret = NULL;
{ "Product", file_product },
{ "Quotient", file_quotient },
{ "ModMul", file_modmul },
+ { "ModSqr", file_modsqr },
{ "ModExp", file_modexp },
{ "Exp", file_exp },
{ "ModSqrt", file_modsqrt },
B = 8bdfa8fe5ef3b2ad02bc63c4d
M = 84daecf412b8c50ad6dfdb546c3eb783dcc6f32003eda914bb
+# These test vectors satisfy A ^ 2 = ModSqr (mod M) and 0 <= ModSqr < M.
+
+Title = ModSqr tests
+
+# Regression test for https://github.com/openssl/openssl/issues/15587
+ModSqr = 166794ed50cb31b6e6a319f7474416c266d5c3f3115ea2a7ed9638367d1f955f66a7179ee3ce5ee5e04e63c46781f1192beac3abb26ff238f5ed2f5505ae06003ff
+A = 1407833bd4c893195cc32f56a507f15140be687a1994febe0bdbe793125f010a3c1c814737b10ab690498b7990ce4e625ad2f32cbf42626cb9649da38a5c9c76a99
+M = 1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
# These test vectors satisfy A ^ E = ModExp (mod M) and 0 <= ModExp < M.