1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci#include <assert.h>
10e1051a39Sopenharmony_ci#include <errno.h>
11e1051a39Sopenharmony_ci#include <stdio.h>
12e1051a39Sopenharmony_ci#include <string.h>
13e1051a39Sopenharmony_ci#include <ctype.h>
14e1051a39Sopenharmony_ci
15e1051a39Sopenharmony_ci#include <openssl/bn.h>
16e1051a39Sopenharmony_ci#include <openssl/crypto.h>
17e1051a39Sopenharmony_ci#include <openssl/err.h>
18e1051a39Sopenharmony_ci#include <openssl/rand.h>
19e1051a39Sopenharmony_ci#include "internal/nelem.h"
20e1051a39Sopenharmony_ci#include "internal/numbers.h"
21e1051a39Sopenharmony_ci#include "testutil.h"
22e1051a39Sopenharmony_ci
23e1051a39Sopenharmony_ci/*
24e1051a39Sopenharmony_ci * Things in boring, not in openssl.
25e1051a39Sopenharmony_ci */
26e1051a39Sopenharmony_ci#define HAVE_BN_SQRT 0
27e1051a39Sopenharmony_ci
28e1051a39Sopenharmony_citypedef struct filetest_st {
29e1051a39Sopenharmony_ci    const char *name;
30e1051a39Sopenharmony_ci    int (*func)(STANZA *s);
31e1051a39Sopenharmony_ci} FILETEST;
32e1051a39Sopenharmony_ci
33e1051a39Sopenharmony_citypedef struct mpitest_st {
34e1051a39Sopenharmony_ci    const char *base10;
35e1051a39Sopenharmony_ci    const char *mpi;
36e1051a39Sopenharmony_ci    size_t mpi_len;
37e1051a39Sopenharmony_ci} MPITEST;
38e1051a39Sopenharmony_ci
39e1051a39Sopenharmony_cistatic const int NUM0 = 100;           /* number of tests */
40e1051a39Sopenharmony_cistatic const int NUM1 = 50;            /* additional tests for some functions */
41e1051a39Sopenharmony_cistatic BN_CTX *ctx;
42e1051a39Sopenharmony_ci
43e1051a39Sopenharmony_ci/*
44e1051a39Sopenharmony_ci * Polynomial coefficients used in GFM tests.
45e1051a39Sopenharmony_ci */
46e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC2M
47e1051a39Sopenharmony_cistatic int p0[] = { 163, 7, 6, 3, 0, -1 };
48e1051a39Sopenharmony_cistatic int p1[] = { 193, 15, 0, -1 };
49e1051a39Sopenharmony_ci#endif
50e1051a39Sopenharmony_ci
51e1051a39Sopenharmony_ci/*
52e1051a39Sopenharmony_ci * Look for |key| in the stanza and return it or NULL if not found.
53e1051a39Sopenharmony_ci */
54e1051a39Sopenharmony_cistatic const char *findattr(STANZA *s, const char *key)
55e1051a39Sopenharmony_ci{
56e1051a39Sopenharmony_ci    int i = s->numpairs;
57e1051a39Sopenharmony_ci    PAIR *pp = s->pairs;
58e1051a39Sopenharmony_ci
59e1051a39Sopenharmony_ci    for ( ; --i >= 0; pp++)
60e1051a39Sopenharmony_ci        if (OPENSSL_strcasecmp(pp->key, key) == 0)
61e1051a39Sopenharmony_ci            return pp->value;
62e1051a39Sopenharmony_ci    return NULL;
63e1051a39Sopenharmony_ci}
64e1051a39Sopenharmony_ci
65e1051a39Sopenharmony_ci/*
66e1051a39Sopenharmony_ci * Parse BIGNUM from sparse hex-strings, return |BN_hex2bn| result.
67e1051a39Sopenharmony_ci */
68e1051a39Sopenharmony_cistatic int parse_bigBN(BIGNUM **out, const char *bn_strings[])
69e1051a39Sopenharmony_ci{
70e1051a39Sopenharmony_ci    char *bigstring = glue_strings(bn_strings, NULL);
71e1051a39Sopenharmony_ci    int ret = BN_hex2bn(out, bigstring);
72e1051a39Sopenharmony_ci
73e1051a39Sopenharmony_ci    OPENSSL_free(bigstring);
74e1051a39Sopenharmony_ci    return ret;
75e1051a39Sopenharmony_ci}
76e1051a39Sopenharmony_ci
77e1051a39Sopenharmony_ci/*
78e1051a39Sopenharmony_ci * Parse BIGNUM, return number of bytes parsed.
79e1051a39Sopenharmony_ci */
80e1051a39Sopenharmony_cistatic int parseBN(BIGNUM **out, const char *in)
81e1051a39Sopenharmony_ci{
82e1051a39Sopenharmony_ci    *out = NULL;
83e1051a39Sopenharmony_ci    return BN_hex2bn(out, in);
84e1051a39Sopenharmony_ci}
85e1051a39Sopenharmony_ci
86e1051a39Sopenharmony_cistatic int parsedecBN(BIGNUM **out, const char *in)
87e1051a39Sopenharmony_ci{
88e1051a39Sopenharmony_ci    *out = NULL;
89e1051a39Sopenharmony_ci    return BN_dec2bn(out, in);
90e1051a39Sopenharmony_ci}
91e1051a39Sopenharmony_ci
92e1051a39Sopenharmony_cistatic BIGNUM *getBN(STANZA *s, const char *attribute)
93e1051a39Sopenharmony_ci{
94e1051a39Sopenharmony_ci    const char *hex;
95e1051a39Sopenharmony_ci    BIGNUM *ret = NULL;
96e1051a39Sopenharmony_ci
97e1051a39Sopenharmony_ci    if ((hex = findattr(s, attribute)) == NULL) {
98e1051a39Sopenharmony_ci        TEST_error("%s:%d: Can't find %s", s->test_file, s->start, attribute);
99e1051a39Sopenharmony_ci        return NULL;
100e1051a39Sopenharmony_ci    }
101e1051a39Sopenharmony_ci
102e1051a39Sopenharmony_ci    if (parseBN(&ret, hex) != (int)strlen(hex)) {
103e1051a39Sopenharmony_ci        TEST_error("Could not decode '%s'", hex);
104e1051a39Sopenharmony_ci        return NULL;
105e1051a39Sopenharmony_ci    }
106e1051a39Sopenharmony_ci    return ret;
107e1051a39Sopenharmony_ci}
108e1051a39Sopenharmony_ci
109e1051a39Sopenharmony_cistatic int getint(STANZA *s, int *out, const char *attribute)
110e1051a39Sopenharmony_ci{
111e1051a39Sopenharmony_ci    BIGNUM *ret;
112e1051a39Sopenharmony_ci    BN_ULONG word;
113e1051a39Sopenharmony_ci    int st = 0;
114e1051a39Sopenharmony_ci
115e1051a39Sopenharmony_ci    if (!TEST_ptr(ret = getBN(s, attribute))
116e1051a39Sopenharmony_ci            || !TEST_ulong_le(word = BN_get_word(ret), INT_MAX))
117e1051a39Sopenharmony_ci        goto err;
118e1051a39Sopenharmony_ci
119e1051a39Sopenharmony_ci    *out = (int)word;
120e1051a39Sopenharmony_ci    st = 1;
121e1051a39Sopenharmony_ci err:
122e1051a39Sopenharmony_ci    BN_free(ret);
123e1051a39Sopenharmony_ci    return st;
124e1051a39Sopenharmony_ci}
125e1051a39Sopenharmony_ci
126e1051a39Sopenharmony_cistatic int equalBN(const char *op, const BIGNUM *expected, const BIGNUM *actual)
127e1051a39Sopenharmony_ci{
128e1051a39Sopenharmony_ci    if (BN_cmp(expected, actual) == 0)
129e1051a39Sopenharmony_ci        return 1;
130e1051a39Sopenharmony_ci
131e1051a39Sopenharmony_ci    TEST_error("unexpected %s value", op);
132e1051a39Sopenharmony_ci    TEST_BN_eq(expected, actual);
133e1051a39Sopenharmony_ci    return 0;
134e1051a39Sopenharmony_ci}
135e1051a39Sopenharmony_ci
136e1051a39Sopenharmony_ci/*
137e1051a39Sopenharmony_ci * Return a "random" flag for if a BN should be negated.
138e1051a39Sopenharmony_ci */
139e1051a39Sopenharmony_cistatic int rand_neg(void)
140e1051a39Sopenharmony_ci{
141e1051a39Sopenharmony_ci    static unsigned int neg = 0;
142e1051a39Sopenharmony_ci    static int sign[8] = { 0, 0, 0, 1, 1, 0, 1, 1 };
143e1051a39Sopenharmony_ci
144e1051a39Sopenharmony_ci    return sign[(neg++) % 8];
145e1051a39Sopenharmony_ci}
146e1051a39Sopenharmony_ci
147e1051a39Sopenharmony_cistatic int test_swap(void)
148e1051a39Sopenharmony_ci{
149e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL;
150e1051a39Sopenharmony_ci    int top, cond, st = 0;
151e1051a39Sopenharmony_ci
152e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
153e1051a39Sopenharmony_ci            || !TEST_ptr(b = BN_new())
154e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new())
155e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new()))
156e1051a39Sopenharmony_ci        goto err;
157e1051a39Sopenharmony_ci
158e1051a39Sopenharmony_ci    if (!(TEST_true(BN_bntest_rand(a, 1024, 1, 0))
159e1051a39Sopenharmony_ci            && TEST_true(BN_bntest_rand(b, 1024, 1, 0))
160e1051a39Sopenharmony_ci            && TEST_ptr(BN_copy(c, a))
161e1051a39Sopenharmony_ci            && TEST_ptr(BN_copy(d, b))))
162e1051a39Sopenharmony_ci        goto err;
163e1051a39Sopenharmony_ci    top = BN_num_bits(a) / BN_BITS2;
164e1051a39Sopenharmony_ci
165e1051a39Sopenharmony_ci    /* regular swap */
166e1051a39Sopenharmony_ci    BN_swap(a, b);
167e1051a39Sopenharmony_ci    if (!equalBN("swap", a, d)
168e1051a39Sopenharmony_ci            || !equalBN("swap", b, c))
169e1051a39Sopenharmony_ci        goto err;
170e1051a39Sopenharmony_ci
171e1051a39Sopenharmony_ci    /* conditional swap: true */
172e1051a39Sopenharmony_ci    cond = 1;
173e1051a39Sopenharmony_ci    BN_consttime_swap(cond, a, b, top);
174e1051a39Sopenharmony_ci    if (!equalBN("cswap true", a, c)
175e1051a39Sopenharmony_ci            || !equalBN("cswap true", b, d))
176e1051a39Sopenharmony_ci        goto err;
177e1051a39Sopenharmony_ci
178e1051a39Sopenharmony_ci    /* conditional swap: false */
179e1051a39Sopenharmony_ci    cond = 0;
180e1051a39Sopenharmony_ci    BN_consttime_swap(cond, a, b, top);
181e1051a39Sopenharmony_ci    if (!equalBN("cswap false", a, c)
182e1051a39Sopenharmony_ci            || !equalBN("cswap false", b, d))
183e1051a39Sopenharmony_ci        goto err;
184e1051a39Sopenharmony_ci
185e1051a39Sopenharmony_ci    /* same tests but checking flag swap */
186e1051a39Sopenharmony_ci    BN_set_flags(a, BN_FLG_CONSTTIME);
187e1051a39Sopenharmony_ci
188e1051a39Sopenharmony_ci    BN_swap(a, b);
189e1051a39Sopenharmony_ci    if (!equalBN("swap, flags", a, d)
190e1051a39Sopenharmony_ci            || !equalBN("swap, flags", b, c)
191e1051a39Sopenharmony_ci            || !TEST_true(BN_get_flags(b, BN_FLG_CONSTTIME))
192e1051a39Sopenharmony_ci            || !TEST_false(BN_get_flags(a, BN_FLG_CONSTTIME)))
193e1051a39Sopenharmony_ci        goto err;
194e1051a39Sopenharmony_ci
195e1051a39Sopenharmony_ci    cond = 1;
196e1051a39Sopenharmony_ci    BN_consttime_swap(cond, a, b, top);
197e1051a39Sopenharmony_ci    if (!equalBN("cswap true, flags", a, c)
198e1051a39Sopenharmony_ci            || !equalBN("cswap true, flags", b, d)
199e1051a39Sopenharmony_ci            || !TEST_true(BN_get_flags(a, BN_FLG_CONSTTIME))
200e1051a39Sopenharmony_ci            || !TEST_false(BN_get_flags(b, BN_FLG_CONSTTIME)))
201e1051a39Sopenharmony_ci        goto err;
202e1051a39Sopenharmony_ci
203e1051a39Sopenharmony_ci    cond = 0;
204e1051a39Sopenharmony_ci    BN_consttime_swap(cond, a, b, top);
205e1051a39Sopenharmony_ci    if (!equalBN("cswap false, flags", a, c)
206e1051a39Sopenharmony_ci            || !equalBN("cswap false, flags", b, d)
207e1051a39Sopenharmony_ci            || !TEST_true(BN_get_flags(a, BN_FLG_CONSTTIME))
208e1051a39Sopenharmony_ci            || !TEST_false(BN_get_flags(b, BN_FLG_CONSTTIME)))
209e1051a39Sopenharmony_ci        goto err;
210e1051a39Sopenharmony_ci
211e1051a39Sopenharmony_ci    st = 1;
212e1051a39Sopenharmony_ci err:
213e1051a39Sopenharmony_ci    BN_free(a);
214e1051a39Sopenharmony_ci    BN_free(b);
215e1051a39Sopenharmony_ci    BN_free(c);
216e1051a39Sopenharmony_ci    BN_free(d);
217e1051a39Sopenharmony_ci    return st;
218e1051a39Sopenharmony_ci}
219e1051a39Sopenharmony_ci
220e1051a39Sopenharmony_cistatic int test_sub(void)
221e1051a39Sopenharmony_ci{
222e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *c = NULL;
223e1051a39Sopenharmony_ci    int i, st = 0;
224e1051a39Sopenharmony_ci
225e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
226e1051a39Sopenharmony_ci            || !TEST_ptr(b = BN_new())
227e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new()))
228e1051a39Sopenharmony_ci        goto err;
229e1051a39Sopenharmony_ci
230e1051a39Sopenharmony_ci    for (i = 0; i < NUM0 + NUM1; i++) {
231e1051a39Sopenharmony_ci        if (i < NUM1) {
232e1051a39Sopenharmony_ci            if (!(TEST_true(BN_bntest_rand(a, 512, 0, 0)))
233e1051a39Sopenharmony_ci                    && TEST_ptr(BN_copy(b, a))
234e1051a39Sopenharmony_ci                    && TEST_int_ne(BN_set_bit(a, i), 0)
235e1051a39Sopenharmony_ci                    && TEST_true(BN_add_word(b, i)))
236e1051a39Sopenharmony_ci                goto err;
237e1051a39Sopenharmony_ci        } else {
238e1051a39Sopenharmony_ci            if (!TEST_true(BN_bntest_rand(b, 400 + i - NUM1, 0, 0)))
239e1051a39Sopenharmony_ci                goto err;
240e1051a39Sopenharmony_ci            BN_set_negative(a, rand_neg());
241e1051a39Sopenharmony_ci            BN_set_negative(b, rand_neg());
242e1051a39Sopenharmony_ci        }
243e1051a39Sopenharmony_ci        if (!(TEST_true(BN_sub(c, a, b))
244e1051a39Sopenharmony_ci                && TEST_true(BN_add(c, c, b))
245e1051a39Sopenharmony_ci                && TEST_true(BN_sub(c, c, a))
246e1051a39Sopenharmony_ci                && TEST_BN_eq_zero(c)))
247e1051a39Sopenharmony_ci            goto err;
248e1051a39Sopenharmony_ci    }
249e1051a39Sopenharmony_ci    st = 1;
250e1051a39Sopenharmony_ci err:
251e1051a39Sopenharmony_ci    BN_free(a);
252e1051a39Sopenharmony_ci    BN_free(b);
253e1051a39Sopenharmony_ci    BN_free(c);
254e1051a39Sopenharmony_ci    return st;
255e1051a39Sopenharmony_ci}
256e1051a39Sopenharmony_ci
257e1051a39Sopenharmony_cistatic int test_div_recip(void)
258e1051a39Sopenharmony_ci{
259e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
260e1051a39Sopenharmony_ci    BN_RECP_CTX *recp = NULL;
261e1051a39Sopenharmony_ci    int st = 0, i;
262e1051a39Sopenharmony_ci
263e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
264e1051a39Sopenharmony_ci            || !TEST_ptr(b = BN_new())
265e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new())
266e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new())
267e1051a39Sopenharmony_ci            || !TEST_ptr(e = BN_new())
268e1051a39Sopenharmony_ci            || !TEST_ptr(recp = BN_RECP_CTX_new()))
269e1051a39Sopenharmony_ci        goto err;
270e1051a39Sopenharmony_ci
271e1051a39Sopenharmony_ci    for (i = 0; i < NUM0 + NUM1; i++) {
272e1051a39Sopenharmony_ci        if (i < NUM1) {
273e1051a39Sopenharmony_ci            if (!(TEST_true(BN_bntest_rand(a, 400, 0, 0))
274e1051a39Sopenharmony_ci                    && TEST_ptr(BN_copy(b, a))
275e1051a39Sopenharmony_ci                    && TEST_true(BN_lshift(a, a, i))
276e1051a39Sopenharmony_ci                    && TEST_true(BN_add_word(a, i))))
277e1051a39Sopenharmony_ci                goto err;
278e1051a39Sopenharmony_ci        } else {
279e1051a39Sopenharmony_ci            if (!(TEST_true(BN_bntest_rand(b, 50 + 3 * (i - NUM1), 0, 0))))
280e1051a39Sopenharmony_ci                goto err;
281e1051a39Sopenharmony_ci        }
282e1051a39Sopenharmony_ci        BN_set_negative(a, rand_neg());
283e1051a39Sopenharmony_ci        BN_set_negative(b, rand_neg());
284e1051a39Sopenharmony_ci        if (!(TEST_true(BN_RECP_CTX_set(recp, b, ctx))
285e1051a39Sopenharmony_ci                && TEST_true(BN_div_recp(d, c, a, recp, ctx))
286e1051a39Sopenharmony_ci                && TEST_true(BN_mul(e, d, b, ctx))
287e1051a39Sopenharmony_ci                && TEST_true(BN_add(d, e, c))
288e1051a39Sopenharmony_ci                && TEST_true(BN_sub(d, d, a))
289e1051a39Sopenharmony_ci                && TEST_BN_eq_zero(d)))
290e1051a39Sopenharmony_ci            goto err;
291e1051a39Sopenharmony_ci    }
292e1051a39Sopenharmony_ci    st = 1;
293e1051a39Sopenharmony_ci err:
294e1051a39Sopenharmony_ci    BN_free(a);
295e1051a39Sopenharmony_ci    BN_free(b);
296e1051a39Sopenharmony_ci    BN_free(c);
297e1051a39Sopenharmony_ci    BN_free(d);
298e1051a39Sopenharmony_ci    BN_free(e);
299e1051a39Sopenharmony_ci    BN_RECP_CTX_free(recp);
300e1051a39Sopenharmony_ci    return st;
301e1051a39Sopenharmony_ci}
302e1051a39Sopenharmony_ci
303e1051a39Sopenharmony_cistatic struct {
304e1051a39Sopenharmony_ci    int n, divisor, result, remainder;
305e1051a39Sopenharmony_ci} signed_mod_tests[] = {
306e1051a39Sopenharmony_ci    {  10,   3,   3,   1 },
307e1051a39Sopenharmony_ci    { -10,   3,  -3,  -1 },
308e1051a39Sopenharmony_ci    {  10,  -3,  -3,   1 },
309e1051a39Sopenharmony_ci    { -10,  -3,   3,  -1 },
310e1051a39Sopenharmony_ci};
311e1051a39Sopenharmony_ci
312e1051a39Sopenharmony_cistatic BIGNUM *set_signed_bn(int value)
313e1051a39Sopenharmony_ci{
314e1051a39Sopenharmony_ci    BIGNUM *bn = BN_new();
315e1051a39Sopenharmony_ci
316e1051a39Sopenharmony_ci    if (bn == NULL)
317e1051a39Sopenharmony_ci        return NULL;
318e1051a39Sopenharmony_ci    if (!BN_set_word(bn, value < 0 ? -value : value)) {
319e1051a39Sopenharmony_ci        BN_free(bn);
320e1051a39Sopenharmony_ci        return NULL;
321e1051a39Sopenharmony_ci    }
322e1051a39Sopenharmony_ci    BN_set_negative(bn, value < 0);
323e1051a39Sopenharmony_ci    return bn;
324e1051a39Sopenharmony_ci}
325e1051a39Sopenharmony_ci
326e1051a39Sopenharmony_cistatic int test_signed_mod_replace_ab(int n)
327e1051a39Sopenharmony_ci{
328e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL;
329e1051a39Sopenharmony_ci    int st = 0;
330e1051a39Sopenharmony_ci
331e1051a39Sopenharmony_ci    if (!TEST_ptr(a = set_signed_bn(signed_mod_tests[n].n))
332e1051a39Sopenharmony_ci            || !TEST_ptr(b = set_signed_bn(signed_mod_tests[n].divisor))
333e1051a39Sopenharmony_ci            || !TEST_ptr(c = set_signed_bn(signed_mod_tests[n].result))
334e1051a39Sopenharmony_ci            || !TEST_ptr(d = set_signed_bn(signed_mod_tests[n].remainder)))
335e1051a39Sopenharmony_ci        goto err;
336e1051a39Sopenharmony_ci
337e1051a39Sopenharmony_ci    if (TEST_true(BN_div(a, b, a, b, ctx))
338e1051a39Sopenharmony_ci            && TEST_BN_eq(a, c)
339e1051a39Sopenharmony_ci            && TEST_BN_eq(b, d))
340e1051a39Sopenharmony_ci        st = 1;
341e1051a39Sopenharmony_ci err:
342e1051a39Sopenharmony_ci    BN_free(a);
343e1051a39Sopenharmony_ci    BN_free(b);
344e1051a39Sopenharmony_ci    BN_free(c);
345e1051a39Sopenharmony_ci    BN_free(d);
346e1051a39Sopenharmony_ci    return st;
347e1051a39Sopenharmony_ci}
348e1051a39Sopenharmony_ci
349e1051a39Sopenharmony_cistatic int test_signed_mod_replace_ba(int n)
350e1051a39Sopenharmony_ci{
351e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL;
352e1051a39Sopenharmony_ci    int st = 0;
353e1051a39Sopenharmony_ci
354e1051a39Sopenharmony_ci    if (!TEST_ptr(a = set_signed_bn(signed_mod_tests[n].n))
355e1051a39Sopenharmony_ci            || !TEST_ptr(b = set_signed_bn(signed_mod_tests[n].divisor))
356e1051a39Sopenharmony_ci            || !TEST_ptr(c = set_signed_bn(signed_mod_tests[n].result))
357e1051a39Sopenharmony_ci            || !TEST_ptr(d = set_signed_bn(signed_mod_tests[n].remainder)))
358e1051a39Sopenharmony_ci        goto err;
359e1051a39Sopenharmony_ci
360e1051a39Sopenharmony_ci    if (TEST_true(BN_div(b, a, a, b, ctx))
361e1051a39Sopenharmony_ci            && TEST_BN_eq(b, c)
362e1051a39Sopenharmony_ci            && TEST_BN_eq(a, d))
363e1051a39Sopenharmony_ci        st = 1;
364e1051a39Sopenharmony_ci err:
365e1051a39Sopenharmony_ci    BN_free(a);
366e1051a39Sopenharmony_ci    BN_free(b);
367e1051a39Sopenharmony_ci    BN_free(c);
368e1051a39Sopenharmony_ci    BN_free(d);
369e1051a39Sopenharmony_ci    return st;
370e1051a39Sopenharmony_ci}
371e1051a39Sopenharmony_ci
372e1051a39Sopenharmony_cistatic int test_mod(void)
373e1051a39Sopenharmony_ci{
374e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
375e1051a39Sopenharmony_ci    int st = 0, i;
376e1051a39Sopenharmony_ci
377e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
378e1051a39Sopenharmony_ci            || !TEST_ptr(b = BN_new())
379e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new())
380e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new())
381e1051a39Sopenharmony_ci            || !TEST_ptr(e = BN_new()))
382e1051a39Sopenharmony_ci        goto err;
383e1051a39Sopenharmony_ci
384e1051a39Sopenharmony_ci    if (!(TEST_true(BN_bntest_rand(a, 1024, 0, 0))))
385e1051a39Sopenharmony_ci        goto err;
386e1051a39Sopenharmony_ci    for (i = 0; i < NUM0; i++) {
387e1051a39Sopenharmony_ci        if (!(TEST_true(BN_bntest_rand(b, 450 + i * 10, 0, 0))))
388e1051a39Sopenharmony_ci            goto err;
389e1051a39Sopenharmony_ci        BN_set_negative(a, rand_neg());
390e1051a39Sopenharmony_ci        BN_set_negative(b, rand_neg());
391e1051a39Sopenharmony_ci        if (!(TEST_true(BN_mod(c, a, b, ctx))
392e1051a39Sopenharmony_ci                && TEST_true(BN_div(d, e, a, b, ctx))
393e1051a39Sopenharmony_ci                && TEST_BN_eq(e, c)
394e1051a39Sopenharmony_ci                && TEST_true(BN_mul(c, d, b, ctx))
395e1051a39Sopenharmony_ci                && TEST_true(BN_add(d, c, e))
396e1051a39Sopenharmony_ci                && TEST_BN_eq(d, a)))
397e1051a39Sopenharmony_ci            goto err;
398e1051a39Sopenharmony_ci    }
399e1051a39Sopenharmony_ci    st = 1;
400e1051a39Sopenharmony_ci err:
401e1051a39Sopenharmony_ci    BN_free(a);
402e1051a39Sopenharmony_ci    BN_free(b);
403e1051a39Sopenharmony_ci    BN_free(c);
404e1051a39Sopenharmony_ci    BN_free(d);
405e1051a39Sopenharmony_ci    BN_free(e);
406e1051a39Sopenharmony_ci    return st;
407e1051a39Sopenharmony_ci}
408e1051a39Sopenharmony_ci
409e1051a39Sopenharmony_cistatic const char *bn1strings[] = {
410e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
411e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
412e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
413e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
414e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
415e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
416e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
417e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFF00",
418e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
419e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
420e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
421e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
422e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
423e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
424e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
425e1051a39Sopenharmony_ci    "00000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF",
426e1051a39Sopenharmony_ci    NULL
427e1051a39Sopenharmony_ci};
428e1051a39Sopenharmony_ci
429e1051a39Sopenharmony_cistatic const char *bn2strings[] = {
430e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
431e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
432e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
433e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
434e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
435e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
436e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
437e1051a39Sopenharmony_ci    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFF0000000000",
438e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
439e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
440e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
441e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
442e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
443e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
444e1051a39Sopenharmony_ci    "0000000000000000000000000000000000000000000000000000000000000000",
445e1051a39Sopenharmony_ci    "000000000000000000000000000000000000000000FFFFFFFFFFFFFF00000000",
446e1051a39Sopenharmony_ci    NULL
447e1051a39Sopenharmony_ci};
448e1051a39Sopenharmony_ci
449e1051a39Sopenharmony_ci/*
450e1051a39Sopenharmony_ci * Test constant-time modular exponentiation with 1024-bit inputs, which on
451e1051a39Sopenharmony_ci * x86_64 cause a different code branch to be taken.
452e1051a39Sopenharmony_ci */
453e1051a39Sopenharmony_cistatic int test_modexp_mont5(void)
454e1051a39Sopenharmony_ci{
455e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *p = NULL, *m = NULL, *d = NULL, *e = NULL;
456e1051a39Sopenharmony_ci    BIGNUM *b = NULL, *n = NULL, *c = NULL;
457e1051a39Sopenharmony_ci    BN_MONT_CTX *mont = NULL;
458e1051a39Sopenharmony_ci    int st = 0;
459e1051a39Sopenharmony_ci
460e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
461e1051a39Sopenharmony_ci            || !TEST_ptr(p = BN_new())
462e1051a39Sopenharmony_ci            || !TEST_ptr(m = BN_new())
463e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new())
464e1051a39Sopenharmony_ci            || !TEST_ptr(e = BN_new())
465e1051a39Sopenharmony_ci            || !TEST_ptr(b = BN_new())
466e1051a39Sopenharmony_ci            || !TEST_ptr(n = BN_new())
467e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new())
468e1051a39Sopenharmony_ci            || !TEST_ptr(mont = BN_MONT_CTX_new()))
469e1051a39Sopenharmony_ci        goto err;
470e1051a39Sopenharmony_ci
471e1051a39Sopenharmony_ci    /* must be odd for montgomery */
472e1051a39Sopenharmony_ci    if (!(TEST_true(BN_bntest_rand(m, 1024, 0, 1))
473e1051a39Sopenharmony_ci            /* Zero exponent */
474e1051a39Sopenharmony_ci            && TEST_true(BN_bntest_rand(a, 1024, 0, 0))))
475e1051a39Sopenharmony_ci        goto err;
476e1051a39Sopenharmony_ci    BN_zero(p);
477e1051a39Sopenharmony_ci
478e1051a39Sopenharmony_ci    if (!TEST_true(BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)))
479e1051a39Sopenharmony_ci        goto err;
480e1051a39Sopenharmony_ci    if (!TEST_BN_eq_one(d))
481e1051a39Sopenharmony_ci        goto err;
482e1051a39Sopenharmony_ci
483e1051a39Sopenharmony_ci    /* Regression test for carry bug in mulx4x_mont */
484e1051a39Sopenharmony_ci    if (!(TEST_true(BN_hex2bn(&a,
485e1051a39Sopenharmony_ci        "7878787878787878787878787878787878787878787878787878787878787878"
486e1051a39Sopenharmony_ci        "7878787878787878787878787878787878787878787878787878787878787878"
487e1051a39Sopenharmony_ci        "7878787878787878787878787878787878787878787878787878787878787878"
488e1051a39Sopenharmony_ci        "7878787878787878787878787878787878787878787878787878787878787878"))
489e1051a39Sopenharmony_ci        && TEST_true(BN_hex2bn(&b,
490e1051a39Sopenharmony_ci        "095D72C08C097BA488C5E439C655A192EAFB6380073D8C2664668EDDB4060744"
491e1051a39Sopenharmony_ci        "E16E57FB4EDB9AE10A0CEFCDC28A894F689A128379DB279D48A2E20849D68593"
492e1051a39Sopenharmony_ci        "9B7803BCF46CEBF5C533FB0DD35B080593DE5472E3FE5DB951B8BFF9B4CB8F03"
493e1051a39Sopenharmony_ci        "9CC638A5EE8CDD703719F8000E6A9F63BEED5F2FCD52FF293EA05A251BB4AB81"))
494e1051a39Sopenharmony_ci        && TEST_true(BN_hex2bn(&n,
495e1051a39Sopenharmony_ci        "D78AF684E71DB0C39CFF4E64FB9DB567132CB9C50CC98009FEB820B26F2DED9B"
496e1051a39Sopenharmony_ci        "91B9B5E2B83AE0AE4EB4E0523CA726BFBE969B89FD754F674CE99118C3F2D1C5"
497e1051a39Sopenharmony_ci        "D81FDC7C54E02B60262B241D53C040E99E45826ECA37A804668E690E1AFC1CA4"
498e1051a39Sopenharmony_ci        "2C9A15D84D4954425F0B7642FC0BD9D7B24E2618D2DCC9B729D944BADACFDDAF"))))
499e1051a39Sopenharmony_ci        goto err;
500e1051a39Sopenharmony_ci
501e1051a39Sopenharmony_ci    if (!(TEST_true(BN_MONT_CTX_set(mont, n, ctx))
502e1051a39Sopenharmony_ci            && TEST_true(BN_mod_mul_montgomery(c, a, b, mont, ctx))
503e1051a39Sopenharmony_ci            && TEST_true(BN_mod_mul_montgomery(d, b, a, mont, ctx))
504e1051a39Sopenharmony_ci            && TEST_BN_eq(c, d)))
505e1051a39Sopenharmony_ci        goto err;
506e1051a39Sopenharmony_ci
507e1051a39Sopenharmony_ci    /* Regression test for carry bug in sqr[x]8x_mont */
508e1051a39Sopenharmony_ci    if (!(TEST_true(parse_bigBN(&n, bn1strings))
509e1051a39Sopenharmony_ci            && TEST_true(parse_bigBN(&a, bn2strings))))
510e1051a39Sopenharmony_ci        goto err;
511e1051a39Sopenharmony_ci    BN_free(b);
512e1051a39Sopenharmony_ci    if (!(TEST_ptr(b = BN_dup(a))
513e1051a39Sopenharmony_ci            && TEST_true(BN_MONT_CTX_set(mont, n, ctx))
514e1051a39Sopenharmony_ci            && TEST_true(BN_mod_mul_montgomery(c, a, a, mont, ctx))
515e1051a39Sopenharmony_ci            && TEST_true(BN_mod_mul_montgomery(d, a, b, mont, ctx))
516e1051a39Sopenharmony_ci            && TEST_BN_eq(c, d)))
517e1051a39Sopenharmony_ci        goto err;
518e1051a39Sopenharmony_ci
519e1051a39Sopenharmony_ci    /* Regression test for carry bug in bn_sqrx8x_internal */
520e1051a39Sopenharmony_ci    {
521e1051a39Sopenharmony_ci        static const char *ahex[] = {
522e1051a39Sopenharmony_ci                      "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
523e1051a39Sopenharmony_ci            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
524e1051a39Sopenharmony_ci            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
525e1051a39Sopenharmony_ci            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
526e1051a39Sopenharmony_ci            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8FFEADBCFC4DAE7FFF908E92820306B",
527e1051a39Sopenharmony_ci            "9544D954000000006C0000000000000000000000000000000000000000000000",
528e1051a39Sopenharmony_ci            "00000000000000000000FF030202FFFFF8FFEBDBCFC4DAE7FFF908E92820306B",
529e1051a39Sopenharmony_ci            "9544D954000000006C000000FF0302030000000000FFFFFFFFFFFFFFFFFFFFFF",
530e1051a39Sopenharmony_ci            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01FC00FF02FFFFFFFF",
531e1051a39Sopenharmony_ci            "00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FCFD",
532e1051a39Sopenharmony_ci            "FCFFFFFFFFFF000000000000000000FF0302030000000000FFFFFFFFFFFFFFFF",
533e1051a39Sopenharmony_ci            "FF00FCFDFDFF030202FF00000000FFFFFFFFFFFFFFFFFF00FCFDFCFFFFFFFFFF",
534e1051a39Sopenharmony_ci            NULL
535e1051a39Sopenharmony_ci        };
536e1051a39Sopenharmony_ci        static const char *nhex[] = {
537e1051a39Sopenharmony_ci                      "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
538e1051a39Sopenharmony_ci            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
539e1051a39Sopenharmony_ci            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
540e1051a39Sopenharmony_ci            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
541e1051a39Sopenharmony_ci            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8F8000000",
542e1051a39Sopenharmony_ci            "00000010000000006C0000000000000000000000000000000000000000000000",
543e1051a39Sopenharmony_ci            "00000000000000000000000000000000000000FFFFFFFFFFFFF8F8F8F8000000",
544e1051a39Sopenharmony_ci            "00000010000000006C000000000000000000000000FFFFFFFFFFFFFFFFFFFFFF",
545e1051a39Sopenharmony_ci            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
546e1051a39Sopenharmony_ci            "00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
547e1051a39Sopenharmony_ci            "FFFFFFFFFFFF000000000000000000000000000000000000FFFFFFFFFFFFFFFF",
548e1051a39Sopenharmony_ci            "FFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
549e1051a39Sopenharmony_ci            NULL
550e1051a39Sopenharmony_ci        };
551e1051a39Sopenharmony_ci
552e1051a39Sopenharmony_ci        if (!(TEST_true(parse_bigBN(&a, ahex))
553e1051a39Sopenharmony_ci                && TEST_true(parse_bigBN(&n, nhex))))
554e1051a39Sopenharmony_ci            goto err;
555e1051a39Sopenharmony_ci    }
556e1051a39Sopenharmony_ci    BN_free(b);
557e1051a39Sopenharmony_ci    if (!(TEST_ptr(b = BN_dup(a))
558e1051a39Sopenharmony_ci            && TEST_true(BN_MONT_CTX_set(mont, n, ctx))))
559e1051a39Sopenharmony_ci        goto err;
560e1051a39Sopenharmony_ci
561e1051a39Sopenharmony_ci    if (!TEST_true(BN_mod_mul_montgomery(c, a, a, mont, ctx))
562e1051a39Sopenharmony_ci            || !TEST_true(BN_mod_mul_montgomery(d, a, b, mont, ctx))
563e1051a39Sopenharmony_ci            || !TEST_BN_eq(c, d))
564e1051a39Sopenharmony_ci        goto err;
565e1051a39Sopenharmony_ci
566e1051a39Sopenharmony_ci    /* Regression test for bug in BN_from_montgomery_word */
567e1051a39Sopenharmony_ci    if (!(TEST_true(BN_hex2bn(&a,
568e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
569e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
570e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
571e1051a39Sopenharmony_ci         && TEST_true(BN_hex2bn(&n,
572e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
573e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
574e1051a39Sopenharmony_ci        && TEST_true(BN_MONT_CTX_set(mont, n, ctx))
575e1051a39Sopenharmony_ci        && TEST_false(BN_mod_mul_montgomery(d, a, a, mont, ctx))))
576e1051a39Sopenharmony_ci        goto err;
577e1051a39Sopenharmony_ci
578e1051a39Sopenharmony_ci    /* Regression test for bug in rsaz_1024_mul_avx2 */
579e1051a39Sopenharmony_ci    if (!(TEST_true(BN_hex2bn(&a,
580e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
581e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
582e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
583e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2020202020DF"))
584e1051a39Sopenharmony_ci        && TEST_true(BN_hex2bn(&b,
585e1051a39Sopenharmony_ci        "2020202020202020202020202020202020202020202020202020202020202020"
586e1051a39Sopenharmony_ci        "2020202020202020202020202020202020202020202020202020202020202020"
587e1051a39Sopenharmony_ci        "20202020202020FF202020202020202020202020202020202020202020202020"
588e1051a39Sopenharmony_ci        "2020202020202020202020202020202020202020202020202020202020202020"))
589e1051a39Sopenharmony_ci        && TEST_true(BN_hex2bn(&n,
590e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
591e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
592e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
593e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2020202020FF"))
594e1051a39Sopenharmony_ci        && TEST_true(BN_MONT_CTX_set(mont, n, ctx))
595e1051a39Sopenharmony_ci        && TEST_true(BN_mod_exp_mont_consttime(c, a, b, n, ctx, mont))
596e1051a39Sopenharmony_ci        && TEST_true(BN_mod_exp_mont(d, a, b, n, ctx, mont))
597e1051a39Sopenharmony_ci        && TEST_BN_eq(c, d)))
598e1051a39Sopenharmony_ci        goto err;
599e1051a39Sopenharmony_ci
600e1051a39Sopenharmony_ci    /*
601e1051a39Sopenharmony_ci     * rsaz_1024_mul_avx2 expects fully-reduced inputs.
602e1051a39Sopenharmony_ci     * BN_mod_exp_mont_consttime should reduce the input first.
603e1051a39Sopenharmony_ci     */
604e1051a39Sopenharmony_ci    if (!(TEST_true(BN_hex2bn(&a,
605e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
606e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
607e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
608e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2020202020DF"))
609e1051a39Sopenharmony_ci        && TEST_true(BN_hex2bn(&b,
610e1051a39Sopenharmony_ci        "1FA53F26F8811C58BE0357897AA5E165693230BC9DF5F01DFA6A2D59229EC69D"
611e1051a39Sopenharmony_ci        "9DE6A89C36E3B6957B22D6FAAD5A3C73AE587B710DBE92E83D3A9A3339A085CB"
612e1051a39Sopenharmony_ci        "B58F508CA4F837924BB52CC1698B7FDC2FD74362456A595A5B58E38E38E38E38"
613e1051a39Sopenharmony_ci        "E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E38E"))
614e1051a39Sopenharmony_ci        && TEST_true(BN_hex2bn(&n,
615e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
616e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
617e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
618e1051a39Sopenharmony_ci        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2020202020DF"))
619e1051a39Sopenharmony_ci        && TEST_true(BN_MONT_CTX_set(mont, n, ctx))
620e1051a39Sopenharmony_ci        && TEST_true(BN_mod_exp_mont_consttime(c, a, b, n, ctx, mont))))
621e1051a39Sopenharmony_ci        goto err;
622e1051a39Sopenharmony_ci    BN_zero(d);
623e1051a39Sopenharmony_ci    if (!TEST_BN_eq(c, d))
624e1051a39Sopenharmony_ci        goto err;
625e1051a39Sopenharmony_ci
626e1051a39Sopenharmony_ci    /*
627e1051a39Sopenharmony_ci     * Regression test for overflow bug in bn_sqr_comba4/8 for
628e1051a39Sopenharmony_ci     * mips-linux-gnu and mipsel-linux-gnu 32bit targets.
629e1051a39Sopenharmony_ci     */
630e1051a39Sopenharmony_ci    {
631e1051a39Sopenharmony_ci        static const char *ehex[] = {
632e1051a39Sopenharmony_ci            "95564994a96c45954227b845a1e99cb939d5a1da99ee91acc962396ae999a9ee",
633e1051a39Sopenharmony_ci            "38603790448f2f7694c242a875f0cad0aae658eba085f312d2febbbd128dd2b5",
634e1051a39Sopenharmony_ci            "8f7d1149f03724215d704344d0d62c587ae3c5939cba4b9b5f3dc5e8e911ef9a",
635e1051a39Sopenharmony_ci            "5ce1a5a749a4989d0d8368f6e1f8cdf3a362a6c97fb02047ff152b480a4ad985",
636e1051a39Sopenharmony_ci            "2d45efdf0770542992afca6a0590d52930434bba96017afbc9f99e112950a8b1",
637e1051a39Sopenharmony_ci            "a359473ec376f329bdae6a19f503be6d4be7393c4e43468831234e27e3838680",
638e1051a39Sopenharmony_ci            "b949390d2e416a3f9759e5349ab4c253f6f29f819a6fe4cbfd27ada34903300e",
639e1051a39Sopenharmony_ci            "da021f62839f5878a36f1bc3085375b00fd5fa3e68d316c0fdace87a97558465",
640e1051a39Sopenharmony_ci            NULL};
641e1051a39Sopenharmony_ci        static const char *phex[] = {
642e1051a39Sopenharmony_ci            "f95dc0f980fbd22e90caa5a387cc4a369f3f830d50dd321c40db8c09a7e1a241",
643e1051a39Sopenharmony_ci            "a536e096622d3280c0c1ba849c1f4a79bf490f60006d081e8cf69960189f0d31",
644e1051a39Sopenharmony_ci            "2cd9e17073a3fba7881b21474a13b334116cb2f5dbf3189a6de3515d0840f053",
645e1051a39Sopenharmony_ci            "c776d3982d391b6d04d642dda5cc6d1640174c09875addb70595658f89efb439",
646e1051a39Sopenharmony_ci            "dc6fbd55f903aadd307982d3f659207f265e1ec6271b274521b7a5e28e8fd7a5",
647e1051a39Sopenharmony_ci            "5df089292820477802a43cf5b6b94e999e8c9944ddebb0d0e95a60f88cb7e813",
648e1051a39Sopenharmony_ci            "ba110d20e1024774107dd02949031864923b3cb8c3f7250d6d1287b0a40db6a4",
649e1051a39Sopenharmony_ci            "7bd5a469518eb65aa207ddc47d8c6e5fc8e0c105be8fc1d4b57b2e27540471d5",
650e1051a39Sopenharmony_ci            NULL};
651e1051a39Sopenharmony_ci        static const char *mhex[] = {
652e1051a39Sopenharmony_ci            "fef15d5ce4625f1bccfbba49fc8439c72bf8202af039a2259678941b60bb4a8f",
653e1051a39Sopenharmony_ci            "2987e965d58fd8cf86a856674d519763d0e1211cc9f8596971050d56d9b35db3",
654e1051a39Sopenharmony_ci            "785866cfbca17cfdbed6060be3629d894f924a89fdc1efc624f80d41a22f1900",
655e1051a39Sopenharmony_ci            "9503fcc3824ef62ccb9208430c26f2d8ceb2c63488ec4c07437aa4c96c43dd8b",
656e1051a39Sopenharmony_ci            "9289ed00a712ff66ee195dc71f5e4ead02172b63c543d69baf495f5fd63ba7bc",
657e1051a39Sopenharmony_ci            "c633bd309c016e37736da92129d0b053d4ab28d21ad7d8b6fab2a8bbdc8ee647",
658e1051a39Sopenharmony_ci            "d2fbcf2cf426cf892e6f5639e0252993965dfb73ccd277407014ea784aaa280c",
659e1051a39Sopenharmony_ci            "b7b03972bc8b0baa72360bdb44b82415b86b2f260f877791cd33ba8f2d65229b",
660e1051a39Sopenharmony_ci            NULL};
661e1051a39Sopenharmony_ci
662e1051a39Sopenharmony_ci        if (!TEST_true(parse_bigBN(&e, ehex))
663e1051a39Sopenharmony_ci                || !TEST_true(parse_bigBN(&p, phex))
664e1051a39Sopenharmony_ci                || !TEST_true(parse_bigBN(&m, mhex))
665e1051a39Sopenharmony_ci                || !TEST_true(BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL))
666e1051a39Sopenharmony_ci                || !TEST_true(BN_mod_exp_simple(a, e, p, m, ctx))
667e1051a39Sopenharmony_ci                || !TEST_BN_eq(a, d))
668e1051a39Sopenharmony_ci            goto err;
669e1051a39Sopenharmony_ci    }
670e1051a39Sopenharmony_ci
671e1051a39Sopenharmony_ci    /* Zero input */
672e1051a39Sopenharmony_ci    if (!TEST_true(BN_bntest_rand(p, 1024, 0, 0)))
673e1051a39Sopenharmony_ci        goto err;
674e1051a39Sopenharmony_ci    BN_zero(a);
675e1051a39Sopenharmony_ci    if (!TEST_true(BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL))
676e1051a39Sopenharmony_ci            || !TEST_BN_eq_zero(d))
677e1051a39Sopenharmony_ci        goto err;
678e1051a39Sopenharmony_ci
679e1051a39Sopenharmony_ci    /*
680e1051a39Sopenharmony_ci     * Craft an input whose Montgomery representation is 1, i.e., shorter
681e1051a39Sopenharmony_ci     * than the modulus m, in order to test the const time precomputation
682e1051a39Sopenharmony_ci     * scattering/gathering.
683e1051a39Sopenharmony_ci     */
684e1051a39Sopenharmony_ci    if (!(TEST_true(BN_one(a))
685e1051a39Sopenharmony_ci            && TEST_true(BN_MONT_CTX_set(mont, m, ctx))))
686e1051a39Sopenharmony_ci        goto err;
687e1051a39Sopenharmony_ci    if (!TEST_true(BN_from_montgomery(e, a, mont, ctx))
688e1051a39Sopenharmony_ci            || !TEST_true(BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL))
689e1051a39Sopenharmony_ci            || !TEST_true(BN_mod_exp_simple(a, e, p, m, ctx))
690e1051a39Sopenharmony_ci            || !TEST_BN_eq(a, d))
691e1051a39Sopenharmony_ci        goto err;
692e1051a39Sopenharmony_ci
693e1051a39Sopenharmony_ci    /* Finally, some regular test vectors. */
694e1051a39Sopenharmony_ci    if (!(TEST_true(BN_bntest_rand(e, 1024, 0, 0))
695e1051a39Sopenharmony_ci            && TEST_true(BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL))
696e1051a39Sopenharmony_ci            && TEST_true(BN_mod_exp_simple(a, e, p, m, ctx))
697e1051a39Sopenharmony_ci            && TEST_BN_eq(a, d)))
698e1051a39Sopenharmony_ci        goto err;
699e1051a39Sopenharmony_ci
700e1051a39Sopenharmony_ci    st = 1;
701e1051a39Sopenharmony_ci
702e1051a39Sopenharmony_ci err:
703e1051a39Sopenharmony_ci    BN_MONT_CTX_free(mont);
704e1051a39Sopenharmony_ci    BN_free(a);
705e1051a39Sopenharmony_ci    BN_free(p);
706e1051a39Sopenharmony_ci    BN_free(m);
707e1051a39Sopenharmony_ci    BN_free(d);
708e1051a39Sopenharmony_ci    BN_free(e);
709e1051a39Sopenharmony_ci    BN_free(b);
710e1051a39Sopenharmony_ci    BN_free(n);
711e1051a39Sopenharmony_ci    BN_free(c);
712e1051a39Sopenharmony_ci    return st;
713e1051a39Sopenharmony_ci}
714e1051a39Sopenharmony_ci
715e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC2M
716e1051a39Sopenharmony_cistatic int test_gf2m_add(void)
717e1051a39Sopenharmony_ci{
718e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *c = NULL;
719e1051a39Sopenharmony_ci    int i, st = 0;
720e1051a39Sopenharmony_ci
721e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
722e1051a39Sopenharmony_ci            || !TEST_ptr(b = BN_new())
723e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new()))
724e1051a39Sopenharmony_ci        goto err;
725e1051a39Sopenharmony_ci
726e1051a39Sopenharmony_ci    for (i = 0; i < NUM0; i++) {
727e1051a39Sopenharmony_ci        if (!(TEST_true(BN_rand(a, 512, 0, 0))
728e1051a39Sopenharmony_ci                && TEST_ptr(BN_copy(b, BN_value_one()))))
729e1051a39Sopenharmony_ci            goto err;
730e1051a39Sopenharmony_ci        BN_set_negative(a, rand_neg());
731e1051a39Sopenharmony_ci        BN_set_negative(b, rand_neg());
732e1051a39Sopenharmony_ci        if (!(TEST_true(BN_GF2m_add(c, a, b))
733e1051a39Sopenharmony_ci                /* Test that two added values have the correct parity. */
734e1051a39Sopenharmony_ci                && TEST_false((BN_is_odd(a) && BN_is_odd(c))
735e1051a39Sopenharmony_ci                        || (!BN_is_odd(a) && !BN_is_odd(c)))))
736e1051a39Sopenharmony_ci            goto err;
737e1051a39Sopenharmony_ci        if (!(TEST_true(BN_GF2m_add(c, c, c))
738e1051a39Sopenharmony_ci                /* Test that c + c = 0. */
739e1051a39Sopenharmony_ci                && TEST_BN_eq_zero(c)))
740e1051a39Sopenharmony_ci            goto err;
741e1051a39Sopenharmony_ci    }
742e1051a39Sopenharmony_ci    st = 1;
743e1051a39Sopenharmony_ci err:
744e1051a39Sopenharmony_ci    BN_free(a);
745e1051a39Sopenharmony_ci    BN_free(b);
746e1051a39Sopenharmony_ci    BN_free(c);
747e1051a39Sopenharmony_ci    return st;
748e1051a39Sopenharmony_ci}
749e1051a39Sopenharmony_ci
750e1051a39Sopenharmony_cistatic int test_gf2m_mod(void)
751e1051a39Sopenharmony_ci{
752e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL, *e = NULL;
753e1051a39Sopenharmony_ci    int i, j, st = 0;
754e1051a39Sopenharmony_ci
755e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
756e1051a39Sopenharmony_ci            || !TEST_ptr(b[0] = BN_new())
757e1051a39Sopenharmony_ci            || !TEST_ptr(b[1] = BN_new())
758e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new())
759e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new())
760e1051a39Sopenharmony_ci            || !TEST_ptr(e = BN_new()))
761e1051a39Sopenharmony_ci        goto err;
762e1051a39Sopenharmony_ci
763e1051a39Sopenharmony_ci    if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0]))
764e1051a39Sopenharmony_ci            && TEST_true(BN_GF2m_arr2poly(p1, b[1]))))
765e1051a39Sopenharmony_ci        goto err;
766e1051a39Sopenharmony_ci
767e1051a39Sopenharmony_ci    for (i = 0; i < NUM0; i++) {
768e1051a39Sopenharmony_ci        if (!TEST_true(BN_bntest_rand(a, 1024, 0, 0)))
769e1051a39Sopenharmony_ci            goto err;
770e1051a39Sopenharmony_ci        for (j = 0; j < 2; j++) {
771e1051a39Sopenharmony_ci            if (!(TEST_true(BN_GF2m_mod(c, a, b[j]))
772e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_add(d, a, c))
773e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_mod(e, d, b[j]))
774e1051a39Sopenharmony_ci                    /* Test that a + (a mod p) mod p == 0. */
775e1051a39Sopenharmony_ci                    && TEST_BN_eq_zero(e)))
776e1051a39Sopenharmony_ci                goto err;
777e1051a39Sopenharmony_ci        }
778e1051a39Sopenharmony_ci    }
779e1051a39Sopenharmony_ci    st = 1;
780e1051a39Sopenharmony_ci err:
781e1051a39Sopenharmony_ci    BN_free(a);
782e1051a39Sopenharmony_ci    BN_free(b[0]);
783e1051a39Sopenharmony_ci    BN_free(b[1]);
784e1051a39Sopenharmony_ci    BN_free(c);
785e1051a39Sopenharmony_ci    BN_free(d);
786e1051a39Sopenharmony_ci    BN_free(e);
787e1051a39Sopenharmony_ci    return st;
788e1051a39Sopenharmony_ci}
789e1051a39Sopenharmony_ci
790e1051a39Sopenharmony_cistatic int test_gf2m_mul(void)
791e1051a39Sopenharmony_ci{
792e1051a39Sopenharmony_ci    BIGNUM *a, *b[2] = {NULL, NULL}, *c = NULL, *d = NULL;
793e1051a39Sopenharmony_ci    BIGNUM *e = NULL, *f = NULL, *g = NULL, *h = NULL;
794e1051a39Sopenharmony_ci    int i, j, st = 0;
795e1051a39Sopenharmony_ci
796e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
797e1051a39Sopenharmony_ci            || !TEST_ptr(b[0] = BN_new())
798e1051a39Sopenharmony_ci            || !TEST_ptr(b[1] = BN_new())
799e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new())
800e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new())
801e1051a39Sopenharmony_ci            || !TEST_ptr(e = BN_new())
802e1051a39Sopenharmony_ci            || !TEST_ptr(f = BN_new())
803e1051a39Sopenharmony_ci            || !TEST_ptr(g = BN_new())
804e1051a39Sopenharmony_ci            || !TEST_ptr(h = BN_new()))
805e1051a39Sopenharmony_ci        goto err;
806e1051a39Sopenharmony_ci
807e1051a39Sopenharmony_ci    if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0]))
808e1051a39Sopenharmony_ci            && TEST_true(BN_GF2m_arr2poly(p1, b[1]))))
809e1051a39Sopenharmony_ci        goto err;
810e1051a39Sopenharmony_ci
811e1051a39Sopenharmony_ci    for (i = 0; i < NUM0; i++) {
812e1051a39Sopenharmony_ci        if (!(TEST_true(BN_bntest_rand(a, 1024, 0, 0))
813e1051a39Sopenharmony_ci                && TEST_true(BN_bntest_rand(c, 1024, 0, 0))
814e1051a39Sopenharmony_ci                && TEST_true(BN_bntest_rand(d, 1024, 0, 0))))
815e1051a39Sopenharmony_ci            goto err;
816e1051a39Sopenharmony_ci        for (j = 0; j < 2; j++) {
817e1051a39Sopenharmony_ci            if (!(TEST_true(BN_GF2m_mod_mul(e, a, c, b[j], ctx))
818e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_add(f, a, d))
819e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_mod_mul(g, f, c, b[j], ctx))
820e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_mod_mul(h, d, c, b[j], ctx))
821e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_add(f, e, g))
822e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_add(f, f, h))
823e1051a39Sopenharmony_ci                    /* Test that (a+d)*c = a*c + d*c. */
824e1051a39Sopenharmony_ci                    && TEST_BN_eq_zero(f)))
825e1051a39Sopenharmony_ci                goto err;
826e1051a39Sopenharmony_ci        }
827e1051a39Sopenharmony_ci    }
828e1051a39Sopenharmony_ci    st = 1;
829e1051a39Sopenharmony_ci
830e1051a39Sopenharmony_ci err:
831e1051a39Sopenharmony_ci    BN_free(a);
832e1051a39Sopenharmony_ci    BN_free(b[0]);
833e1051a39Sopenharmony_ci    BN_free(b[1]);
834e1051a39Sopenharmony_ci    BN_free(c);
835e1051a39Sopenharmony_ci    BN_free(d);
836e1051a39Sopenharmony_ci    BN_free(e);
837e1051a39Sopenharmony_ci    BN_free(f);
838e1051a39Sopenharmony_ci    BN_free(g);
839e1051a39Sopenharmony_ci    BN_free(h);
840e1051a39Sopenharmony_ci    return st;
841e1051a39Sopenharmony_ci}
842e1051a39Sopenharmony_ci
843e1051a39Sopenharmony_cistatic int test_gf2m_sqr(void)
844e1051a39Sopenharmony_ci{
845e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL;
846e1051a39Sopenharmony_ci    int i, j, st = 0;
847e1051a39Sopenharmony_ci
848e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
849e1051a39Sopenharmony_ci            || !TEST_ptr(b[0] = BN_new())
850e1051a39Sopenharmony_ci            || !TEST_ptr(b[1] = BN_new())
851e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new())
852e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new()))
853e1051a39Sopenharmony_ci        goto err;
854e1051a39Sopenharmony_ci
855e1051a39Sopenharmony_ci    if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0]))
856e1051a39Sopenharmony_ci            && TEST_true(BN_GF2m_arr2poly(p1, b[1]))))
857e1051a39Sopenharmony_ci        goto err;
858e1051a39Sopenharmony_ci
859e1051a39Sopenharmony_ci    for (i = 0; i < NUM0; i++) {
860e1051a39Sopenharmony_ci        if (!TEST_true(BN_bntest_rand(a, 1024, 0, 0)))
861e1051a39Sopenharmony_ci                goto err;
862e1051a39Sopenharmony_ci        for (j = 0; j < 2; j++) {
863e1051a39Sopenharmony_ci            if (!(TEST_true(BN_GF2m_mod_sqr(c, a, b[j], ctx))
864e1051a39Sopenharmony_ci                    && TEST_true(BN_copy(d, a))
865e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_mod_mul(d, a, d, b[j], ctx))
866e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_add(d, c, d))
867e1051a39Sopenharmony_ci                    /* Test that a*a = a^2. */
868e1051a39Sopenharmony_ci                    && TEST_BN_eq_zero(d)))
869e1051a39Sopenharmony_ci                goto err;
870e1051a39Sopenharmony_ci        }
871e1051a39Sopenharmony_ci    }
872e1051a39Sopenharmony_ci    st = 1;
873e1051a39Sopenharmony_ci err:
874e1051a39Sopenharmony_ci    BN_free(a);
875e1051a39Sopenharmony_ci    BN_free(b[0]);
876e1051a39Sopenharmony_ci    BN_free(b[1]);
877e1051a39Sopenharmony_ci    BN_free(c);
878e1051a39Sopenharmony_ci    BN_free(d);
879e1051a39Sopenharmony_ci    return st;
880e1051a39Sopenharmony_ci}
881e1051a39Sopenharmony_ci
882e1051a39Sopenharmony_cistatic int test_gf2m_modinv(void)
883e1051a39Sopenharmony_ci{
884e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL;
885e1051a39Sopenharmony_ci    int i, j, st = 0;
886e1051a39Sopenharmony_ci
887e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
888e1051a39Sopenharmony_ci            || !TEST_ptr(b[0] = BN_new())
889e1051a39Sopenharmony_ci            || !TEST_ptr(b[1] = BN_new())
890e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new())
891e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new()))
892e1051a39Sopenharmony_ci        goto err;
893e1051a39Sopenharmony_ci
894e1051a39Sopenharmony_ci    if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0]))
895e1051a39Sopenharmony_ci            && TEST_true(BN_GF2m_arr2poly(p1, b[1]))))
896e1051a39Sopenharmony_ci        goto err;
897e1051a39Sopenharmony_ci
898e1051a39Sopenharmony_ci    for (i = 0; i < NUM0; i++) {
899e1051a39Sopenharmony_ci        if (!TEST_true(BN_bntest_rand(a, 512, 0, 0)))
900e1051a39Sopenharmony_ci            goto err;
901e1051a39Sopenharmony_ci        for (j = 0; j < 2; j++) {
902e1051a39Sopenharmony_ci            if (!(TEST_true(BN_GF2m_mod_inv(c, a, b[j], ctx))
903e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_mod_mul(d, a, c, b[j], ctx))
904e1051a39Sopenharmony_ci                    /* Test that ((1/a)*a) = 1. */
905e1051a39Sopenharmony_ci                    && TEST_BN_eq_one(d)))
906e1051a39Sopenharmony_ci                goto err;
907e1051a39Sopenharmony_ci        }
908e1051a39Sopenharmony_ci    }
909e1051a39Sopenharmony_ci    st = 1;
910e1051a39Sopenharmony_ci err:
911e1051a39Sopenharmony_ci    BN_free(a);
912e1051a39Sopenharmony_ci    BN_free(b[0]);
913e1051a39Sopenharmony_ci    BN_free(b[1]);
914e1051a39Sopenharmony_ci    BN_free(c);
915e1051a39Sopenharmony_ci    BN_free(d);
916e1051a39Sopenharmony_ci    return st;
917e1051a39Sopenharmony_ci}
918e1051a39Sopenharmony_ci
919e1051a39Sopenharmony_cistatic int test_gf2m_moddiv(void)
920e1051a39Sopenharmony_ci{
921e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL;
922e1051a39Sopenharmony_ci    BIGNUM *e = NULL, *f = NULL;
923e1051a39Sopenharmony_ci    int i, j, st = 0;
924e1051a39Sopenharmony_ci
925e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
926e1051a39Sopenharmony_ci            || !TEST_ptr(b[0] = BN_new())
927e1051a39Sopenharmony_ci            || !TEST_ptr(b[1] = BN_new())
928e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new())
929e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new())
930e1051a39Sopenharmony_ci            || !TEST_ptr(e = BN_new())
931e1051a39Sopenharmony_ci            || !TEST_ptr(f = BN_new()))
932e1051a39Sopenharmony_ci        goto err;
933e1051a39Sopenharmony_ci
934e1051a39Sopenharmony_ci    if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0]))
935e1051a39Sopenharmony_ci            && TEST_true(BN_GF2m_arr2poly(p1, b[1]))))
936e1051a39Sopenharmony_ci        goto err;
937e1051a39Sopenharmony_ci
938e1051a39Sopenharmony_ci    for (i = 0; i < NUM0; i++) {
939e1051a39Sopenharmony_ci        if (!(TEST_true(BN_bntest_rand(a, 512, 0, 0))
940e1051a39Sopenharmony_ci                && TEST_true(BN_bntest_rand(c, 512, 0, 0))))
941e1051a39Sopenharmony_ci            goto err;
942e1051a39Sopenharmony_ci        for (j = 0; j < 2; j++) {
943e1051a39Sopenharmony_ci            if (!(TEST_true(BN_GF2m_mod_div(d, a, c, b[j], ctx))
944e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_mod_mul(e, d, c, b[j], ctx))
945e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_mod_div(f, a, e, b[j], ctx))
946e1051a39Sopenharmony_ci                    /* Test that ((a/c)*c)/a = 1. */
947e1051a39Sopenharmony_ci                    && TEST_BN_eq_one(f)))
948e1051a39Sopenharmony_ci                goto err;
949e1051a39Sopenharmony_ci        }
950e1051a39Sopenharmony_ci    }
951e1051a39Sopenharmony_ci    st = 1;
952e1051a39Sopenharmony_ci err:
953e1051a39Sopenharmony_ci    BN_free(a);
954e1051a39Sopenharmony_ci    BN_free(b[0]);
955e1051a39Sopenharmony_ci    BN_free(b[1]);
956e1051a39Sopenharmony_ci    BN_free(c);
957e1051a39Sopenharmony_ci    BN_free(d);
958e1051a39Sopenharmony_ci    BN_free(e);
959e1051a39Sopenharmony_ci    BN_free(f);
960e1051a39Sopenharmony_ci    return st;
961e1051a39Sopenharmony_ci}
962e1051a39Sopenharmony_ci
963e1051a39Sopenharmony_cistatic int test_gf2m_modexp(void)
964e1051a39Sopenharmony_ci{
965e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL;
966e1051a39Sopenharmony_ci    BIGNUM *e = NULL, *f = NULL;
967e1051a39Sopenharmony_ci    int i, j, st = 0;
968e1051a39Sopenharmony_ci
969e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
970e1051a39Sopenharmony_ci            || !TEST_ptr(b[0] = BN_new())
971e1051a39Sopenharmony_ci            || !TEST_ptr(b[1] = BN_new())
972e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new())
973e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new())
974e1051a39Sopenharmony_ci            || !TEST_ptr(e = BN_new())
975e1051a39Sopenharmony_ci            || !TEST_ptr(f = BN_new()))
976e1051a39Sopenharmony_ci        goto err;
977e1051a39Sopenharmony_ci
978e1051a39Sopenharmony_ci    if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0]))
979e1051a39Sopenharmony_ci            && TEST_true(BN_GF2m_arr2poly(p1, b[1]))))
980e1051a39Sopenharmony_ci        goto err;
981e1051a39Sopenharmony_ci
982e1051a39Sopenharmony_ci    for (i = 0; i < NUM0; i++) {
983e1051a39Sopenharmony_ci        if (!(TEST_true(BN_bntest_rand(a, 512, 0, 0))
984e1051a39Sopenharmony_ci                && TEST_true(BN_bntest_rand(c, 512, 0, 0))
985e1051a39Sopenharmony_ci                && TEST_true(BN_bntest_rand(d, 512, 0, 0))))
986e1051a39Sopenharmony_ci            goto err;
987e1051a39Sopenharmony_ci        for (j = 0; j < 2; j++) {
988e1051a39Sopenharmony_ci            if (!(TEST_true(BN_GF2m_mod_exp(e, a, c, b[j], ctx))
989e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_mod_exp(f, a, d, b[j], ctx))
990e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_mod_mul(e, e, f, b[j], ctx))
991e1051a39Sopenharmony_ci                    && TEST_true(BN_add(f, c, d))
992e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_mod_exp(f, a, f, b[j], ctx))
993e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_add(f, e, f))
994e1051a39Sopenharmony_ci                    /* Test that a^(c+d)=a^c*a^d. */
995e1051a39Sopenharmony_ci                    && TEST_BN_eq_zero(f)))
996e1051a39Sopenharmony_ci                goto err;
997e1051a39Sopenharmony_ci        }
998e1051a39Sopenharmony_ci    }
999e1051a39Sopenharmony_ci    st = 1;
1000e1051a39Sopenharmony_ci err:
1001e1051a39Sopenharmony_ci    BN_free(a);
1002e1051a39Sopenharmony_ci    BN_free(b[0]);
1003e1051a39Sopenharmony_ci    BN_free(b[1]);
1004e1051a39Sopenharmony_ci    BN_free(c);
1005e1051a39Sopenharmony_ci    BN_free(d);
1006e1051a39Sopenharmony_ci    BN_free(e);
1007e1051a39Sopenharmony_ci    BN_free(f);
1008e1051a39Sopenharmony_ci    return st;
1009e1051a39Sopenharmony_ci}
1010e1051a39Sopenharmony_ci
1011e1051a39Sopenharmony_cistatic int test_gf2m_modsqrt(void)
1012e1051a39Sopenharmony_ci{
1013e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL;
1014e1051a39Sopenharmony_ci    BIGNUM *e = NULL, *f = NULL;
1015e1051a39Sopenharmony_ci    int i, j, st = 0;
1016e1051a39Sopenharmony_ci
1017e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
1018e1051a39Sopenharmony_ci            || !TEST_ptr(b[0] = BN_new())
1019e1051a39Sopenharmony_ci            || !TEST_ptr(b[1] = BN_new())
1020e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new())
1021e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new())
1022e1051a39Sopenharmony_ci            || !TEST_ptr(e = BN_new())
1023e1051a39Sopenharmony_ci            || !TEST_ptr(f = BN_new()))
1024e1051a39Sopenharmony_ci        goto err;
1025e1051a39Sopenharmony_ci
1026e1051a39Sopenharmony_ci    if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0]))
1027e1051a39Sopenharmony_ci            && TEST_true(BN_GF2m_arr2poly(p1, b[1]))))
1028e1051a39Sopenharmony_ci        goto err;
1029e1051a39Sopenharmony_ci
1030e1051a39Sopenharmony_ci    for (i = 0; i < NUM0; i++) {
1031e1051a39Sopenharmony_ci        if (!TEST_true(BN_bntest_rand(a, 512, 0, 0)))
1032e1051a39Sopenharmony_ci            goto err;
1033e1051a39Sopenharmony_ci
1034e1051a39Sopenharmony_ci        for (j = 0; j < 2; j++) {
1035e1051a39Sopenharmony_ci            if (!(TEST_true(BN_GF2m_mod(c, a, b[j]))
1036e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_mod_sqrt(d, a, b[j], ctx))
1037e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_mod_sqr(e, d, b[j], ctx))
1038e1051a39Sopenharmony_ci                    && TEST_true(BN_GF2m_add(f, c, e))
1039e1051a39Sopenharmony_ci                    /* Test that d^2 = a, where d = sqrt(a). */
1040e1051a39Sopenharmony_ci                    && TEST_BN_eq_zero(f)))
1041e1051a39Sopenharmony_ci                goto err;
1042e1051a39Sopenharmony_ci        }
1043e1051a39Sopenharmony_ci    }
1044e1051a39Sopenharmony_ci    st = 1;
1045e1051a39Sopenharmony_ci err:
1046e1051a39Sopenharmony_ci    BN_free(a);
1047e1051a39Sopenharmony_ci    BN_free(b[0]);
1048e1051a39Sopenharmony_ci    BN_free(b[1]);
1049e1051a39Sopenharmony_ci    BN_free(c);
1050e1051a39Sopenharmony_ci    BN_free(d);
1051e1051a39Sopenharmony_ci    BN_free(e);
1052e1051a39Sopenharmony_ci    BN_free(f);
1053e1051a39Sopenharmony_ci    return st;
1054e1051a39Sopenharmony_ci}
1055e1051a39Sopenharmony_ci
1056e1051a39Sopenharmony_cistatic int test_gf2m_modsolvequad(void)
1057e1051a39Sopenharmony_ci{
1058e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b[2] = {NULL,NULL}, *c = NULL, *d = NULL;
1059e1051a39Sopenharmony_ci    BIGNUM *e = NULL;
1060e1051a39Sopenharmony_ci    int i, j, s = 0, t, st = 0;
1061e1051a39Sopenharmony_ci
1062e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
1063e1051a39Sopenharmony_ci            || !TEST_ptr(b[0] = BN_new())
1064e1051a39Sopenharmony_ci            || !TEST_ptr(b[1] = BN_new())
1065e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new())
1066e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new())
1067e1051a39Sopenharmony_ci            || !TEST_ptr(e = BN_new()))
1068e1051a39Sopenharmony_ci        goto err;
1069e1051a39Sopenharmony_ci
1070e1051a39Sopenharmony_ci    if (!(TEST_true(BN_GF2m_arr2poly(p0, b[0]))
1071e1051a39Sopenharmony_ci            && TEST_true(BN_GF2m_arr2poly(p1, b[1]))))
1072e1051a39Sopenharmony_ci        goto err;
1073e1051a39Sopenharmony_ci
1074e1051a39Sopenharmony_ci    for (i = 0; i < NUM0; i++) {
1075e1051a39Sopenharmony_ci        if (!TEST_true(BN_bntest_rand(a, 512, 0, 0)))
1076e1051a39Sopenharmony_ci            goto err;
1077e1051a39Sopenharmony_ci        for (j = 0; j < 2; j++) {
1078e1051a39Sopenharmony_ci            t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
1079e1051a39Sopenharmony_ci            if (t) {
1080e1051a39Sopenharmony_ci                s++;
1081e1051a39Sopenharmony_ci                if (!(TEST_true(BN_GF2m_mod_sqr(d, c, b[j], ctx))
1082e1051a39Sopenharmony_ci                        && TEST_true(BN_GF2m_add(d, c, d))
1083e1051a39Sopenharmony_ci                        && TEST_true(BN_GF2m_mod(e, a, b[j]))
1084e1051a39Sopenharmony_ci                        && TEST_true(BN_GF2m_add(e, e, d))
1085e1051a39Sopenharmony_ci                        /*
1086e1051a39Sopenharmony_ci                         * Test that solution of quadratic c
1087e1051a39Sopenharmony_ci                         * satisfies c^2 + c = a.
1088e1051a39Sopenharmony_ci                         */
1089e1051a39Sopenharmony_ci                        && TEST_BN_eq_zero(e)))
1090e1051a39Sopenharmony_ci                    goto err;
1091e1051a39Sopenharmony_ci            }
1092e1051a39Sopenharmony_ci        }
1093e1051a39Sopenharmony_ci    }
1094e1051a39Sopenharmony_ci    if (!TEST_int_ge(s, 0)) {
1095e1051a39Sopenharmony_ci        TEST_info("%d tests found no roots; probably an error", NUM0);
1096e1051a39Sopenharmony_ci        goto err;
1097e1051a39Sopenharmony_ci    }
1098e1051a39Sopenharmony_ci    st = 1;
1099e1051a39Sopenharmony_ci err:
1100e1051a39Sopenharmony_ci    BN_free(a);
1101e1051a39Sopenharmony_ci    BN_free(b[0]);
1102e1051a39Sopenharmony_ci    BN_free(b[1]);
1103e1051a39Sopenharmony_ci    BN_free(c);
1104e1051a39Sopenharmony_ci    BN_free(d);
1105e1051a39Sopenharmony_ci    BN_free(e);
1106e1051a39Sopenharmony_ci    return st;
1107e1051a39Sopenharmony_ci}
1108e1051a39Sopenharmony_ci#endif
1109e1051a39Sopenharmony_ci
1110e1051a39Sopenharmony_cistatic int test_kronecker(void)
1111e1051a39Sopenharmony_ci{
1112e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *r = NULL, *t = NULL;
1113e1051a39Sopenharmony_ci    int i, legendre, kronecker, st = 0;
1114e1051a39Sopenharmony_ci
1115e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
1116e1051a39Sopenharmony_ci            || !TEST_ptr(b = BN_new())
1117e1051a39Sopenharmony_ci            || !TEST_ptr(r = BN_new())
1118e1051a39Sopenharmony_ci            || !TEST_ptr(t = BN_new()))
1119e1051a39Sopenharmony_ci        goto err;
1120e1051a39Sopenharmony_ci
1121e1051a39Sopenharmony_ci    /*
1122e1051a39Sopenharmony_ci     * We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol). In
1123e1051a39Sopenharmony_ci     * this case we know that if b is prime, then BN_kronecker(a, b, ctx) is
1124e1051a39Sopenharmony_ci     * congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol). So we
1125e1051a39Sopenharmony_ci     * generate a random prime b and compare these values for a number of
1126e1051a39Sopenharmony_ci     * random a's.  (That is, we run the Solovay-Strassen primality test to
1127e1051a39Sopenharmony_ci     * confirm that b is prime, except that we don't want to test whether b
1128e1051a39Sopenharmony_ci     * is prime but whether BN_kronecker works.)
1129e1051a39Sopenharmony_ci     */
1130e1051a39Sopenharmony_ci
1131e1051a39Sopenharmony_ci    if (!TEST_true(BN_generate_prime_ex(b, 512, 0, NULL, NULL, NULL)))
1132e1051a39Sopenharmony_ci        goto err;
1133e1051a39Sopenharmony_ci    BN_set_negative(b, rand_neg());
1134e1051a39Sopenharmony_ci
1135e1051a39Sopenharmony_ci    for (i = 0; i < NUM0; i++) {
1136e1051a39Sopenharmony_ci        if (!TEST_true(BN_bntest_rand(a, 512, 0, 0)))
1137e1051a39Sopenharmony_ci            goto err;
1138e1051a39Sopenharmony_ci        BN_set_negative(a, rand_neg());
1139e1051a39Sopenharmony_ci
1140e1051a39Sopenharmony_ci        /* t := (|b|-1)/2  (note that b is odd) */
1141e1051a39Sopenharmony_ci        if (!TEST_true(BN_copy(t, b)))
1142e1051a39Sopenharmony_ci            goto err;
1143e1051a39Sopenharmony_ci        BN_set_negative(t, 0);
1144e1051a39Sopenharmony_ci        if (!TEST_true(BN_sub_word(t, 1)))
1145e1051a39Sopenharmony_ci            goto err;
1146e1051a39Sopenharmony_ci        if (!TEST_true(BN_rshift1(t, t)))
1147e1051a39Sopenharmony_ci            goto err;
1148e1051a39Sopenharmony_ci        /* r := a^t mod b */
1149e1051a39Sopenharmony_ci        BN_set_negative(b, 0);
1150e1051a39Sopenharmony_ci
1151e1051a39Sopenharmony_ci        if (!TEST_true(BN_mod_exp_recp(r, a, t, b, ctx)))
1152e1051a39Sopenharmony_ci            goto err;
1153e1051a39Sopenharmony_ci        BN_set_negative(b, 1);
1154e1051a39Sopenharmony_ci
1155e1051a39Sopenharmony_ci        if (BN_is_word(r, 1))
1156e1051a39Sopenharmony_ci            legendre = 1;
1157e1051a39Sopenharmony_ci        else if (BN_is_zero(r))
1158e1051a39Sopenharmony_ci            legendre = 0;
1159e1051a39Sopenharmony_ci        else {
1160e1051a39Sopenharmony_ci            if (!TEST_true(BN_add_word(r, 1)))
1161e1051a39Sopenharmony_ci                goto err;
1162e1051a39Sopenharmony_ci            if (!TEST_int_eq(BN_ucmp(r, b), 0)) {
1163e1051a39Sopenharmony_ci                TEST_info("Legendre symbol computation failed");
1164e1051a39Sopenharmony_ci                goto err;
1165e1051a39Sopenharmony_ci            }
1166e1051a39Sopenharmony_ci            legendre = -1;
1167e1051a39Sopenharmony_ci        }
1168e1051a39Sopenharmony_ci
1169e1051a39Sopenharmony_ci        if (!TEST_int_ge(kronecker = BN_kronecker(a, b, ctx), -1))
1170e1051a39Sopenharmony_ci            goto err;
1171e1051a39Sopenharmony_ci        /* we actually need BN_kronecker(a, |b|) */
1172e1051a39Sopenharmony_ci        if (BN_is_negative(a) && BN_is_negative(b))
1173e1051a39Sopenharmony_ci            kronecker = -kronecker;
1174e1051a39Sopenharmony_ci
1175e1051a39Sopenharmony_ci        if (!TEST_int_eq(legendre, kronecker))
1176e1051a39Sopenharmony_ci            goto err;
1177e1051a39Sopenharmony_ci    }
1178e1051a39Sopenharmony_ci
1179e1051a39Sopenharmony_ci    st = 1;
1180e1051a39Sopenharmony_ci err:
1181e1051a39Sopenharmony_ci    BN_free(a);
1182e1051a39Sopenharmony_ci    BN_free(b);
1183e1051a39Sopenharmony_ci    BN_free(r);
1184e1051a39Sopenharmony_ci    BN_free(t);
1185e1051a39Sopenharmony_ci    return st;
1186e1051a39Sopenharmony_ci}
1187e1051a39Sopenharmony_ci
1188e1051a39Sopenharmony_cistatic int file_sum(STANZA *s)
1189e1051a39Sopenharmony_ci{
1190e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *sum = NULL, *ret = NULL;
1191e1051a39Sopenharmony_ci    BN_ULONG b_word;
1192e1051a39Sopenharmony_ci    int st = 0;
1193e1051a39Sopenharmony_ci
1194e1051a39Sopenharmony_ci    if (!TEST_ptr(a = getBN(s, "A"))
1195e1051a39Sopenharmony_ci            || !TEST_ptr(b = getBN(s, "B"))
1196e1051a39Sopenharmony_ci            || !TEST_ptr(sum = getBN(s, "Sum"))
1197e1051a39Sopenharmony_ci            || !TEST_ptr(ret = BN_new()))
1198e1051a39Sopenharmony_ci        goto err;
1199e1051a39Sopenharmony_ci
1200e1051a39Sopenharmony_ci    if (!TEST_true(BN_add(ret, a, b))
1201e1051a39Sopenharmony_ci            || !equalBN("A + B", sum, ret)
1202e1051a39Sopenharmony_ci            || !TEST_true(BN_sub(ret, sum, a))
1203e1051a39Sopenharmony_ci            || !equalBN("Sum - A", b, ret)
1204e1051a39Sopenharmony_ci            || !TEST_true(BN_sub(ret, sum, b))
1205e1051a39Sopenharmony_ci            || !equalBN("Sum - B", a, ret))
1206e1051a39Sopenharmony_ci        goto err;
1207e1051a39Sopenharmony_ci
1208e1051a39Sopenharmony_ci    /*
1209e1051a39Sopenharmony_ci     * Test that the functions work when |r| and |a| point to the same BIGNUM,
1210e1051a39Sopenharmony_ci     * or when |r| and |b| point to the same BIGNUM.
1211e1051a39Sopenharmony_ci     * There is no test for all of |r|, |a|, and |b| pointint to the same BIGNUM.
1212e1051a39Sopenharmony_ci     */
1213e1051a39Sopenharmony_ci    if (!TEST_true(BN_copy(ret, a))
1214e1051a39Sopenharmony_ci            || !TEST_true(BN_add(ret, ret, b))
1215e1051a39Sopenharmony_ci            || !equalBN("A + B (r is a)", sum, ret)
1216e1051a39Sopenharmony_ci            || !TEST_true(BN_copy(ret, b))
1217e1051a39Sopenharmony_ci            || !TEST_true(BN_add(ret, a, ret))
1218e1051a39Sopenharmony_ci            || !equalBN("A + B (r is b)", sum, ret)
1219e1051a39Sopenharmony_ci            || !TEST_true(BN_copy(ret, sum))
1220e1051a39Sopenharmony_ci            || !TEST_true(BN_sub(ret, ret, a))
1221e1051a39Sopenharmony_ci            || !equalBN("Sum - A (r is a)", b, ret)
1222e1051a39Sopenharmony_ci            || !TEST_true(BN_copy(ret, a))
1223e1051a39Sopenharmony_ci            || !TEST_true(BN_sub(ret, sum, ret))
1224e1051a39Sopenharmony_ci            || !equalBN("Sum - A (r is b)", b, ret)
1225e1051a39Sopenharmony_ci            || !TEST_true(BN_copy(ret, sum))
1226e1051a39Sopenharmony_ci            || !TEST_true(BN_sub(ret, ret, b))
1227e1051a39Sopenharmony_ci            || !equalBN("Sum - B (r is a)", a, ret)
1228e1051a39Sopenharmony_ci            || !TEST_true(BN_copy(ret, b))
1229e1051a39Sopenharmony_ci            || !TEST_true(BN_sub(ret, sum, ret))
1230e1051a39Sopenharmony_ci            || !equalBN("Sum - B (r is b)", a, ret))
1231e1051a39Sopenharmony_ci        goto err;
1232e1051a39Sopenharmony_ci
1233e1051a39Sopenharmony_ci    /*
1234e1051a39Sopenharmony_ci     * Test BN_uadd() and BN_usub() with the prerequisites they are
1235e1051a39Sopenharmony_ci     * documented as having. Note that these functions are frequently used
1236e1051a39Sopenharmony_ci     * when the prerequisites don't hold. In those cases, they are supposed
1237e1051a39Sopenharmony_ci     * to work as if the prerequisite hold, but we don't test that yet.
1238e1051a39Sopenharmony_ci     */
1239e1051a39Sopenharmony_ci    if (!BN_is_negative(a) && !BN_is_negative(b) && BN_cmp(a, b) >= 0) {
1240e1051a39Sopenharmony_ci        if (!TEST_true(BN_uadd(ret, a, b))
1241e1051a39Sopenharmony_ci                || !equalBN("A +u B", sum, ret)
1242e1051a39Sopenharmony_ci                || !TEST_true(BN_usub(ret, sum, a))
1243e1051a39Sopenharmony_ci                || !equalBN("Sum -u A", b, ret)
1244e1051a39Sopenharmony_ci                || !TEST_true(BN_usub(ret, sum, b))
1245e1051a39Sopenharmony_ci                || !equalBN("Sum -u B", a, ret))
1246e1051a39Sopenharmony_ci            goto err;
1247e1051a39Sopenharmony_ci        /*
1248e1051a39Sopenharmony_ci         * Test that the functions work when |r| and |a| point to the same
1249e1051a39Sopenharmony_ci         * BIGNUM, or when |r| and |b| point to the same BIGNUM.
1250e1051a39Sopenharmony_ci         * There is no test for all of |r|, |a|, and |b| pointint to the same
1251e1051a39Sopenharmony_ci         * BIGNUM.
1252e1051a39Sopenharmony_ci         */
1253e1051a39Sopenharmony_ci        if (!TEST_true(BN_copy(ret, a))
1254e1051a39Sopenharmony_ci                || !TEST_true(BN_uadd(ret, ret, b))
1255e1051a39Sopenharmony_ci                || !equalBN("A +u B (r is a)", sum, ret)
1256e1051a39Sopenharmony_ci                || !TEST_true(BN_copy(ret, b))
1257e1051a39Sopenharmony_ci                || !TEST_true(BN_uadd(ret, a, ret))
1258e1051a39Sopenharmony_ci                || !equalBN("A +u B (r is b)", sum, ret)
1259e1051a39Sopenharmony_ci                || !TEST_true(BN_copy(ret, sum))
1260e1051a39Sopenharmony_ci                || !TEST_true(BN_usub(ret, ret, a))
1261e1051a39Sopenharmony_ci                || !equalBN("Sum -u A (r is a)", b, ret)
1262e1051a39Sopenharmony_ci                || !TEST_true(BN_copy(ret, a))
1263e1051a39Sopenharmony_ci                || !TEST_true(BN_usub(ret, sum, ret))
1264e1051a39Sopenharmony_ci                || !equalBN("Sum -u A (r is b)", b, ret)
1265e1051a39Sopenharmony_ci                || !TEST_true(BN_copy(ret, sum))
1266e1051a39Sopenharmony_ci                || !TEST_true(BN_usub(ret, ret, b))
1267e1051a39Sopenharmony_ci                || !equalBN("Sum -u B (r is a)", a, ret)
1268e1051a39Sopenharmony_ci                || !TEST_true(BN_copy(ret, b))
1269e1051a39Sopenharmony_ci                || !TEST_true(BN_usub(ret, sum, ret))
1270e1051a39Sopenharmony_ci                || !equalBN("Sum -u B (r is b)", a, ret))
1271e1051a39Sopenharmony_ci            goto err;
1272e1051a39Sopenharmony_ci    }
1273e1051a39Sopenharmony_ci
1274e1051a39Sopenharmony_ci    /*
1275e1051a39Sopenharmony_ci     * Test with BN_add_word() and BN_sub_word() if |b| is small enough.
1276e1051a39Sopenharmony_ci     */
1277e1051a39Sopenharmony_ci    b_word = BN_get_word(b);
1278e1051a39Sopenharmony_ci    if (!BN_is_negative(b) && b_word != (BN_ULONG)-1) {
1279e1051a39Sopenharmony_ci        if (!TEST_true(BN_copy(ret, a))
1280e1051a39Sopenharmony_ci                || !TEST_true(BN_add_word(ret, b_word))
1281e1051a39Sopenharmony_ci                || !equalBN("A + B (word)", sum, ret)
1282e1051a39Sopenharmony_ci                || !TEST_true(BN_copy(ret, sum))
1283e1051a39Sopenharmony_ci                || !TEST_true(BN_sub_word(ret, b_word))
1284e1051a39Sopenharmony_ci                || !equalBN("Sum - B (word)", a, ret))
1285e1051a39Sopenharmony_ci            goto err;
1286e1051a39Sopenharmony_ci    }
1287e1051a39Sopenharmony_ci    st = 1;
1288e1051a39Sopenharmony_ci
1289e1051a39Sopenharmony_ci err:
1290e1051a39Sopenharmony_ci    BN_free(a);
1291e1051a39Sopenharmony_ci    BN_free(b);
1292e1051a39Sopenharmony_ci    BN_free(sum);
1293e1051a39Sopenharmony_ci    BN_free(ret);
1294e1051a39Sopenharmony_ci    return st;
1295e1051a39Sopenharmony_ci}
1296e1051a39Sopenharmony_ci
1297e1051a39Sopenharmony_cistatic int file_lshift1(STANZA *s)
1298e1051a39Sopenharmony_ci{
1299e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *lshift1 = NULL, *zero = NULL, *ret = NULL;
1300e1051a39Sopenharmony_ci    BIGNUM *two = NULL, *remainder = NULL;
1301e1051a39Sopenharmony_ci    int st = 0;
1302e1051a39Sopenharmony_ci
1303e1051a39Sopenharmony_ci    if (!TEST_ptr(a = getBN(s, "A"))
1304e1051a39Sopenharmony_ci            || !TEST_ptr(lshift1 = getBN(s, "LShift1"))
1305e1051a39Sopenharmony_ci            || !TEST_ptr(zero = BN_new())
1306e1051a39Sopenharmony_ci            || !TEST_ptr(ret = BN_new())
1307e1051a39Sopenharmony_ci            || !TEST_ptr(two = BN_new())
1308e1051a39Sopenharmony_ci            || !TEST_ptr(remainder = BN_new()))
1309e1051a39Sopenharmony_ci        goto err;
1310e1051a39Sopenharmony_ci
1311e1051a39Sopenharmony_ci    BN_zero(zero);
1312e1051a39Sopenharmony_ci
1313e1051a39Sopenharmony_ci    if (!TEST_true(BN_set_word(two, 2))
1314e1051a39Sopenharmony_ci            || !TEST_true(BN_add(ret, a, a))
1315e1051a39Sopenharmony_ci            || !equalBN("A + A", lshift1, ret)
1316e1051a39Sopenharmony_ci            || !TEST_true(BN_mul(ret, a, two, ctx))
1317e1051a39Sopenharmony_ci            || !equalBN("A * 2", lshift1, ret)
1318e1051a39Sopenharmony_ci            || !TEST_true(BN_div(ret, remainder, lshift1, two, ctx))
1319e1051a39Sopenharmony_ci            || !equalBN("LShift1 / 2", a, ret)
1320e1051a39Sopenharmony_ci            || !equalBN("LShift1 % 2", zero, remainder)
1321e1051a39Sopenharmony_ci            || !TEST_true(BN_lshift1(ret, a))
1322e1051a39Sopenharmony_ci            || !equalBN("A << 1", lshift1, ret)
1323e1051a39Sopenharmony_ci            || !TEST_true(BN_rshift1(ret, lshift1))
1324e1051a39Sopenharmony_ci            || !equalBN("LShift >> 1", a, ret)
1325e1051a39Sopenharmony_ci            || !TEST_true(BN_rshift1(ret, lshift1))
1326e1051a39Sopenharmony_ci            || !equalBN("LShift >> 1", a, ret))
1327e1051a39Sopenharmony_ci        goto err;
1328e1051a39Sopenharmony_ci
1329e1051a39Sopenharmony_ci    /* Set the LSB to 1 and test rshift1 again. */
1330e1051a39Sopenharmony_ci    if (!TEST_true(BN_set_bit(lshift1, 0))
1331e1051a39Sopenharmony_ci            || !TEST_true(BN_div(ret, NULL /* rem */ , lshift1, two, ctx))
1332e1051a39Sopenharmony_ci            || !equalBN("(LShift1 | 1) / 2", a, ret)
1333e1051a39Sopenharmony_ci            || !TEST_true(BN_rshift1(ret, lshift1))
1334e1051a39Sopenharmony_ci            || !equalBN("(LShift | 1) >> 1", a, ret))
1335e1051a39Sopenharmony_ci        goto err;
1336e1051a39Sopenharmony_ci
1337e1051a39Sopenharmony_ci    st = 1;
1338e1051a39Sopenharmony_ci err:
1339e1051a39Sopenharmony_ci    BN_free(a);
1340e1051a39Sopenharmony_ci    BN_free(lshift1);
1341e1051a39Sopenharmony_ci    BN_free(zero);
1342e1051a39Sopenharmony_ci    BN_free(ret);
1343e1051a39Sopenharmony_ci    BN_free(two);
1344e1051a39Sopenharmony_ci    BN_free(remainder);
1345e1051a39Sopenharmony_ci
1346e1051a39Sopenharmony_ci    return st;
1347e1051a39Sopenharmony_ci}
1348e1051a39Sopenharmony_ci
1349e1051a39Sopenharmony_cistatic int file_lshift(STANZA *s)
1350e1051a39Sopenharmony_ci{
1351e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *lshift = NULL, *ret = NULL;
1352e1051a39Sopenharmony_ci    int n = 0, st = 0;
1353e1051a39Sopenharmony_ci
1354e1051a39Sopenharmony_ci    if (!TEST_ptr(a = getBN(s, "A"))
1355e1051a39Sopenharmony_ci            || !TEST_ptr(lshift = getBN(s, "LShift"))
1356e1051a39Sopenharmony_ci            || !TEST_ptr(ret = BN_new())
1357e1051a39Sopenharmony_ci            || !getint(s, &n, "N"))
1358e1051a39Sopenharmony_ci        goto err;
1359e1051a39Sopenharmony_ci
1360e1051a39Sopenharmony_ci    if (!TEST_true(BN_lshift(ret, a, n))
1361e1051a39Sopenharmony_ci            || !equalBN("A << N", lshift, ret)
1362e1051a39Sopenharmony_ci            || !TEST_true(BN_rshift(ret, lshift, n))
1363e1051a39Sopenharmony_ci            || !equalBN("A >> N", a, ret))
1364e1051a39Sopenharmony_ci        goto err;
1365e1051a39Sopenharmony_ci
1366e1051a39Sopenharmony_ci    st = 1;
1367e1051a39Sopenharmony_ci err:
1368e1051a39Sopenharmony_ci    BN_free(a);
1369e1051a39Sopenharmony_ci    BN_free(lshift);
1370e1051a39Sopenharmony_ci    BN_free(ret);
1371e1051a39Sopenharmony_ci    return st;
1372e1051a39Sopenharmony_ci}
1373e1051a39Sopenharmony_ci
1374e1051a39Sopenharmony_cistatic int file_rshift(STANZA *s)
1375e1051a39Sopenharmony_ci{
1376e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *rshift = NULL, *ret = NULL;
1377e1051a39Sopenharmony_ci    int n = 0, st = 0;
1378e1051a39Sopenharmony_ci
1379e1051a39Sopenharmony_ci    if (!TEST_ptr(a = getBN(s, "A"))
1380e1051a39Sopenharmony_ci            || !TEST_ptr(rshift = getBN(s, "RShift"))
1381e1051a39Sopenharmony_ci            || !TEST_ptr(ret = BN_new())
1382e1051a39Sopenharmony_ci            || !getint(s, &n, "N"))
1383e1051a39Sopenharmony_ci        goto err;
1384e1051a39Sopenharmony_ci
1385e1051a39Sopenharmony_ci    if (!TEST_true(BN_rshift(ret, a, n))
1386e1051a39Sopenharmony_ci            || !equalBN("A >> N", rshift, ret))
1387e1051a39Sopenharmony_ci        goto err;
1388e1051a39Sopenharmony_ci
1389e1051a39Sopenharmony_ci    /* If N == 1, try with rshift1 as well */
1390e1051a39Sopenharmony_ci    if (n == 1) {
1391e1051a39Sopenharmony_ci        if (!TEST_true(BN_rshift1(ret, a))
1392e1051a39Sopenharmony_ci                || !equalBN("A >> 1 (rshift1)", rshift, ret))
1393e1051a39Sopenharmony_ci            goto err;
1394e1051a39Sopenharmony_ci    }
1395e1051a39Sopenharmony_ci    st = 1;
1396e1051a39Sopenharmony_ci
1397e1051a39Sopenharmony_ci err:
1398e1051a39Sopenharmony_ci    BN_free(a);
1399e1051a39Sopenharmony_ci    BN_free(rshift);
1400e1051a39Sopenharmony_ci    BN_free(ret);
1401e1051a39Sopenharmony_ci    return st;
1402e1051a39Sopenharmony_ci}
1403e1051a39Sopenharmony_ci
1404e1051a39Sopenharmony_cistatic int file_square(STANZA *s)
1405e1051a39Sopenharmony_ci{
1406e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *square = NULL, *zero = NULL, *ret = NULL;
1407e1051a39Sopenharmony_ci    BIGNUM *remainder = NULL, *tmp = NULL;
1408e1051a39Sopenharmony_ci    int st = 0;
1409e1051a39Sopenharmony_ci
1410e1051a39Sopenharmony_ci    if (!TEST_ptr(a = getBN(s, "A"))
1411e1051a39Sopenharmony_ci            || !TEST_ptr(square = getBN(s, "Square"))
1412e1051a39Sopenharmony_ci            || !TEST_ptr(zero = BN_new())
1413e1051a39Sopenharmony_ci            || !TEST_ptr(ret = BN_new())
1414e1051a39Sopenharmony_ci            || !TEST_ptr(remainder = BN_new()))
1415e1051a39Sopenharmony_ci        goto err;
1416e1051a39Sopenharmony_ci
1417e1051a39Sopenharmony_ci    BN_zero(zero);
1418e1051a39Sopenharmony_ci    if (!TEST_true(BN_sqr(ret, a, ctx))
1419e1051a39Sopenharmony_ci            || !equalBN("A^2", square, ret)
1420e1051a39Sopenharmony_ci            || !TEST_true(BN_mul(ret, a, a, ctx))
1421e1051a39Sopenharmony_ci            || !equalBN("A * A", square, ret)
1422e1051a39Sopenharmony_ci            || !TEST_true(BN_div(ret, remainder, square, a, ctx))
1423e1051a39Sopenharmony_ci            || !equalBN("Square / A", a, ret)
1424e1051a39Sopenharmony_ci            || !equalBN("Square % A", zero, remainder))
1425e1051a39Sopenharmony_ci        goto err;
1426e1051a39Sopenharmony_ci
1427e1051a39Sopenharmony_ci#if HAVE_BN_SQRT
1428e1051a39Sopenharmony_ci    BN_set_negative(a, 0);
1429e1051a39Sopenharmony_ci    if (!TEST_true(BN_sqrt(ret, square, ctx))
1430e1051a39Sopenharmony_ci            || !equalBN("sqrt(Square)", a, ret))
1431e1051a39Sopenharmony_ci        goto err;
1432e1051a39Sopenharmony_ci
1433e1051a39Sopenharmony_ci    /* BN_sqrt should fail on non-squares and negative numbers. */
1434e1051a39Sopenharmony_ci    if (!TEST_BN_eq_zero(square)) {
1435e1051a39Sopenharmony_ci        if (!TEST_ptr(tmp = BN_new())
1436e1051a39Sopenharmony_ci                || !TEST_true(BN_copy(tmp, square)))
1437e1051a39Sopenharmony_ci            goto err;
1438e1051a39Sopenharmony_ci        BN_set_negative(tmp, 1);
1439e1051a39Sopenharmony_ci
1440e1051a39Sopenharmony_ci        if (!TEST_int_eq(BN_sqrt(ret, tmp, ctx), 0))
1441e1051a39Sopenharmony_ci            goto err;
1442e1051a39Sopenharmony_ci        ERR_clear_error();
1443e1051a39Sopenharmony_ci
1444e1051a39Sopenharmony_ci        BN_set_negative(tmp, 0);
1445e1051a39Sopenharmony_ci        if (BN_add(tmp, tmp, BN_value_one()))
1446e1051a39Sopenharmony_ci            goto err;
1447e1051a39Sopenharmony_ci        if (!TEST_int_eq(BN_sqrt(ret, tmp, ctx)))
1448e1051a39Sopenharmony_ci            goto err;
1449e1051a39Sopenharmony_ci        ERR_clear_error();
1450e1051a39Sopenharmony_ci    }
1451e1051a39Sopenharmony_ci#endif
1452e1051a39Sopenharmony_ci
1453e1051a39Sopenharmony_ci    st = 1;
1454e1051a39Sopenharmony_ci err:
1455e1051a39Sopenharmony_ci    BN_free(a);
1456e1051a39Sopenharmony_ci    BN_free(square);
1457e1051a39Sopenharmony_ci    BN_free(zero);
1458e1051a39Sopenharmony_ci    BN_free(ret);
1459e1051a39Sopenharmony_ci    BN_free(remainder);
1460e1051a39Sopenharmony_ci    BN_free(tmp);
1461e1051a39Sopenharmony_ci    return st;
1462e1051a39Sopenharmony_ci}
1463e1051a39Sopenharmony_ci
1464e1051a39Sopenharmony_cistatic int file_product(STANZA *s)
1465e1051a39Sopenharmony_ci{
1466e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *product = NULL, *ret = NULL;
1467e1051a39Sopenharmony_ci    BIGNUM *remainder = NULL, *zero = NULL;
1468e1051a39Sopenharmony_ci    int st = 0;
1469e1051a39Sopenharmony_ci
1470e1051a39Sopenharmony_ci    if (!TEST_ptr(a = getBN(s, "A"))
1471e1051a39Sopenharmony_ci            || !TEST_ptr(b = getBN(s, "B"))
1472e1051a39Sopenharmony_ci            || !TEST_ptr(product = getBN(s, "Product"))
1473e1051a39Sopenharmony_ci            || !TEST_ptr(ret = BN_new())
1474e1051a39Sopenharmony_ci            || !TEST_ptr(remainder = BN_new())
1475e1051a39Sopenharmony_ci            || !TEST_ptr(zero = BN_new()))
1476e1051a39Sopenharmony_ci        goto err;
1477e1051a39Sopenharmony_ci
1478e1051a39Sopenharmony_ci    BN_zero(zero);
1479e1051a39Sopenharmony_ci
1480e1051a39Sopenharmony_ci    if (!TEST_true(BN_mul(ret, a, b, ctx))
1481e1051a39Sopenharmony_ci            || !equalBN("A * B", product, ret)
1482e1051a39Sopenharmony_ci            || !TEST_true(BN_div(ret, remainder, product, a, ctx))
1483e1051a39Sopenharmony_ci            || !equalBN("Product / A", b, ret)
1484e1051a39Sopenharmony_ci            || !equalBN("Product % A", zero, remainder)
1485e1051a39Sopenharmony_ci            || !TEST_true(BN_div(ret, remainder, product, b, ctx))
1486e1051a39Sopenharmony_ci            || !equalBN("Product / B", a, ret)
1487e1051a39Sopenharmony_ci            || !equalBN("Product % B", zero, remainder))
1488e1051a39Sopenharmony_ci        goto err;
1489e1051a39Sopenharmony_ci
1490e1051a39Sopenharmony_ci    st = 1;
1491e1051a39Sopenharmony_ci err:
1492e1051a39Sopenharmony_ci    BN_free(a);
1493e1051a39Sopenharmony_ci    BN_free(b);
1494e1051a39Sopenharmony_ci    BN_free(product);
1495e1051a39Sopenharmony_ci    BN_free(ret);
1496e1051a39Sopenharmony_ci    BN_free(remainder);
1497e1051a39Sopenharmony_ci    BN_free(zero);
1498e1051a39Sopenharmony_ci    return st;
1499e1051a39Sopenharmony_ci}
1500e1051a39Sopenharmony_ci
1501e1051a39Sopenharmony_cistatic int file_quotient(STANZA *s)
1502e1051a39Sopenharmony_ci{
1503e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *quotient = NULL, *remainder = NULL;
1504e1051a39Sopenharmony_ci    BIGNUM *ret = NULL, *ret2 = NULL, *nnmod = NULL;
1505e1051a39Sopenharmony_ci    BN_ULONG b_word, ret_word;
1506e1051a39Sopenharmony_ci    int st = 0;
1507e1051a39Sopenharmony_ci
1508e1051a39Sopenharmony_ci    if (!TEST_ptr(a = getBN(s, "A"))
1509e1051a39Sopenharmony_ci            || !TEST_ptr(b = getBN(s, "B"))
1510e1051a39Sopenharmony_ci            || !TEST_ptr(quotient = getBN(s, "Quotient"))
1511e1051a39Sopenharmony_ci            || !TEST_ptr(remainder = getBN(s, "Remainder"))
1512e1051a39Sopenharmony_ci            || !TEST_ptr(ret = BN_new())
1513e1051a39Sopenharmony_ci            || !TEST_ptr(ret2 = BN_new())
1514e1051a39Sopenharmony_ci            || !TEST_ptr(nnmod = BN_new()))
1515e1051a39Sopenharmony_ci        goto err;
1516e1051a39Sopenharmony_ci
1517e1051a39Sopenharmony_ci    if (!TEST_true(BN_div(ret, ret2, a, b, ctx))
1518e1051a39Sopenharmony_ci            || !equalBN("A / B", quotient, ret)
1519e1051a39Sopenharmony_ci            || !equalBN("A % B", remainder, ret2)
1520e1051a39Sopenharmony_ci            || !TEST_true(BN_mul(ret, quotient, b, ctx))
1521e1051a39Sopenharmony_ci            || !TEST_true(BN_add(ret, ret, remainder))
1522e1051a39Sopenharmony_ci            || !equalBN("Quotient * B + Remainder", a, ret))
1523e1051a39Sopenharmony_ci        goto err;
1524e1051a39Sopenharmony_ci
1525e1051a39Sopenharmony_ci    /*
1526e1051a39Sopenharmony_ci     * Test with BN_mod_word() and BN_div_word() if the divisor is
1527e1051a39Sopenharmony_ci     * small enough.
1528e1051a39Sopenharmony_ci     */
1529e1051a39Sopenharmony_ci    b_word = BN_get_word(b);
1530e1051a39Sopenharmony_ci    if (!BN_is_negative(b) && b_word != (BN_ULONG)-1) {
1531e1051a39Sopenharmony_ci        BN_ULONG remainder_word = BN_get_word(remainder);
1532e1051a39Sopenharmony_ci
1533e1051a39Sopenharmony_ci        assert(remainder_word != (BN_ULONG)-1);
1534e1051a39Sopenharmony_ci        if (!TEST_ptr(BN_copy(ret, a)))
1535e1051a39Sopenharmony_ci            goto err;
1536e1051a39Sopenharmony_ci        ret_word = BN_div_word(ret, b_word);
1537e1051a39Sopenharmony_ci        if (ret_word != remainder_word) {
1538e1051a39Sopenharmony_ci#ifdef BN_DEC_FMT1
1539e1051a39Sopenharmony_ci            TEST_error(
1540e1051a39Sopenharmony_ci                    "Got A %% B (word) = " BN_DEC_FMT1 ", wanted " BN_DEC_FMT1,
1541e1051a39Sopenharmony_ci                    ret_word, remainder_word);
1542e1051a39Sopenharmony_ci#else
1543e1051a39Sopenharmony_ci            TEST_error("Got A %% B (word) mismatch");
1544e1051a39Sopenharmony_ci#endif
1545e1051a39Sopenharmony_ci            goto err;
1546e1051a39Sopenharmony_ci        }
1547e1051a39Sopenharmony_ci        if (!equalBN ("A / B (word)", quotient, ret))
1548e1051a39Sopenharmony_ci            goto err;
1549e1051a39Sopenharmony_ci
1550e1051a39Sopenharmony_ci        ret_word = BN_mod_word(a, b_word);
1551e1051a39Sopenharmony_ci        if (ret_word != remainder_word) {
1552e1051a39Sopenharmony_ci#ifdef BN_DEC_FMT1
1553e1051a39Sopenharmony_ci            TEST_error(
1554e1051a39Sopenharmony_ci                    "Got A %% B (word) = " BN_DEC_FMT1 ", wanted " BN_DEC_FMT1 "",
1555e1051a39Sopenharmony_ci                    ret_word, remainder_word);
1556e1051a39Sopenharmony_ci#else
1557e1051a39Sopenharmony_ci            TEST_error("Got A %% B (word) mismatch");
1558e1051a39Sopenharmony_ci#endif
1559e1051a39Sopenharmony_ci            goto err;
1560e1051a39Sopenharmony_ci        }
1561e1051a39Sopenharmony_ci    }
1562e1051a39Sopenharmony_ci
1563e1051a39Sopenharmony_ci    /* Test BN_nnmod. */
1564e1051a39Sopenharmony_ci    if (!BN_is_negative(b)) {
1565e1051a39Sopenharmony_ci        if (!TEST_true(BN_copy(nnmod, remainder))
1566e1051a39Sopenharmony_ci                || (BN_is_negative(nnmod)
1567e1051a39Sopenharmony_ci                        && !TEST_true(BN_add(nnmod, nnmod, b)))
1568e1051a39Sopenharmony_ci                || !TEST_true(BN_nnmod(ret, a, b, ctx))
1569e1051a39Sopenharmony_ci                || !equalBN("A % B (non-negative)", nnmod, ret))
1570e1051a39Sopenharmony_ci            goto err;
1571e1051a39Sopenharmony_ci    }
1572e1051a39Sopenharmony_ci
1573e1051a39Sopenharmony_ci    st = 1;
1574e1051a39Sopenharmony_ci err:
1575e1051a39Sopenharmony_ci    BN_free(a);
1576e1051a39Sopenharmony_ci    BN_free(b);
1577e1051a39Sopenharmony_ci    BN_free(quotient);
1578e1051a39Sopenharmony_ci    BN_free(remainder);
1579e1051a39Sopenharmony_ci    BN_free(ret);
1580e1051a39Sopenharmony_ci    BN_free(ret2);
1581e1051a39Sopenharmony_ci    BN_free(nnmod);
1582e1051a39Sopenharmony_ci    return st;
1583e1051a39Sopenharmony_ci}
1584e1051a39Sopenharmony_ci
1585e1051a39Sopenharmony_cistatic int file_modmul(STANZA *s)
1586e1051a39Sopenharmony_ci{
1587e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *m = NULL, *mod_mul = NULL, *ret = NULL;
1588e1051a39Sopenharmony_ci    int st = 0;
1589e1051a39Sopenharmony_ci
1590e1051a39Sopenharmony_ci    if (!TEST_ptr(a = getBN(s, "A"))
1591e1051a39Sopenharmony_ci            || !TEST_ptr(b = getBN(s, "B"))
1592e1051a39Sopenharmony_ci            || !TEST_ptr(m = getBN(s, "M"))
1593e1051a39Sopenharmony_ci            || !TEST_ptr(mod_mul = getBN(s, "ModMul"))
1594e1051a39Sopenharmony_ci            || !TEST_ptr(ret = BN_new()))
1595e1051a39Sopenharmony_ci        goto err;
1596e1051a39Sopenharmony_ci
1597e1051a39Sopenharmony_ci    if (!TEST_true(BN_mod_mul(ret, a, b, m, ctx))
1598e1051a39Sopenharmony_ci            || !equalBN("A * B (mod M)", mod_mul, ret))
1599e1051a39Sopenharmony_ci        goto err;
1600e1051a39Sopenharmony_ci
1601e1051a39Sopenharmony_ci    if (BN_is_odd(m)) {
1602e1051a39Sopenharmony_ci        /* Reduce |a| and |b| and test the Montgomery version. */
1603e1051a39Sopenharmony_ci        BN_MONT_CTX *mont = BN_MONT_CTX_new();
1604e1051a39Sopenharmony_ci        BIGNUM *a_tmp = BN_new();
1605e1051a39Sopenharmony_ci        BIGNUM *b_tmp = BN_new();
1606e1051a39Sopenharmony_ci
1607e1051a39Sopenharmony_ci        if (mont == NULL || a_tmp == NULL || b_tmp == NULL
1608e1051a39Sopenharmony_ci                || !TEST_true(BN_MONT_CTX_set(mont, m, ctx))
1609e1051a39Sopenharmony_ci                || !TEST_true(BN_nnmod(a_tmp, a, m, ctx))
1610e1051a39Sopenharmony_ci                || !TEST_true(BN_nnmod(b_tmp, b, m, ctx))
1611e1051a39Sopenharmony_ci                || !TEST_true(BN_to_montgomery(a_tmp, a_tmp, mont, ctx))
1612e1051a39Sopenharmony_ci                || !TEST_true(BN_to_montgomery(b_tmp, b_tmp, mont, ctx))
1613e1051a39Sopenharmony_ci                || !TEST_true(BN_mod_mul_montgomery(ret, a_tmp, b_tmp,
1614e1051a39Sopenharmony_ci                                                    mont, ctx))
1615e1051a39Sopenharmony_ci                || !TEST_true(BN_from_montgomery(ret, ret, mont, ctx))
1616e1051a39Sopenharmony_ci                || !equalBN("A * B (mod M) (mont)", mod_mul, ret))
1617e1051a39Sopenharmony_ci            st = 0;
1618e1051a39Sopenharmony_ci        else
1619e1051a39Sopenharmony_ci            st = 1;
1620e1051a39Sopenharmony_ci        BN_MONT_CTX_free(mont);
1621e1051a39Sopenharmony_ci        BN_free(a_tmp);
1622e1051a39Sopenharmony_ci        BN_free(b_tmp);
1623e1051a39Sopenharmony_ci        if (st == 0)
1624e1051a39Sopenharmony_ci            goto err;
1625e1051a39Sopenharmony_ci    }
1626e1051a39Sopenharmony_ci
1627e1051a39Sopenharmony_ci    st = 1;
1628e1051a39Sopenharmony_ci err:
1629e1051a39Sopenharmony_ci    BN_free(a);
1630e1051a39Sopenharmony_ci    BN_free(b);
1631e1051a39Sopenharmony_ci    BN_free(m);
1632e1051a39Sopenharmony_ci    BN_free(mod_mul);
1633e1051a39Sopenharmony_ci    BN_free(ret);
1634e1051a39Sopenharmony_ci    return st;
1635e1051a39Sopenharmony_ci}
1636e1051a39Sopenharmony_ci
1637e1051a39Sopenharmony_cistatic int file_modexp(STANZA *s)
1638e1051a39Sopenharmony_ci{
1639e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *e = NULL, *m = NULL, *mod_exp = NULL, *ret = NULL;
1640e1051a39Sopenharmony_ci    BIGNUM *b = NULL, *c = NULL, *d = NULL;
1641e1051a39Sopenharmony_ci    int st = 0;
1642e1051a39Sopenharmony_ci
1643e1051a39Sopenharmony_ci    if (!TEST_ptr(a = getBN(s, "A"))
1644e1051a39Sopenharmony_ci            || !TEST_ptr(e = getBN(s, "E"))
1645e1051a39Sopenharmony_ci            || !TEST_ptr(m = getBN(s, "M"))
1646e1051a39Sopenharmony_ci            || !TEST_ptr(mod_exp = getBN(s, "ModExp"))
1647e1051a39Sopenharmony_ci            || !TEST_ptr(ret = BN_new())
1648e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new()))
1649e1051a39Sopenharmony_ci        goto err;
1650e1051a39Sopenharmony_ci
1651e1051a39Sopenharmony_ci    if (!TEST_true(BN_mod_exp(ret, a, e, m, ctx))
1652e1051a39Sopenharmony_ci            || !equalBN("A ^ E (mod M)", mod_exp, ret))
1653e1051a39Sopenharmony_ci        goto err;
1654e1051a39Sopenharmony_ci
1655e1051a39Sopenharmony_ci    if (BN_is_odd(m)) {
1656e1051a39Sopenharmony_ci        if (!TEST_true(BN_mod_exp_mont(ret, a, e, m, ctx, NULL))
1657e1051a39Sopenharmony_ci                || !equalBN("A ^ E (mod M) (mont)", mod_exp, ret)
1658e1051a39Sopenharmony_ci                || !TEST_true(BN_mod_exp_mont_consttime(ret, a, e, m,
1659e1051a39Sopenharmony_ci                                                        ctx, NULL))
1660e1051a39Sopenharmony_ci                || !equalBN("A ^ E (mod M) (mont const", mod_exp, ret))
1661e1051a39Sopenharmony_ci            goto err;
1662e1051a39Sopenharmony_ci    }
1663e1051a39Sopenharmony_ci
1664e1051a39Sopenharmony_ci    /* Regression test for carry propagation bug in sqr8x_reduction */
1665e1051a39Sopenharmony_ci    BN_hex2bn(&a, "050505050505");
1666e1051a39Sopenharmony_ci    BN_hex2bn(&b, "02");
1667e1051a39Sopenharmony_ci    BN_hex2bn(&c,
1668e1051a39Sopenharmony_ci        "4141414141414141414141274141414141414141414141414141414141414141"
1669e1051a39Sopenharmony_ci        "4141414141414141414141414141414141414141414141414141414141414141"
1670e1051a39Sopenharmony_ci        "4141414141414141414141800000000000000000000000000000000000000000"
1671e1051a39Sopenharmony_ci        "0000000000000000000000000000000000000000000000000000000000000000"
1672e1051a39Sopenharmony_ci        "0000000000000000000000000000000000000000000000000000000000000000"
1673e1051a39Sopenharmony_ci        "0000000000000000000000000000000000000000000000000000000001");
1674e1051a39Sopenharmony_ci    if (!TEST_true(BN_mod_exp(d, a, b, c, ctx))
1675e1051a39Sopenharmony_ci        || !TEST_true(BN_mul(e, a, a, ctx))
1676e1051a39Sopenharmony_ci        || !TEST_BN_eq(d, e))
1677e1051a39Sopenharmony_ci        goto err;
1678e1051a39Sopenharmony_ci
1679e1051a39Sopenharmony_ci    st = 1;
1680e1051a39Sopenharmony_ci err:
1681e1051a39Sopenharmony_ci    BN_free(a);
1682e1051a39Sopenharmony_ci    BN_free(b);
1683e1051a39Sopenharmony_ci    BN_free(c);
1684e1051a39Sopenharmony_ci    BN_free(d);
1685e1051a39Sopenharmony_ci    BN_free(e);
1686e1051a39Sopenharmony_ci    BN_free(m);
1687e1051a39Sopenharmony_ci    BN_free(mod_exp);
1688e1051a39Sopenharmony_ci    BN_free(ret);
1689e1051a39Sopenharmony_ci    return st;
1690e1051a39Sopenharmony_ci}
1691e1051a39Sopenharmony_ci
1692e1051a39Sopenharmony_cistatic int file_exp(STANZA *s)
1693e1051a39Sopenharmony_ci{
1694e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *e = NULL, *exp = NULL, *ret = NULL;
1695e1051a39Sopenharmony_ci    int st = 0;
1696e1051a39Sopenharmony_ci
1697e1051a39Sopenharmony_ci    if (!TEST_ptr(a = getBN(s, "A"))
1698e1051a39Sopenharmony_ci            || !TEST_ptr(e = getBN(s, "E"))
1699e1051a39Sopenharmony_ci            || !TEST_ptr(exp = getBN(s, "Exp"))
1700e1051a39Sopenharmony_ci            || !TEST_ptr(ret = BN_new()))
1701e1051a39Sopenharmony_ci        goto err;
1702e1051a39Sopenharmony_ci
1703e1051a39Sopenharmony_ci    if (!TEST_true(BN_exp(ret, a, e, ctx))
1704e1051a39Sopenharmony_ci            || !equalBN("A ^ E", exp, ret))
1705e1051a39Sopenharmony_ci        goto err;
1706e1051a39Sopenharmony_ci
1707e1051a39Sopenharmony_ci    st = 1;
1708e1051a39Sopenharmony_ci err:
1709e1051a39Sopenharmony_ci    BN_free(a);
1710e1051a39Sopenharmony_ci    BN_free(e);
1711e1051a39Sopenharmony_ci    BN_free(exp);
1712e1051a39Sopenharmony_ci    BN_free(ret);
1713e1051a39Sopenharmony_ci    return st;
1714e1051a39Sopenharmony_ci}
1715e1051a39Sopenharmony_ci
1716e1051a39Sopenharmony_cistatic int file_modsqrt(STANZA *s)
1717e1051a39Sopenharmony_ci{
1718e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *p = NULL, *mod_sqrt = NULL, *ret = NULL, *ret2 = NULL;
1719e1051a39Sopenharmony_ci    int st = 0;
1720e1051a39Sopenharmony_ci
1721e1051a39Sopenharmony_ci    if (!TEST_ptr(a = getBN(s, "A"))
1722e1051a39Sopenharmony_ci            || !TEST_ptr(p = getBN(s, "P"))
1723e1051a39Sopenharmony_ci            || !TEST_ptr(mod_sqrt = getBN(s, "ModSqrt"))
1724e1051a39Sopenharmony_ci            || !TEST_ptr(ret = BN_new())
1725e1051a39Sopenharmony_ci            || !TEST_ptr(ret2 = BN_new()))
1726e1051a39Sopenharmony_ci        goto err;
1727e1051a39Sopenharmony_ci
1728e1051a39Sopenharmony_ci    if (BN_is_negative(mod_sqrt)) {
1729e1051a39Sopenharmony_ci        /* A negative testcase */
1730e1051a39Sopenharmony_ci        if (!TEST_ptr_null(BN_mod_sqrt(ret, a, p, ctx)))
1731e1051a39Sopenharmony_ci            goto err;
1732e1051a39Sopenharmony_ci
1733e1051a39Sopenharmony_ci        st = 1;
1734e1051a39Sopenharmony_ci        goto err;
1735e1051a39Sopenharmony_ci    }
1736e1051a39Sopenharmony_ci
1737e1051a39Sopenharmony_ci    /* There are two possible answers. */
1738e1051a39Sopenharmony_ci    if (!TEST_ptr(BN_mod_sqrt(ret, a, p, ctx))
1739e1051a39Sopenharmony_ci            || !TEST_true(BN_sub(ret2, p, ret)))
1740e1051a39Sopenharmony_ci        goto err;
1741e1051a39Sopenharmony_ci
1742e1051a39Sopenharmony_ci    /* The first condition should NOT be a test. */
1743e1051a39Sopenharmony_ci    if (BN_cmp(ret2, mod_sqrt) != 0
1744e1051a39Sopenharmony_ci            && !equalBN("sqrt(A) (mod P)", mod_sqrt, ret))
1745e1051a39Sopenharmony_ci        goto err;
1746e1051a39Sopenharmony_ci
1747e1051a39Sopenharmony_ci    st = 1;
1748e1051a39Sopenharmony_ci err:
1749e1051a39Sopenharmony_ci    BN_free(a);
1750e1051a39Sopenharmony_ci    BN_free(p);
1751e1051a39Sopenharmony_ci    BN_free(mod_sqrt);
1752e1051a39Sopenharmony_ci    BN_free(ret);
1753e1051a39Sopenharmony_ci    BN_free(ret2);
1754e1051a39Sopenharmony_ci    return st;
1755e1051a39Sopenharmony_ci}
1756e1051a39Sopenharmony_ci
1757e1051a39Sopenharmony_cistatic int file_gcd(STANZA *s)
1758e1051a39Sopenharmony_ci{
1759e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *gcd = NULL, *ret = NULL;
1760e1051a39Sopenharmony_ci    int st = 0;
1761e1051a39Sopenharmony_ci
1762e1051a39Sopenharmony_ci    if (!TEST_ptr(a = getBN(s, "A"))
1763e1051a39Sopenharmony_ci            || !TEST_ptr(b = getBN(s, "B"))
1764e1051a39Sopenharmony_ci            || !TEST_ptr(gcd = getBN(s, "GCD"))
1765e1051a39Sopenharmony_ci            || !TEST_ptr(ret = BN_new()))
1766e1051a39Sopenharmony_ci        goto err;
1767e1051a39Sopenharmony_ci
1768e1051a39Sopenharmony_ci    if (!TEST_true(BN_gcd(ret, a, b, ctx))
1769e1051a39Sopenharmony_ci            || !equalBN("gcd(A,B)", gcd, ret))
1770e1051a39Sopenharmony_ci        goto err;
1771e1051a39Sopenharmony_ci
1772e1051a39Sopenharmony_ci    st = 1;
1773e1051a39Sopenharmony_ci err:
1774e1051a39Sopenharmony_ci    BN_free(a);
1775e1051a39Sopenharmony_ci    BN_free(b);
1776e1051a39Sopenharmony_ci    BN_free(gcd);
1777e1051a39Sopenharmony_ci    BN_free(ret);
1778e1051a39Sopenharmony_ci    return st;
1779e1051a39Sopenharmony_ci}
1780e1051a39Sopenharmony_ci
1781e1051a39Sopenharmony_cistatic int test_bn2padded(void)
1782e1051a39Sopenharmony_ci{
1783e1051a39Sopenharmony_ci    uint8_t zeros[256], out[256], reference[128];
1784e1051a39Sopenharmony_ci    size_t bytes;
1785e1051a39Sopenharmony_ci    BIGNUM *n;
1786e1051a39Sopenharmony_ci    int st = 0;
1787e1051a39Sopenharmony_ci
1788e1051a39Sopenharmony_ci    /* Test edge case at 0. */
1789e1051a39Sopenharmony_ci    if (!TEST_ptr((n = BN_new())))
1790e1051a39Sopenharmony_ci        goto err;
1791e1051a39Sopenharmony_ci    if (!TEST_int_eq(BN_bn2binpad(n, NULL, 0), 0))
1792e1051a39Sopenharmony_ci        goto err;
1793e1051a39Sopenharmony_ci    memset(out, -1, sizeof(out));
1794e1051a39Sopenharmony_ci    if (!TEST_int_eq(BN_bn2binpad(n, out, sizeof(out)), sizeof(out)))
1795e1051a39Sopenharmony_ci        goto err;
1796e1051a39Sopenharmony_ci    memset(zeros, 0, sizeof(zeros));
1797e1051a39Sopenharmony_ci    if (!TEST_mem_eq(zeros, sizeof(zeros), out, sizeof(out)))
1798e1051a39Sopenharmony_ci        goto err;
1799e1051a39Sopenharmony_ci
1800e1051a39Sopenharmony_ci    /* Test a random numbers at various byte lengths. */
1801e1051a39Sopenharmony_ci    for (bytes = 128 - 7; bytes <= 128; bytes++) {
1802e1051a39Sopenharmony_ci# define TOP_BIT_ON 0
1803e1051a39Sopenharmony_ci# define BOTTOM_BIT_NOTOUCH 0
1804e1051a39Sopenharmony_ci        if (!TEST_true(BN_rand(n, bytes * 8, TOP_BIT_ON, BOTTOM_BIT_NOTOUCH)))
1805e1051a39Sopenharmony_ci            goto err;
1806e1051a39Sopenharmony_ci        if (!TEST_int_eq(BN_num_bytes(n), bytes)
1807e1051a39Sopenharmony_ci                || !TEST_int_eq(BN_bn2bin(n, reference), bytes))
1808e1051a39Sopenharmony_ci            goto err;
1809e1051a39Sopenharmony_ci        /* Empty buffer should fail. */
1810e1051a39Sopenharmony_ci        if (!TEST_int_eq(BN_bn2binpad(n, NULL, 0), -1))
1811e1051a39Sopenharmony_ci            goto err;
1812e1051a39Sopenharmony_ci        /* One byte short should fail. */
1813e1051a39Sopenharmony_ci        if (!TEST_int_eq(BN_bn2binpad(n, out, bytes - 1), -1))
1814e1051a39Sopenharmony_ci            goto err;
1815e1051a39Sopenharmony_ci        /* Exactly right size should encode. */
1816e1051a39Sopenharmony_ci        if (!TEST_int_eq(BN_bn2binpad(n, out, bytes), bytes)
1817e1051a39Sopenharmony_ci                || !TEST_mem_eq(out, bytes, reference, bytes))
1818e1051a39Sopenharmony_ci            goto err;
1819e1051a39Sopenharmony_ci        /* Pad up one byte extra. */
1820e1051a39Sopenharmony_ci        if (!TEST_int_eq(BN_bn2binpad(n, out, bytes + 1), bytes + 1)
1821e1051a39Sopenharmony_ci                || !TEST_mem_eq(out + 1, bytes, reference, bytes)
1822e1051a39Sopenharmony_ci                || !TEST_mem_eq(out, 1, zeros, 1))
1823e1051a39Sopenharmony_ci            goto err;
1824e1051a39Sopenharmony_ci        /* Pad up to 256. */
1825e1051a39Sopenharmony_ci        if (!TEST_int_eq(BN_bn2binpad(n, out, sizeof(out)), sizeof(out))
1826e1051a39Sopenharmony_ci                || !TEST_mem_eq(out + sizeof(out) - bytes, bytes,
1827e1051a39Sopenharmony_ci                                reference, bytes)
1828e1051a39Sopenharmony_ci                || !TEST_mem_eq(out, sizeof(out) - bytes,
1829e1051a39Sopenharmony_ci                                zeros, sizeof(out) - bytes))
1830e1051a39Sopenharmony_ci            goto err;
1831e1051a39Sopenharmony_ci    }
1832e1051a39Sopenharmony_ci
1833e1051a39Sopenharmony_ci    st = 1;
1834e1051a39Sopenharmony_ci err:
1835e1051a39Sopenharmony_ci    BN_free(n);
1836e1051a39Sopenharmony_ci    return st;
1837e1051a39Sopenharmony_ci}
1838e1051a39Sopenharmony_ci
1839e1051a39Sopenharmony_cistatic int test_dec2bn(void)
1840e1051a39Sopenharmony_ci{
1841e1051a39Sopenharmony_ci    BIGNUM *bn = NULL;
1842e1051a39Sopenharmony_ci    int st = 0;
1843e1051a39Sopenharmony_ci
1844e1051a39Sopenharmony_ci    if (!TEST_int_eq(parsedecBN(&bn, "0"), 1)
1845e1051a39Sopenharmony_ci            || !TEST_BN_eq_word(bn, 0)
1846e1051a39Sopenharmony_ci            || !TEST_BN_eq_zero(bn)
1847e1051a39Sopenharmony_ci            || !TEST_BN_le_zero(bn)
1848e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn)
1849e1051a39Sopenharmony_ci            || !TEST_BN_even(bn))
1850e1051a39Sopenharmony_ci        goto err;
1851e1051a39Sopenharmony_ci    BN_free(bn);
1852e1051a39Sopenharmony_ci    bn = NULL;
1853e1051a39Sopenharmony_ci
1854e1051a39Sopenharmony_ci    if (!TEST_int_eq(parsedecBN(&bn, "256"), 3)
1855e1051a39Sopenharmony_ci            || !TEST_BN_eq_word(bn, 256)
1856e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn)
1857e1051a39Sopenharmony_ci            || !TEST_BN_gt_zero(bn)
1858e1051a39Sopenharmony_ci            || !TEST_BN_ne_zero(bn)
1859e1051a39Sopenharmony_ci            || !TEST_BN_even(bn))
1860e1051a39Sopenharmony_ci        goto err;
1861e1051a39Sopenharmony_ci    BN_free(bn);
1862e1051a39Sopenharmony_ci    bn = NULL;
1863e1051a39Sopenharmony_ci
1864e1051a39Sopenharmony_ci    if (!TEST_int_eq(parsedecBN(&bn, "-42"), 3)
1865e1051a39Sopenharmony_ci            || !TEST_BN_abs_eq_word(bn, 42)
1866e1051a39Sopenharmony_ci            || !TEST_BN_lt_zero(bn)
1867e1051a39Sopenharmony_ci            || !TEST_BN_le_zero(bn)
1868e1051a39Sopenharmony_ci            || !TEST_BN_ne_zero(bn)
1869e1051a39Sopenharmony_ci            || !TEST_BN_even(bn))
1870e1051a39Sopenharmony_ci        goto err;
1871e1051a39Sopenharmony_ci    BN_free(bn);
1872e1051a39Sopenharmony_ci    bn = NULL;
1873e1051a39Sopenharmony_ci
1874e1051a39Sopenharmony_ci    if (!TEST_int_eq(parsedecBN(&bn, "1"), 1)
1875e1051a39Sopenharmony_ci            || !TEST_BN_eq_word(bn, 1)
1876e1051a39Sopenharmony_ci            || !TEST_BN_ne_zero(bn)
1877e1051a39Sopenharmony_ci            || !TEST_BN_gt_zero(bn)
1878e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn)
1879e1051a39Sopenharmony_ci            || !TEST_BN_eq_one(bn)
1880e1051a39Sopenharmony_ci            || !TEST_BN_odd(bn))
1881e1051a39Sopenharmony_ci        goto err;
1882e1051a39Sopenharmony_ci    BN_free(bn);
1883e1051a39Sopenharmony_ci    bn = NULL;
1884e1051a39Sopenharmony_ci
1885e1051a39Sopenharmony_ci    if (!TEST_int_eq(parsedecBN(&bn, "-0"), 2)
1886e1051a39Sopenharmony_ci            || !TEST_BN_eq_zero(bn)
1887e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn)
1888e1051a39Sopenharmony_ci            || !TEST_BN_le_zero(bn)
1889e1051a39Sopenharmony_ci            || !TEST_BN_even(bn))
1890e1051a39Sopenharmony_ci        goto err;
1891e1051a39Sopenharmony_ci    BN_free(bn);
1892e1051a39Sopenharmony_ci    bn = NULL;
1893e1051a39Sopenharmony_ci
1894e1051a39Sopenharmony_ci    if (!TEST_int_eq(parsedecBN(&bn, "42trailing garbage is ignored"), 2)
1895e1051a39Sopenharmony_ci            || !TEST_BN_abs_eq_word(bn, 42)
1896e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn)
1897e1051a39Sopenharmony_ci            || !TEST_BN_gt_zero(bn)
1898e1051a39Sopenharmony_ci            || !TEST_BN_ne_zero(bn)
1899e1051a39Sopenharmony_ci            || !TEST_BN_even(bn))
1900e1051a39Sopenharmony_ci        goto err;
1901e1051a39Sopenharmony_ci
1902e1051a39Sopenharmony_ci    st = 1;
1903e1051a39Sopenharmony_ci err:
1904e1051a39Sopenharmony_ci    BN_free(bn);
1905e1051a39Sopenharmony_ci    return st;
1906e1051a39Sopenharmony_ci}
1907e1051a39Sopenharmony_ci
1908e1051a39Sopenharmony_cistatic int test_hex2bn(void)
1909e1051a39Sopenharmony_ci{
1910e1051a39Sopenharmony_ci    BIGNUM *bn = NULL;
1911e1051a39Sopenharmony_ci    int st = 0;
1912e1051a39Sopenharmony_ci
1913e1051a39Sopenharmony_ci    if (!TEST_int_eq(parseBN(&bn, "0"), 1)
1914e1051a39Sopenharmony_ci            || !TEST_BN_eq_zero(bn)
1915e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn)
1916e1051a39Sopenharmony_ci            || !TEST_BN_even(bn))
1917e1051a39Sopenharmony_ci        goto err;
1918e1051a39Sopenharmony_ci    BN_free(bn);
1919e1051a39Sopenharmony_ci    bn = NULL;
1920e1051a39Sopenharmony_ci
1921e1051a39Sopenharmony_ci    if (!TEST_int_eq(parseBN(&bn, "256"), 3)
1922e1051a39Sopenharmony_ci            || !TEST_BN_eq_word(bn, 0x256)
1923e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn)
1924e1051a39Sopenharmony_ci            || !TEST_BN_gt_zero(bn)
1925e1051a39Sopenharmony_ci            || !TEST_BN_ne_zero(bn)
1926e1051a39Sopenharmony_ci            || !TEST_BN_even(bn))
1927e1051a39Sopenharmony_ci        goto err;
1928e1051a39Sopenharmony_ci    BN_free(bn);
1929e1051a39Sopenharmony_ci    bn = NULL;
1930e1051a39Sopenharmony_ci
1931e1051a39Sopenharmony_ci    if (!TEST_int_eq(parseBN(&bn, "-42"), 3)
1932e1051a39Sopenharmony_ci            || !TEST_BN_abs_eq_word(bn, 0x42)
1933e1051a39Sopenharmony_ci            || !TEST_BN_lt_zero(bn)
1934e1051a39Sopenharmony_ci            || !TEST_BN_le_zero(bn)
1935e1051a39Sopenharmony_ci            || !TEST_BN_ne_zero(bn)
1936e1051a39Sopenharmony_ci            || !TEST_BN_even(bn))
1937e1051a39Sopenharmony_ci        goto err;
1938e1051a39Sopenharmony_ci    BN_free(bn);
1939e1051a39Sopenharmony_ci    bn = NULL;
1940e1051a39Sopenharmony_ci
1941e1051a39Sopenharmony_ci    if (!TEST_int_eq(parseBN(&bn, "cb"), 2)
1942e1051a39Sopenharmony_ci            || !TEST_BN_eq_word(bn, 0xCB)
1943e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn)
1944e1051a39Sopenharmony_ci            || !TEST_BN_gt_zero(bn)
1945e1051a39Sopenharmony_ci            || !TEST_BN_ne_zero(bn)
1946e1051a39Sopenharmony_ci            || !TEST_BN_odd(bn))
1947e1051a39Sopenharmony_ci        goto err;
1948e1051a39Sopenharmony_ci    BN_free(bn);
1949e1051a39Sopenharmony_ci    bn = NULL;
1950e1051a39Sopenharmony_ci
1951e1051a39Sopenharmony_ci    if (!TEST_int_eq(parseBN(&bn, "-0"), 2)
1952e1051a39Sopenharmony_ci            || !TEST_BN_eq_zero(bn)
1953e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn)
1954e1051a39Sopenharmony_ci            || !TEST_BN_le_zero(bn)
1955e1051a39Sopenharmony_ci            || !TEST_BN_even(bn))
1956e1051a39Sopenharmony_ci        goto err;
1957e1051a39Sopenharmony_ci    BN_free(bn);
1958e1051a39Sopenharmony_ci    bn = NULL;
1959e1051a39Sopenharmony_ci
1960e1051a39Sopenharmony_ci    if (!TEST_int_eq(parseBN(&bn, "abctrailing garbage is ignored"), 3)
1961e1051a39Sopenharmony_ci            || !TEST_BN_eq_word(bn, 0xabc)
1962e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn)
1963e1051a39Sopenharmony_ci            || !TEST_BN_gt_zero(bn)
1964e1051a39Sopenharmony_ci            || !TEST_BN_ne_zero(bn)
1965e1051a39Sopenharmony_ci            || !TEST_BN_even(bn))
1966e1051a39Sopenharmony_ci        goto err;
1967e1051a39Sopenharmony_ci    st = 1;
1968e1051a39Sopenharmony_ci
1969e1051a39Sopenharmony_ci err:
1970e1051a39Sopenharmony_ci    BN_free(bn);
1971e1051a39Sopenharmony_ci    return st;
1972e1051a39Sopenharmony_ci}
1973e1051a39Sopenharmony_ci
1974e1051a39Sopenharmony_cistatic int test_asc2bn(void)
1975e1051a39Sopenharmony_ci{
1976e1051a39Sopenharmony_ci    BIGNUM *bn = NULL;
1977e1051a39Sopenharmony_ci    int st = 0;
1978e1051a39Sopenharmony_ci
1979e1051a39Sopenharmony_ci    if (!TEST_ptr(bn = BN_new()))
1980e1051a39Sopenharmony_ci        goto err;
1981e1051a39Sopenharmony_ci
1982e1051a39Sopenharmony_ci    if (!TEST_true(BN_asc2bn(&bn, "0"))
1983e1051a39Sopenharmony_ci            || !TEST_BN_eq_zero(bn)
1984e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn))
1985e1051a39Sopenharmony_ci        goto err;
1986e1051a39Sopenharmony_ci
1987e1051a39Sopenharmony_ci    if (!TEST_true(BN_asc2bn(&bn, "256"))
1988e1051a39Sopenharmony_ci            || !TEST_BN_eq_word(bn, 256)
1989e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn))
1990e1051a39Sopenharmony_ci        goto err;
1991e1051a39Sopenharmony_ci
1992e1051a39Sopenharmony_ci    if (!TEST_true(BN_asc2bn(&bn, "-42"))
1993e1051a39Sopenharmony_ci            || !TEST_BN_abs_eq_word(bn, 42)
1994e1051a39Sopenharmony_ci            || !TEST_BN_lt_zero(bn))
1995e1051a39Sopenharmony_ci        goto err;
1996e1051a39Sopenharmony_ci
1997e1051a39Sopenharmony_ci    if (!TEST_true(BN_asc2bn(&bn, "0x1234"))
1998e1051a39Sopenharmony_ci            || !TEST_BN_eq_word(bn, 0x1234)
1999e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn))
2000e1051a39Sopenharmony_ci        goto err;
2001e1051a39Sopenharmony_ci
2002e1051a39Sopenharmony_ci    if (!TEST_true(BN_asc2bn(&bn, "0X1234"))
2003e1051a39Sopenharmony_ci            || !TEST_BN_eq_word(bn, 0x1234)
2004e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn))
2005e1051a39Sopenharmony_ci        goto err;
2006e1051a39Sopenharmony_ci
2007e1051a39Sopenharmony_ci    if (!TEST_true(BN_asc2bn(&bn, "-0xabcd"))
2008e1051a39Sopenharmony_ci            || !TEST_BN_abs_eq_word(bn, 0xabcd)
2009e1051a39Sopenharmony_ci            || !TEST_BN_lt_zero(bn))
2010e1051a39Sopenharmony_ci        goto err;
2011e1051a39Sopenharmony_ci
2012e1051a39Sopenharmony_ci    if (!TEST_true(BN_asc2bn(&bn, "-0"))
2013e1051a39Sopenharmony_ci            || !TEST_BN_eq_zero(bn)
2014e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn))
2015e1051a39Sopenharmony_ci        goto err;
2016e1051a39Sopenharmony_ci
2017e1051a39Sopenharmony_ci    if (!TEST_true(BN_asc2bn(&bn, "123trailing garbage is ignored"))
2018e1051a39Sopenharmony_ci            || !TEST_BN_eq_word(bn, 123)
2019e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(bn))
2020e1051a39Sopenharmony_ci        goto err;
2021e1051a39Sopenharmony_ci
2022e1051a39Sopenharmony_ci    st = 1;
2023e1051a39Sopenharmony_ci err:
2024e1051a39Sopenharmony_ci    BN_free(bn);
2025e1051a39Sopenharmony_ci    return st;
2026e1051a39Sopenharmony_ci}
2027e1051a39Sopenharmony_ci
2028e1051a39Sopenharmony_cistatic const MPITEST kMPITests[] = {
2029e1051a39Sopenharmony_ci    {"0", "\x00\x00\x00\x00", 4},
2030e1051a39Sopenharmony_ci    {"1", "\x00\x00\x00\x01\x01", 5},
2031e1051a39Sopenharmony_ci    {"-1", "\x00\x00\x00\x01\x81", 5},
2032e1051a39Sopenharmony_ci    {"128", "\x00\x00\x00\x02\x00\x80", 6},
2033e1051a39Sopenharmony_ci    {"256", "\x00\x00\x00\x02\x01\x00", 6},
2034e1051a39Sopenharmony_ci    {"-256", "\x00\x00\x00\x02\x81\x00", 6},
2035e1051a39Sopenharmony_ci};
2036e1051a39Sopenharmony_ci
2037e1051a39Sopenharmony_cistatic int test_mpi(int i)
2038e1051a39Sopenharmony_ci{
2039e1051a39Sopenharmony_ci    uint8_t scratch[8];
2040e1051a39Sopenharmony_ci    const MPITEST *test = &kMPITests[i];
2041e1051a39Sopenharmony_ci    size_t mpi_len, mpi_len2;
2042e1051a39Sopenharmony_ci    BIGNUM *bn = NULL;
2043e1051a39Sopenharmony_ci    BIGNUM *bn2 = NULL;
2044e1051a39Sopenharmony_ci    int st = 0;
2045e1051a39Sopenharmony_ci
2046e1051a39Sopenharmony_ci    if (!TEST_ptr(bn = BN_new())
2047e1051a39Sopenharmony_ci            || !TEST_true(BN_asc2bn(&bn, test->base10)))
2048e1051a39Sopenharmony_ci        goto err;
2049e1051a39Sopenharmony_ci    mpi_len = BN_bn2mpi(bn, NULL);
2050e1051a39Sopenharmony_ci    if (!TEST_size_t_le(mpi_len, sizeof(scratch)))
2051e1051a39Sopenharmony_ci        goto err;
2052e1051a39Sopenharmony_ci
2053e1051a39Sopenharmony_ci    if (!TEST_size_t_eq(mpi_len2 = BN_bn2mpi(bn, scratch), mpi_len)
2054e1051a39Sopenharmony_ci            || !TEST_mem_eq(test->mpi, test->mpi_len, scratch, mpi_len))
2055e1051a39Sopenharmony_ci        goto err;
2056e1051a39Sopenharmony_ci
2057e1051a39Sopenharmony_ci    if (!TEST_ptr(bn2 = BN_mpi2bn(scratch, mpi_len, NULL)))
2058e1051a39Sopenharmony_ci        goto err;
2059e1051a39Sopenharmony_ci
2060e1051a39Sopenharmony_ci    if (!TEST_BN_eq(bn, bn2)) {
2061e1051a39Sopenharmony_ci        BN_free(bn2);
2062e1051a39Sopenharmony_ci        goto err;
2063e1051a39Sopenharmony_ci    }
2064e1051a39Sopenharmony_ci    BN_free(bn2);
2065e1051a39Sopenharmony_ci
2066e1051a39Sopenharmony_ci    st = 1;
2067e1051a39Sopenharmony_ci err:
2068e1051a39Sopenharmony_ci    BN_free(bn);
2069e1051a39Sopenharmony_ci    return st;
2070e1051a39Sopenharmony_ci}
2071e1051a39Sopenharmony_ci
2072e1051a39Sopenharmony_cistatic int test_rand(void)
2073e1051a39Sopenharmony_ci{
2074e1051a39Sopenharmony_ci    BIGNUM *bn = NULL;
2075e1051a39Sopenharmony_ci    int st = 0;
2076e1051a39Sopenharmony_ci
2077e1051a39Sopenharmony_ci    if (!TEST_ptr(bn = BN_new()))
2078e1051a39Sopenharmony_ci        return 0;
2079e1051a39Sopenharmony_ci
2080e1051a39Sopenharmony_ci    /* Test BN_rand for degenerate cases with |top| and |bottom| parameters. */
2081e1051a39Sopenharmony_ci    if (!TEST_false(BN_rand(bn, 0, 0 /* top */ , 0 /* bottom */ ))
2082e1051a39Sopenharmony_ci            || !TEST_false(BN_rand(bn, 0, 1 /* top */ , 1 /* bottom */ ))
2083e1051a39Sopenharmony_ci            || !TEST_true(BN_rand(bn, 1, 0 /* top */ , 0 /* bottom */ ))
2084e1051a39Sopenharmony_ci            || !TEST_BN_eq_one(bn)
2085e1051a39Sopenharmony_ci            || !TEST_false(BN_rand(bn, 1, 1 /* top */ , 0 /* bottom */ ))
2086e1051a39Sopenharmony_ci            || !TEST_true(BN_rand(bn, 1, -1 /* top */ , 1 /* bottom */ ))
2087e1051a39Sopenharmony_ci            || !TEST_BN_eq_one(bn)
2088e1051a39Sopenharmony_ci            || !TEST_true(BN_rand(bn, 2, 1 /* top */ , 0 /* bottom */ ))
2089e1051a39Sopenharmony_ci            || !TEST_BN_eq_word(bn, 3))
2090e1051a39Sopenharmony_ci        goto err;
2091e1051a39Sopenharmony_ci
2092e1051a39Sopenharmony_ci    st = 1;
2093e1051a39Sopenharmony_ci err:
2094e1051a39Sopenharmony_ci    BN_free(bn);
2095e1051a39Sopenharmony_ci    return st;
2096e1051a39Sopenharmony_ci}
2097e1051a39Sopenharmony_ci
2098e1051a39Sopenharmony_ci/*
2099e1051a39Sopenharmony_ci * Run some statistical tests to provide a degree confidence that the
2100e1051a39Sopenharmony_ci * BN_rand_range() function works as expected.  The test cases and
2101e1051a39Sopenharmony_ci * critical values are generated by the bn_rand_range script.
2102e1051a39Sopenharmony_ci *
2103e1051a39Sopenharmony_ci * Each individual test is a Chi^2 goodness of fit for a specified number
2104e1051a39Sopenharmony_ci * of samples and range.  The samples are assumed to be independent and
2105e1051a39Sopenharmony_ci * that they are from a discrete uniform distribution.
2106e1051a39Sopenharmony_ci *
2107e1051a39Sopenharmony_ci * Some of these individual tests are expected to fail, the success/failure
2108e1051a39Sopenharmony_ci * of each is an independent Bernoulli trial.  The number of such successes
2109e1051a39Sopenharmony_ci * will form a binomial distribution.  The count of the successes is compared
2110e1051a39Sopenharmony_ci * against a precomputed critical value to determine the overall outcome.
2111e1051a39Sopenharmony_ci */
2112e1051a39Sopenharmony_cistruct rand_range_case {
2113e1051a39Sopenharmony_ci    unsigned int range;
2114e1051a39Sopenharmony_ci    unsigned int iterations;
2115e1051a39Sopenharmony_ci    double critical;
2116e1051a39Sopenharmony_ci};
2117e1051a39Sopenharmony_ci
2118e1051a39Sopenharmony_ci#include "bn_rand_range.h"
2119e1051a39Sopenharmony_ci
2120e1051a39Sopenharmony_cistatic int test_rand_range_single(size_t n)
2121e1051a39Sopenharmony_ci{
2122e1051a39Sopenharmony_ci    const unsigned int range = rand_range_cases[n].range;
2123e1051a39Sopenharmony_ci    const unsigned int iterations = rand_range_cases[n].iterations;
2124e1051a39Sopenharmony_ci    const double critical = rand_range_cases[n].critical;
2125e1051a39Sopenharmony_ci    const double expected = iterations / (double)range;
2126e1051a39Sopenharmony_ci    double sum = 0;
2127e1051a39Sopenharmony_ci    BIGNUM *rng = NULL, *val = NULL;
2128e1051a39Sopenharmony_ci    size_t *counts;
2129e1051a39Sopenharmony_ci    unsigned int i, v;
2130e1051a39Sopenharmony_ci    int res = 0;
2131e1051a39Sopenharmony_ci
2132e1051a39Sopenharmony_ci    if (!TEST_ptr(counts = OPENSSL_zalloc(sizeof(*counts) * range))
2133e1051a39Sopenharmony_ci        || !TEST_ptr(rng = BN_new())
2134e1051a39Sopenharmony_ci        || !TEST_ptr(val = BN_new())
2135e1051a39Sopenharmony_ci        || !TEST_true(BN_set_word(rng, range)))
2136e1051a39Sopenharmony_ci        goto err;
2137e1051a39Sopenharmony_ci    for (i = 0; i < iterations; i++) {
2138e1051a39Sopenharmony_ci        if (!TEST_true(BN_rand_range(val, rng))
2139e1051a39Sopenharmony_ci            || !TEST_uint_lt(v = (unsigned int)BN_get_word(val), range))
2140e1051a39Sopenharmony_ci            goto err;
2141e1051a39Sopenharmony_ci        counts[v]++;
2142e1051a39Sopenharmony_ci    }
2143e1051a39Sopenharmony_ci
2144e1051a39Sopenharmony_ci    for (i = 0; i < range; i++) {
2145e1051a39Sopenharmony_ci        const double delta = counts[i] - expected;
2146e1051a39Sopenharmony_ci        sum += delta * delta;
2147e1051a39Sopenharmony_ci    }
2148e1051a39Sopenharmony_ci    sum /= expected;
2149e1051a39Sopenharmony_ci
2150e1051a39Sopenharmony_ci    if (sum > critical) {
2151e1051a39Sopenharmony_ci        TEST_info("Chi^2 test negative %.4f > %4.f", sum, critical);
2152e1051a39Sopenharmony_ci        TEST_note("test case %zu  range %u  iterations %u", n + 1, range,
2153e1051a39Sopenharmony_ci                  iterations);
2154e1051a39Sopenharmony_ci        goto err;
2155e1051a39Sopenharmony_ci    }
2156e1051a39Sopenharmony_ci
2157e1051a39Sopenharmony_ci    res = 1;
2158e1051a39Sopenharmony_cierr:
2159e1051a39Sopenharmony_ci    BN_free(rng);
2160e1051a39Sopenharmony_ci    BN_free(val);
2161e1051a39Sopenharmony_ci    OPENSSL_free(counts);
2162e1051a39Sopenharmony_ci    return res;
2163e1051a39Sopenharmony_ci}
2164e1051a39Sopenharmony_ci
2165e1051a39Sopenharmony_cistatic int test_rand_range(void)
2166e1051a39Sopenharmony_ci{
2167e1051a39Sopenharmony_ci    int n_success = 0;
2168e1051a39Sopenharmony_ci    size_t i;
2169e1051a39Sopenharmony_ci
2170e1051a39Sopenharmony_ci    for (i = 0; i < OSSL_NELEM(rand_range_cases); i++)
2171e1051a39Sopenharmony_ci        n_success += test_rand_range_single(i);
2172e1051a39Sopenharmony_ci    if (TEST_int_ge(n_success, binomial_critical))
2173e1051a39Sopenharmony_ci        return 1;
2174e1051a39Sopenharmony_ci    TEST_note("This test is expected to fail by chance 0.01%% of the time.");
2175e1051a39Sopenharmony_ci    return 0;
2176e1051a39Sopenharmony_ci}
2177e1051a39Sopenharmony_ci
2178e1051a39Sopenharmony_cistatic int test_negzero(void)
2179e1051a39Sopenharmony_ci{
2180e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL;
2181e1051a39Sopenharmony_ci    BIGNUM *numerator = NULL, *denominator = NULL;
2182e1051a39Sopenharmony_ci    int consttime, st = 0;
2183e1051a39Sopenharmony_ci
2184e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
2185e1051a39Sopenharmony_ci            || !TEST_ptr(b = BN_new())
2186e1051a39Sopenharmony_ci            || !TEST_ptr(c = BN_new())
2187e1051a39Sopenharmony_ci            || !TEST_ptr(d = BN_new()))
2188e1051a39Sopenharmony_ci        goto err;
2189e1051a39Sopenharmony_ci
2190e1051a39Sopenharmony_ci    /* Test that BN_mul never gives negative zero. */
2191e1051a39Sopenharmony_ci    if (!TEST_true(BN_set_word(a, 1)))
2192e1051a39Sopenharmony_ci        goto err;
2193e1051a39Sopenharmony_ci    BN_set_negative(a, 1);
2194e1051a39Sopenharmony_ci    BN_zero(b);
2195e1051a39Sopenharmony_ci    if (!TEST_true(BN_mul(c, a, b, ctx)))
2196e1051a39Sopenharmony_ci        goto err;
2197e1051a39Sopenharmony_ci    if (!TEST_BN_eq_zero(c)
2198e1051a39Sopenharmony_ci            || !TEST_BN_ge_zero(c))
2199e1051a39Sopenharmony_ci        goto err;
2200e1051a39Sopenharmony_ci
2201e1051a39Sopenharmony_ci    for (consttime = 0; consttime < 2; consttime++) {
2202e1051a39Sopenharmony_ci        if (!TEST_ptr(numerator = BN_new())
2203e1051a39Sopenharmony_ci                || !TEST_ptr(denominator = BN_new()))
2204e1051a39Sopenharmony_ci            goto err;
2205e1051a39Sopenharmony_ci        if (consttime) {
2206e1051a39Sopenharmony_ci            BN_set_flags(numerator, BN_FLG_CONSTTIME);
2207e1051a39Sopenharmony_ci            BN_set_flags(denominator, BN_FLG_CONSTTIME);
2208e1051a39Sopenharmony_ci        }
2209e1051a39Sopenharmony_ci        /* Test that BN_div never gives negative zero in the quotient. */
2210e1051a39Sopenharmony_ci        if (!TEST_true(BN_set_word(numerator, 1))
2211e1051a39Sopenharmony_ci                || !TEST_true(BN_set_word(denominator, 2)))
2212e1051a39Sopenharmony_ci            goto err;
2213e1051a39Sopenharmony_ci        BN_set_negative(numerator, 1);
2214e1051a39Sopenharmony_ci        if (!TEST_true(BN_div(a, b, numerator, denominator, ctx))
2215e1051a39Sopenharmony_ci                || !TEST_BN_eq_zero(a)
2216e1051a39Sopenharmony_ci                || !TEST_BN_ge_zero(a))
2217e1051a39Sopenharmony_ci            goto err;
2218e1051a39Sopenharmony_ci
2219e1051a39Sopenharmony_ci        /* Test that BN_div never gives negative zero in the remainder. */
2220e1051a39Sopenharmony_ci        if (!TEST_true(BN_set_word(denominator, 1))
2221e1051a39Sopenharmony_ci                || !TEST_true(BN_div(a, b, numerator, denominator, ctx))
2222e1051a39Sopenharmony_ci                || !TEST_BN_eq_zero(b)
2223e1051a39Sopenharmony_ci                || !TEST_BN_ge_zero(b))
2224e1051a39Sopenharmony_ci            goto err;
2225e1051a39Sopenharmony_ci        BN_free(numerator);
2226e1051a39Sopenharmony_ci        BN_free(denominator);
2227e1051a39Sopenharmony_ci        numerator = denominator = NULL;
2228e1051a39Sopenharmony_ci    }
2229e1051a39Sopenharmony_ci
2230e1051a39Sopenharmony_ci    /* Test that BN_set_negative will not produce a negative zero. */
2231e1051a39Sopenharmony_ci    BN_zero(a);
2232e1051a39Sopenharmony_ci    BN_set_negative(a, 1);
2233e1051a39Sopenharmony_ci    if (BN_is_negative(a))
2234e1051a39Sopenharmony_ci        goto err;
2235e1051a39Sopenharmony_ci    st = 1;
2236e1051a39Sopenharmony_ci
2237e1051a39Sopenharmony_ci err:
2238e1051a39Sopenharmony_ci    BN_free(a);
2239e1051a39Sopenharmony_ci    BN_free(b);
2240e1051a39Sopenharmony_ci    BN_free(c);
2241e1051a39Sopenharmony_ci    BN_free(d);
2242e1051a39Sopenharmony_ci    BN_free(numerator);
2243e1051a39Sopenharmony_ci    BN_free(denominator);
2244e1051a39Sopenharmony_ci    return st;
2245e1051a39Sopenharmony_ci}
2246e1051a39Sopenharmony_ci
2247e1051a39Sopenharmony_cistatic int test_badmod(void)
2248e1051a39Sopenharmony_ci{
2249e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *zero = NULL;
2250e1051a39Sopenharmony_ci    BN_MONT_CTX *mont = NULL;
2251e1051a39Sopenharmony_ci    int st = 0;
2252e1051a39Sopenharmony_ci
2253e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
2254e1051a39Sopenharmony_ci            || !TEST_ptr(b = BN_new())
2255e1051a39Sopenharmony_ci            || !TEST_ptr(zero = BN_new())
2256e1051a39Sopenharmony_ci            || !TEST_ptr(mont = BN_MONT_CTX_new()))
2257e1051a39Sopenharmony_ci        goto err;
2258e1051a39Sopenharmony_ci    BN_zero(zero);
2259e1051a39Sopenharmony_ci
2260e1051a39Sopenharmony_ci    if (!TEST_false(BN_div(a, b, BN_value_one(), zero, ctx)))
2261e1051a39Sopenharmony_ci        goto err;
2262e1051a39Sopenharmony_ci    ERR_clear_error();
2263e1051a39Sopenharmony_ci
2264e1051a39Sopenharmony_ci    if (!TEST_false(BN_mod_mul(a, BN_value_one(), BN_value_one(), zero, ctx)))
2265e1051a39Sopenharmony_ci        goto err;
2266e1051a39Sopenharmony_ci    ERR_clear_error();
2267e1051a39Sopenharmony_ci
2268e1051a39Sopenharmony_ci    if (!TEST_false(BN_mod_exp(a, BN_value_one(), BN_value_one(), zero, ctx)))
2269e1051a39Sopenharmony_ci        goto err;
2270e1051a39Sopenharmony_ci    ERR_clear_error();
2271e1051a39Sopenharmony_ci
2272e1051a39Sopenharmony_ci    if (!TEST_false(BN_mod_exp_mont(a, BN_value_one(), BN_value_one(),
2273e1051a39Sopenharmony_ci                                    zero, ctx, NULL)))
2274e1051a39Sopenharmony_ci        goto err;
2275e1051a39Sopenharmony_ci    ERR_clear_error();
2276e1051a39Sopenharmony_ci
2277e1051a39Sopenharmony_ci    if (!TEST_false(BN_mod_exp_mont_consttime(a, BN_value_one(), BN_value_one(),
2278e1051a39Sopenharmony_ci                                              zero, ctx, NULL)))
2279e1051a39Sopenharmony_ci        goto err;
2280e1051a39Sopenharmony_ci    ERR_clear_error();
2281e1051a39Sopenharmony_ci
2282e1051a39Sopenharmony_ci    if (!TEST_false(BN_MONT_CTX_set(mont, zero, ctx)))
2283e1051a39Sopenharmony_ci        goto err;
2284e1051a39Sopenharmony_ci    ERR_clear_error();
2285e1051a39Sopenharmony_ci
2286e1051a39Sopenharmony_ci    /* Some operations also may not be used with an even modulus. */
2287e1051a39Sopenharmony_ci    if (!TEST_true(BN_set_word(b, 16)))
2288e1051a39Sopenharmony_ci        goto err;
2289e1051a39Sopenharmony_ci
2290e1051a39Sopenharmony_ci    if (!TEST_false(BN_MONT_CTX_set(mont, b, ctx)))
2291e1051a39Sopenharmony_ci        goto err;
2292e1051a39Sopenharmony_ci    ERR_clear_error();
2293e1051a39Sopenharmony_ci
2294e1051a39Sopenharmony_ci    if (!TEST_false(BN_mod_exp_mont(a, BN_value_one(), BN_value_one(),
2295e1051a39Sopenharmony_ci                                    b, ctx, NULL)))
2296e1051a39Sopenharmony_ci        goto err;
2297e1051a39Sopenharmony_ci    ERR_clear_error();
2298e1051a39Sopenharmony_ci
2299e1051a39Sopenharmony_ci    if (!TEST_false(BN_mod_exp_mont_consttime(a, BN_value_one(), BN_value_one(),
2300e1051a39Sopenharmony_ci                                              b, ctx, NULL)))
2301e1051a39Sopenharmony_ci        goto err;
2302e1051a39Sopenharmony_ci    ERR_clear_error();
2303e1051a39Sopenharmony_ci
2304e1051a39Sopenharmony_ci    st = 1;
2305e1051a39Sopenharmony_ci err:
2306e1051a39Sopenharmony_ci    BN_free(a);
2307e1051a39Sopenharmony_ci    BN_free(b);
2308e1051a39Sopenharmony_ci    BN_free(zero);
2309e1051a39Sopenharmony_ci    BN_MONT_CTX_free(mont);
2310e1051a39Sopenharmony_ci    return st;
2311e1051a39Sopenharmony_ci}
2312e1051a39Sopenharmony_ci
2313e1051a39Sopenharmony_cistatic int test_expmodzero(void)
2314e1051a39Sopenharmony_ci{
2315e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *r = NULL, *zero = NULL;
2316e1051a39Sopenharmony_ci    int st = 0;
2317e1051a39Sopenharmony_ci
2318e1051a39Sopenharmony_ci    if (!TEST_ptr(zero = BN_new())
2319e1051a39Sopenharmony_ci            || !TEST_ptr(a = BN_new())
2320e1051a39Sopenharmony_ci            || !TEST_ptr(r = BN_new()))
2321e1051a39Sopenharmony_ci        goto err;
2322e1051a39Sopenharmony_ci    BN_zero(zero);
2323e1051a39Sopenharmony_ci
2324e1051a39Sopenharmony_ci    if (!TEST_true(BN_mod_exp(r, a, zero, BN_value_one(), NULL))
2325e1051a39Sopenharmony_ci            || !TEST_BN_eq_zero(r)
2326e1051a39Sopenharmony_ci            || !TEST_true(BN_mod_exp_mont(r, a, zero, BN_value_one(),
2327e1051a39Sopenharmony_ci                                          NULL, NULL))
2328e1051a39Sopenharmony_ci            || !TEST_BN_eq_zero(r)
2329e1051a39Sopenharmony_ci            || !TEST_true(BN_mod_exp_mont_consttime(r, a, zero,
2330e1051a39Sopenharmony_ci                                                    BN_value_one(),
2331e1051a39Sopenharmony_ci                                                    NULL, NULL))
2332e1051a39Sopenharmony_ci            || !TEST_BN_eq_zero(r)
2333e1051a39Sopenharmony_ci            || !TEST_true(BN_mod_exp_mont_word(r, 42, zero,
2334e1051a39Sopenharmony_ci                                               BN_value_one(), NULL, NULL))
2335e1051a39Sopenharmony_ci            || !TEST_BN_eq_zero(r))
2336e1051a39Sopenharmony_ci        goto err;
2337e1051a39Sopenharmony_ci
2338e1051a39Sopenharmony_ci    st = 1;
2339e1051a39Sopenharmony_ci err:
2340e1051a39Sopenharmony_ci    BN_free(zero);
2341e1051a39Sopenharmony_ci    BN_free(a);
2342e1051a39Sopenharmony_ci    BN_free(r);
2343e1051a39Sopenharmony_ci    return st;
2344e1051a39Sopenharmony_ci}
2345e1051a39Sopenharmony_ci
2346e1051a39Sopenharmony_cistatic int test_expmodone(void)
2347e1051a39Sopenharmony_ci{
2348e1051a39Sopenharmony_ci    int ret = 0, i;
2349e1051a39Sopenharmony_ci    BIGNUM *r = BN_new();
2350e1051a39Sopenharmony_ci    BIGNUM *a = BN_new();
2351e1051a39Sopenharmony_ci    BIGNUM *p = BN_new();
2352e1051a39Sopenharmony_ci    BIGNUM *m = BN_new();
2353e1051a39Sopenharmony_ci
2354e1051a39Sopenharmony_ci    if (!TEST_ptr(r)
2355e1051a39Sopenharmony_ci            || !TEST_ptr(a)
2356e1051a39Sopenharmony_ci            || !TEST_ptr(p)
2357e1051a39Sopenharmony_ci            || !TEST_ptr(p)
2358e1051a39Sopenharmony_ci            || !TEST_ptr(m)
2359e1051a39Sopenharmony_ci            || !TEST_true(BN_set_word(a, 1))
2360e1051a39Sopenharmony_ci            || !TEST_true(BN_set_word(p, 0))
2361e1051a39Sopenharmony_ci            || !TEST_true(BN_set_word(m, 1)))
2362e1051a39Sopenharmony_ci        goto err;
2363e1051a39Sopenharmony_ci
2364e1051a39Sopenharmony_ci    /* Calculate r = 1 ^ 0 mod 1, and check the result is always 0 */
2365e1051a39Sopenharmony_ci    for (i = 0; i < 2; i++) {
2366e1051a39Sopenharmony_ci        if (!TEST_true(BN_mod_exp(r, a, p, m, NULL))
2367e1051a39Sopenharmony_ci                || !TEST_BN_eq_zero(r)
2368e1051a39Sopenharmony_ci                || !TEST_true(BN_mod_exp_mont(r, a, p, m, NULL, NULL))
2369e1051a39Sopenharmony_ci                || !TEST_BN_eq_zero(r)
2370e1051a39Sopenharmony_ci                || !TEST_true(BN_mod_exp_mont_consttime(r, a, p, m, NULL, NULL))
2371e1051a39Sopenharmony_ci                || !TEST_BN_eq_zero(r)
2372e1051a39Sopenharmony_ci                || !TEST_true(BN_mod_exp_mont_word(r, 1, p, m, NULL, NULL))
2373e1051a39Sopenharmony_ci                || !TEST_BN_eq_zero(r)
2374e1051a39Sopenharmony_ci                || !TEST_true(BN_mod_exp_simple(r, a, p, m, NULL))
2375e1051a39Sopenharmony_ci                || !TEST_BN_eq_zero(r)
2376e1051a39Sopenharmony_ci                || !TEST_true(BN_mod_exp_recp(r, a, p, m, NULL))
2377e1051a39Sopenharmony_ci                || !TEST_BN_eq_zero(r))
2378e1051a39Sopenharmony_ci            goto err;
2379e1051a39Sopenharmony_ci        /* Repeat for r = 1 ^ 0 mod -1 */
2380e1051a39Sopenharmony_ci        if (i == 0)
2381e1051a39Sopenharmony_ci            BN_set_negative(m, 1);
2382e1051a39Sopenharmony_ci    }
2383e1051a39Sopenharmony_ci
2384e1051a39Sopenharmony_ci    ret = 1;
2385e1051a39Sopenharmony_ci err:
2386e1051a39Sopenharmony_ci    BN_free(r);
2387e1051a39Sopenharmony_ci    BN_free(a);
2388e1051a39Sopenharmony_ci    BN_free(p);
2389e1051a39Sopenharmony_ci    BN_free(m);
2390e1051a39Sopenharmony_ci    return ret;
2391e1051a39Sopenharmony_ci}
2392e1051a39Sopenharmony_ci
2393e1051a39Sopenharmony_cistatic int test_smallprime(int kBits)
2394e1051a39Sopenharmony_ci{
2395e1051a39Sopenharmony_ci    BIGNUM *r;
2396e1051a39Sopenharmony_ci    int st = 0;
2397e1051a39Sopenharmony_ci
2398e1051a39Sopenharmony_ci    if (!TEST_ptr(r = BN_new()))
2399e1051a39Sopenharmony_ci        goto err;
2400e1051a39Sopenharmony_ci
2401e1051a39Sopenharmony_ci    if (kBits <= 1) {
2402e1051a39Sopenharmony_ci        if (!TEST_false(BN_generate_prime_ex(r, kBits, 0,
2403e1051a39Sopenharmony_ci                                             NULL, NULL, NULL)))
2404e1051a39Sopenharmony_ci            goto err;
2405e1051a39Sopenharmony_ci    } else {
2406e1051a39Sopenharmony_ci        if (!TEST_true(BN_generate_prime_ex(r, kBits, 0,
2407e1051a39Sopenharmony_ci                                            NULL, NULL, NULL))
2408e1051a39Sopenharmony_ci                || !TEST_int_eq(BN_num_bits(r), kBits))
2409e1051a39Sopenharmony_ci            goto err;
2410e1051a39Sopenharmony_ci    }
2411e1051a39Sopenharmony_ci
2412e1051a39Sopenharmony_ci    st = 1;
2413e1051a39Sopenharmony_ci err:
2414e1051a39Sopenharmony_ci    BN_free(r);
2415e1051a39Sopenharmony_ci    return st;
2416e1051a39Sopenharmony_ci}
2417e1051a39Sopenharmony_ci
2418e1051a39Sopenharmony_cistatic int test_smallsafeprime(int kBits)
2419e1051a39Sopenharmony_ci{
2420e1051a39Sopenharmony_ci    BIGNUM *r;
2421e1051a39Sopenharmony_ci    int st = 0;
2422e1051a39Sopenharmony_ci
2423e1051a39Sopenharmony_ci    if (!TEST_ptr(r = BN_new()))
2424e1051a39Sopenharmony_ci        goto err;
2425e1051a39Sopenharmony_ci
2426e1051a39Sopenharmony_ci    if (kBits <= 5 && kBits != 3) {
2427e1051a39Sopenharmony_ci        if (!TEST_false(BN_generate_prime_ex(r, kBits, 1,
2428e1051a39Sopenharmony_ci                                             NULL, NULL, NULL)))
2429e1051a39Sopenharmony_ci            goto err;
2430e1051a39Sopenharmony_ci    } else {
2431e1051a39Sopenharmony_ci        if (!TEST_true(BN_generate_prime_ex(r, kBits, 1,
2432e1051a39Sopenharmony_ci                                            NULL, NULL, NULL))
2433e1051a39Sopenharmony_ci                || !TEST_int_eq(BN_num_bits(r), kBits))
2434e1051a39Sopenharmony_ci            goto err;
2435e1051a39Sopenharmony_ci    }
2436e1051a39Sopenharmony_ci
2437e1051a39Sopenharmony_ci    st = 1;
2438e1051a39Sopenharmony_ci err:
2439e1051a39Sopenharmony_ci    BN_free(r);
2440e1051a39Sopenharmony_ci    return st;
2441e1051a39Sopenharmony_ci}
2442e1051a39Sopenharmony_ci
2443e1051a39Sopenharmony_cistatic int primes[] = { 2, 3, 5, 7, 17863 };
2444e1051a39Sopenharmony_ci
2445e1051a39Sopenharmony_cistatic int test_is_prime(int i)
2446e1051a39Sopenharmony_ci{
2447e1051a39Sopenharmony_ci    int ret = 0;
2448e1051a39Sopenharmony_ci    BIGNUM *r = NULL;
2449e1051a39Sopenharmony_ci    int trial;
2450e1051a39Sopenharmony_ci
2451e1051a39Sopenharmony_ci    if (!TEST_ptr(r = BN_new()))
2452e1051a39Sopenharmony_ci        goto err;
2453e1051a39Sopenharmony_ci
2454e1051a39Sopenharmony_ci    for (trial = 0; trial <= 1; ++trial) {
2455e1051a39Sopenharmony_ci        if (!TEST_true(BN_set_word(r, primes[i]))
2456e1051a39Sopenharmony_ci                || !TEST_int_eq(BN_check_prime(r, ctx, NULL),
2457e1051a39Sopenharmony_ci                                1))
2458e1051a39Sopenharmony_ci            goto err;
2459e1051a39Sopenharmony_ci    }
2460e1051a39Sopenharmony_ci
2461e1051a39Sopenharmony_ci    ret = 1;
2462e1051a39Sopenharmony_ci err:
2463e1051a39Sopenharmony_ci    BN_free(r);
2464e1051a39Sopenharmony_ci    return ret;
2465e1051a39Sopenharmony_ci}
2466e1051a39Sopenharmony_ci
2467e1051a39Sopenharmony_cistatic int not_primes[] = { -1, 0, 1, 4 };
2468e1051a39Sopenharmony_ci
2469e1051a39Sopenharmony_cistatic int test_not_prime(int i)
2470e1051a39Sopenharmony_ci{
2471e1051a39Sopenharmony_ci    int ret = 0;
2472e1051a39Sopenharmony_ci    BIGNUM *r = NULL;
2473e1051a39Sopenharmony_ci    int trial;
2474e1051a39Sopenharmony_ci
2475e1051a39Sopenharmony_ci    if (!TEST_ptr(r = BN_new()))
2476e1051a39Sopenharmony_ci        goto err;
2477e1051a39Sopenharmony_ci
2478e1051a39Sopenharmony_ci    for (trial = 0; trial <= 1; ++trial) {
2479e1051a39Sopenharmony_ci        if (!TEST_true(BN_set_word(r, not_primes[i]))
2480e1051a39Sopenharmony_ci                || !TEST_false(BN_check_prime(r, ctx, NULL)))
2481e1051a39Sopenharmony_ci            goto err;
2482e1051a39Sopenharmony_ci    }
2483e1051a39Sopenharmony_ci
2484e1051a39Sopenharmony_ci    ret = 1;
2485e1051a39Sopenharmony_ci err:
2486e1051a39Sopenharmony_ci    BN_free(r);
2487e1051a39Sopenharmony_ci    return ret;
2488e1051a39Sopenharmony_ci}
2489e1051a39Sopenharmony_ci
2490e1051a39Sopenharmony_cistatic int test_ctx_set_ct_flag(BN_CTX *c)
2491e1051a39Sopenharmony_ci{
2492e1051a39Sopenharmony_ci    int st = 0;
2493e1051a39Sopenharmony_ci    size_t i;
2494e1051a39Sopenharmony_ci    BIGNUM *b[15];
2495e1051a39Sopenharmony_ci
2496e1051a39Sopenharmony_ci    BN_CTX_start(c);
2497e1051a39Sopenharmony_ci    for (i = 0; i < OSSL_NELEM(b); i++) {
2498e1051a39Sopenharmony_ci        if (!TEST_ptr(b[i] = BN_CTX_get(c)))
2499e1051a39Sopenharmony_ci            goto err;
2500e1051a39Sopenharmony_ci        if (i % 2 == 1)
2501e1051a39Sopenharmony_ci            BN_set_flags(b[i], BN_FLG_CONSTTIME);
2502e1051a39Sopenharmony_ci    }
2503e1051a39Sopenharmony_ci
2504e1051a39Sopenharmony_ci    st = 1;
2505e1051a39Sopenharmony_ci err:
2506e1051a39Sopenharmony_ci    BN_CTX_end(c);
2507e1051a39Sopenharmony_ci    return st;
2508e1051a39Sopenharmony_ci}
2509e1051a39Sopenharmony_ci
2510e1051a39Sopenharmony_cistatic int test_ctx_check_ct_flag(BN_CTX *c)
2511e1051a39Sopenharmony_ci{
2512e1051a39Sopenharmony_ci    int st = 0;
2513e1051a39Sopenharmony_ci    size_t i;
2514e1051a39Sopenharmony_ci    BIGNUM *b[30];
2515e1051a39Sopenharmony_ci
2516e1051a39Sopenharmony_ci    BN_CTX_start(c);
2517e1051a39Sopenharmony_ci    for (i = 0; i < OSSL_NELEM(b); i++) {
2518e1051a39Sopenharmony_ci        if (!TEST_ptr(b[i] = BN_CTX_get(c)))
2519e1051a39Sopenharmony_ci            goto err;
2520e1051a39Sopenharmony_ci        if (!TEST_false(BN_get_flags(b[i], BN_FLG_CONSTTIME)))
2521e1051a39Sopenharmony_ci            goto err;
2522e1051a39Sopenharmony_ci    }
2523e1051a39Sopenharmony_ci
2524e1051a39Sopenharmony_ci    st = 1;
2525e1051a39Sopenharmony_ci err:
2526e1051a39Sopenharmony_ci    BN_CTX_end(c);
2527e1051a39Sopenharmony_ci    return st;
2528e1051a39Sopenharmony_ci}
2529e1051a39Sopenharmony_ci
2530e1051a39Sopenharmony_cistatic int test_ctx_consttime_flag(void)
2531e1051a39Sopenharmony_ci{
2532e1051a39Sopenharmony_ci    /*-
2533e1051a39Sopenharmony_ci     * The constant-time flag should not "leak" among BN_CTX frames:
2534e1051a39Sopenharmony_ci     *
2535e1051a39Sopenharmony_ci     * - test_ctx_set_ct_flag() starts a frame in the given BN_CTX and
2536e1051a39Sopenharmony_ci     *   sets the BN_FLG_CONSTTIME flag on some of the BIGNUMs obtained
2537e1051a39Sopenharmony_ci     *   from the frame before ending it.
2538e1051a39Sopenharmony_ci     * - test_ctx_check_ct_flag() then starts a new frame and gets a
2539e1051a39Sopenharmony_ci     *   number of BIGNUMs from it. In absence of leaks, none of the
2540e1051a39Sopenharmony_ci     *   BIGNUMs in the new frame should have BN_FLG_CONSTTIME set.
2541e1051a39Sopenharmony_ci     *
2542e1051a39Sopenharmony_ci     * In actual BN_CTX usage inside libcrypto the leak could happen at
2543e1051a39Sopenharmony_ci     * any depth level in the BN_CTX stack, with varying results
2544e1051a39Sopenharmony_ci     * depending on the patterns of sibling trees of nested function
2545e1051a39Sopenharmony_ci     * calls sharing the same BN_CTX object, and the effect of
2546e1051a39Sopenharmony_ci     * unintended BN_FLG_CONSTTIME on the called BN_* functions.
2547e1051a39Sopenharmony_ci     *
2548e1051a39Sopenharmony_ci     * This simple unit test abstracts away this complexity and verifies
2549e1051a39Sopenharmony_ci     * that the leak does not happen between two sibling functions
2550e1051a39Sopenharmony_ci     * sharing the same BN_CTX object at the same level of nesting.
2551e1051a39Sopenharmony_ci     *
2552e1051a39Sopenharmony_ci     */
2553e1051a39Sopenharmony_ci    BN_CTX *nctx = NULL;
2554e1051a39Sopenharmony_ci    BN_CTX *sctx = NULL;
2555e1051a39Sopenharmony_ci    size_t i = 0;
2556e1051a39Sopenharmony_ci    int st = 0;
2557e1051a39Sopenharmony_ci
2558e1051a39Sopenharmony_ci    if (!TEST_ptr(nctx = BN_CTX_new())
2559e1051a39Sopenharmony_ci            || !TEST_ptr(sctx = BN_CTX_secure_new()))
2560e1051a39Sopenharmony_ci        goto err;
2561e1051a39Sopenharmony_ci
2562e1051a39Sopenharmony_ci    for (i = 0; i < 2; i++) {
2563e1051a39Sopenharmony_ci        BN_CTX *c = i == 0 ? nctx : sctx;
2564e1051a39Sopenharmony_ci        if (!TEST_true(test_ctx_set_ct_flag(c))
2565e1051a39Sopenharmony_ci                || !TEST_true(test_ctx_check_ct_flag(c)))
2566e1051a39Sopenharmony_ci            goto err;
2567e1051a39Sopenharmony_ci    }
2568e1051a39Sopenharmony_ci
2569e1051a39Sopenharmony_ci    st = 1;
2570e1051a39Sopenharmony_ci err:
2571e1051a39Sopenharmony_ci    BN_CTX_free(nctx);
2572e1051a39Sopenharmony_ci    BN_CTX_free(sctx);
2573e1051a39Sopenharmony_ci    return st;
2574e1051a39Sopenharmony_ci}
2575e1051a39Sopenharmony_ci
2576e1051a39Sopenharmony_cistatic int test_gcd_prime(void)
2577e1051a39Sopenharmony_ci{
2578e1051a39Sopenharmony_ci    BIGNUM *a = NULL, *b = NULL, *gcd = NULL;
2579e1051a39Sopenharmony_ci    int i, st = 0;
2580e1051a39Sopenharmony_ci
2581e1051a39Sopenharmony_ci    if (!TEST_ptr(a = BN_new())
2582e1051a39Sopenharmony_ci            || !TEST_ptr(b = BN_new())
2583e1051a39Sopenharmony_ci            || !TEST_ptr(gcd = BN_new()))
2584e1051a39Sopenharmony_ci        goto err;
2585e1051a39Sopenharmony_ci
2586e1051a39Sopenharmony_ci    if (!TEST_true(BN_generate_prime_ex(a, 1024, 0, NULL, NULL, NULL)))
2587e1051a39Sopenharmony_ci            goto err;
2588e1051a39Sopenharmony_ci    for (i = 0; i < NUM0; i++) {
2589e1051a39Sopenharmony_ci        if (!TEST_true(BN_generate_prime_ex(b, 1024, 0,
2590e1051a39Sopenharmony_ci                                            NULL, NULL, NULL))
2591e1051a39Sopenharmony_ci                || !TEST_true(BN_gcd(gcd, a, b, ctx))
2592e1051a39Sopenharmony_ci                || !TEST_true(BN_is_one(gcd)))
2593e1051a39Sopenharmony_ci            goto err;
2594e1051a39Sopenharmony_ci    }
2595e1051a39Sopenharmony_ci
2596e1051a39Sopenharmony_ci    st = 1;
2597e1051a39Sopenharmony_ci err:
2598e1051a39Sopenharmony_ci    BN_free(a);
2599e1051a39Sopenharmony_ci    BN_free(b);
2600e1051a39Sopenharmony_ci    BN_free(gcd);
2601e1051a39Sopenharmony_ci    return st;
2602e1051a39Sopenharmony_ci}
2603e1051a39Sopenharmony_ci
2604e1051a39Sopenharmony_citypedef struct mod_exp_test_st
2605e1051a39Sopenharmony_ci{
2606e1051a39Sopenharmony_ci  const char *base;
2607e1051a39Sopenharmony_ci  const char *exp;
2608e1051a39Sopenharmony_ci  const char *mod;
2609e1051a39Sopenharmony_ci  const char *res;
2610e1051a39Sopenharmony_ci} MOD_EXP_TEST;
2611e1051a39Sopenharmony_ci
2612e1051a39Sopenharmony_cistatic const MOD_EXP_TEST ModExpTests[] = {
2613e1051a39Sopenharmony_ci   /* original test vectors for rsaz_512_sqr bug, by OSS-Fuzz */
2614e1051a39Sopenharmony_ci   {
2615e1051a39Sopenharmony_ci       "1166180238001879113042182292626169621106255558914000595999312084"
2616e1051a39Sopenharmony_ci       "4627946820899490684928760491249738643524880720584249698100907201"
2617e1051a39Sopenharmony_ci       "002086675047927600340800371",
2618e1051a39Sopenharmony_ci       "8000000000000000000000000000000000000000000000000000000000000000"
2619e1051a39Sopenharmony_ci       "0000000000000000000000000000000000000000000000000000000000000000"
2620e1051a39Sopenharmony_ci       "00000000",
2621e1051a39Sopenharmony_ci       "1340780792684523720980737645613191762604395855615117867483316354"
2622e1051a39Sopenharmony_ci       "3294276330515137663421134775482798690129946803802212663956180562"
2623e1051a39Sopenharmony_ci       "088664022929883876655300863",
2624e1051a39Sopenharmony_ci       "8243904058268085430037326628480645845409758077568738532059032482"
2625e1051a39Sopenharmony_ci       "8294114415890603594730158120426756266457928475330450251339773498"
2626e1051a39Sopenharmony_ci       "26758407619521544102068438"
2627e1051a39Sopenharmony_ci   },
2628e1051a39Sopenharmony_ci   {
2629e1051a39Sopenharmony_ci       "4974270041410803822078866696159586946995877618987010219312844726"
2630e1051a39Sopenharmony_ci       "0284386121835740784990869050050504348861513337232530490826340663"
2631e1051a39Sopenharmony_ci       "197278031692737429054",
2632e1051a39Sopenharmony_ci       "4974270041410803822078866696159586946995877428188754995041148539"
2633e1051a39Sopenharmony_ci       "1663243362592271353668158565195557417149981094324650322556843202"
2634e1051a39Sopenharmony_ci       "946445882670777892608",
2635e1051a39Sopenharmony_ci       "1340780716511420227215592830971452482815377482627251725537099028"
2636e1051a39Sopenharmony_ci       "4429769497230131760206012644403029349547320953206103351725462999"
2637e1051a39Sopenharmony_ci       "947509743623340557059752191",
2638e1051a39Sopenharmony_ci       "5296244594780707015616522701706118082963369547253192207884519362"
2639e1051a39Sopenharmony_ci       "1767869984947542695665420219028522815539559194793619684334900442"
2640e1051a39Sopenharmony_ci       "49304558011362360473525933"
2641e1051a39Sopenharmony_ci   },
2642e1051a39Sopenharmony_ci   /* test vectors for rsaz_512_srq bug, with rcx/rbx=1 */
2643e1051a39Sopenharmony_ci   {   /* between first and second iteration */
2644e1051a39Sopenharmony_ci       "5148719036160389201525610950887605325980251964889646556085286545"
2645e1051a39Sopenharmony_ci       "3931548809178823413169359635978762036512397113080988070677858033"
2646e1051a39Sopenharmony_ci       "36463909753993540214027190",
2647e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2648e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2649e1051a39Sopenharmony_ci       "05973284973216824503042158",
2650e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2651e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2652e1051a39Sopenharmony_ci       "05973284973216824503042159",
2653e1051a39Sopenharmony_ci       "1"
2654e1051a39Sopenharmony_ci   },
2655e1051a39Sopenharmony_ci   {   /* between second and third iteration */
2656e1051a39Sopenharmony_ci       "8908340854353752577419678771330460827942371434853054158622636544"
2657e1051a39Sopenharmony_ci       "8151360109722890949471912566649465436296659601091730745087014189"
2658e1051a39Sopenharmony_ci       "2672764191218875181826063",
2659e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2660e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2661e1051a39Sopenharmony_ci       "05973284973216824503042158",
2662e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2663e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2664e1051a39Sopenharmony_ci       "05973284973216824503042159",
2665e1051a39Sopenharmony_ci       "1"
2666e1051a39Sopenharmony_ci   },
2667e1051a39Sopenharmony_ci   {   /* between third and fourth iteration */
2668e1051a39Sopenharmony_ci       "3427446396505596330634350984901719674479522569002785244080234738"
2669e1051a39Sopenharmony_ci       "4288743635435746136297299366444548736533053717416735379073185344"
2670e1051a39Sopenharmony_ci       "26985272974404612945608761",
2671e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2672e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2673e1051a39Sopenharmony_ci       "05973284973216824503042158",
2674e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2675e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2676e1051a39Sopenharmony_ci       "05973284973216824503042159",
2677e1051a39Sopenharmony_ci       "1"
2678e1051a39Sopenharmony_ci   },
2679e1051a39Sopenharmony_ci   {   /* between fourth and fifth iteration */
2680e1051a39Sopenharmony_ci       "3472743044917564564078857826111874560045331237315597383869652985"
2681e1051a39Sopenharmony_ci       "6919870028890895988478351133601517365908445058405433832718206902"
2682e1051a39Sopenharmony_ci       "4088133164805266956353542",
2683e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2684e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2685e1051a39Sopenharmony_ci       "05973284973216824503042158",
2686e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2687e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2688e1051a39Sopenharmony_ci       "05973284973216824503042159",
2689e1051a39Sopenharmony_ci       "1"
2690e1051a39Sopenharmony_ci   },
2691e1051a39Sopenharmony_ci   {   /* between fifth and sixth iteration */
2692e1051a39Sopenharmony_ci       "3608632990153469264412378349742339216742409743898601587274768025"
2693e1051a39Sopenharmony_ci       "0110772032985643555192767717344946174122842255204082586753499651"
2694e1051a39Sopenharmony_ci       "14483434992887431333675068",
2695e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2696e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2697e1051a39Sopenharmony_ci       "05973284973216824503042158",
2698e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2699e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2700e1051a39Sopenharmony_ci       "05973284973216824503042159",
2701e1051a39Sopenharmony_ci       "1"
2702e1051a39Sopenharmony_ci   },
2703e1051a39Sopenharmony_ci   {   /* between sixth and seventh iteration */
2704e1051a39Sopenharmony_ci       "8455374370234070242910508226941981520235709767260723212165264877"
2705e1051a39Sopenharmony_ci       "8689064388017521524568434328264431772644802567028663962962025746"
2706e1051a39Sopenharmony_ci       "9283458217850119569539086",
2707e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2708e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2709e1051a39Sopenharmony_ci       "05973284973216824503042158",
2710e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2711e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2712e1051a39Sopenharmony_ci       "05973284973216824503042159",
2713e1051a39Sopenharmony_ci       "1"
2714e1051a39Sopenharmony_ci   },
2715e1051a39Sopenharmony_ci   {   /* between seventh and eighth iteration */
2716e1051a39Sopenharmony_ci       "5155371529688532178421209781159131443543419764974688878527112131"
2717e1051a39Sopenharmony_ci       "7446518205609427412336183157918981038066636807317733319323257603"
2718e1051a39Sopenharmony_ci       "04416292040754017461076359",
2719e1051a39Sopenharmony_ci       "1005585594745694782468051874865438459560952436544429503329267108"
2720e1051a39Sopenharmony_ci       "2791323022555160232601405723625177570767523893639864538140315412"
2721e1051a39Sopenharmony_ci       "108959927459825236754563832",
2722e1051a39Sopenharmony_ci       "1005585594745694782468051874865438459560952436544429503329267108"
2723e1051a39Sopenharmony_ci       "2791323022555160232601405723625177570767523893639864538140315412"
2724e1051a39Sopenharmony_ci       "108959927459825236754563833",
2725e1051a39Sopenharmony_ci       "1"
2726e1051a39Sopenharmony_ci   },
2727e1051a39Sopenharmony_ci   /* test vectors for rsaz_512_srq bug, with rcx/rbx=2 */
2728e1051a39Sopenharmony_ci   {   /* between first and second iteration */
2729e1051a39Sopenharmony_ci       "3155666506033786929967309937640790361084670559125912405342594979"
2730e1051a39Sopenharmony_ci       "4345142818528956285490897841406338022378565972533508820577760065"
2731e1051a39Sopenharmony_ci       "58494345853302083699912572",
2732e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2733e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2734e1051a39Sopenharmony_ci       "05973284973216824503042158",
2735e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2736e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2737e1051a39Sopenharmony_ci       "05973284973216824503042159",
2738e1051a39Sopenharmony_ci       "1"
2739e1051a39Sopenharmony_ci   },
2740e1051a39Sopenharmony_ci   {   /* between second and third iteration */
2741e1051a39Sopenharmony_ci       "3789819583801342198190405714582958759005991915505282362397087750"
2742e1051a39Sopenharmony_ci       "4213544724644823098843135685133927198668818185338794377239590049"
2743e1051a39Sopenharmony_ci       "41019388529192775771488319",
2744e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2745e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2746e1051a39Sopenharmony_ci       "05973284973216824503042158",
2747e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2748e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2749e1051a39Sopenharmony_ci       "05973284973216824503042159",
2750e1051a39Sopenharmony_ci       "1"
2751e1051a39Sopenharmony_ci   },
2752e1051a39Sopenharmony_ci   {   /* between third and forth iteration */
2753e1051a39Sopenharmony_ci       "4695752552040706867080542538786056470322165281761525158189220280"
2754e1051a39Sopenharmony_ci       "4025547447667484759200742764246905647644662050122968912279199065"
2755e1051a39Sopenharmony_ci       "48065034299166336940507214",
2756e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2757e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2758e1051a39Sopenharmony_ci       "05973284973216824503042158",
2759e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2760e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2761e1051a39Sopenharmony_ci       "05973284973216824503042159",
2762e1051a39Sopenharmony_ci       "1"
2763e1051a39Sopenharmony_ci   },
2764e1051a39Sopenharmony_ci   {   /* between forth and fifth iteration */
2765e1051a39Sopenharmony_ci       "2159140240970485794188159431017382878636879856244045329971239574"
2766e1051a39Sopenharmony_ci       "8919691133560661162828034323196457386059819832804593989740268964"
2767e1051a39Sopenharmony_ci       "74502911811812651475927076",
2768e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2769e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2770e1051a39Sopenharmony_ci       "05973284973216824503042158",
2771e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2772e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2773e1051a39Sopenharmony_ci       "05973284973216824503042159",
2774e1051a39Sopenharmony_ci       "1"
2775e1051a39Sopenharmony_ci   },
2776e1051a39Sopenharmony_ci   {   /* between fifth and sixth iteration */
2777e1051a39Sopenharmony_ci       "5239312332984325668414624633307915097111691815000872662334695514"
2778e1051a39Sopenharmony_ci       "5436533521392362443557163429336808208137221322444780490437871903"
2779e1051a39Sopenharmony_ci       "99972784701334569424519255",
2780e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2781e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2782e1051a39Sopenharmony_ci       "05973284973216824503042158",
2783e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2784e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2785e1051a39Sopenharmony_ci       "05973284973216824503042159",
2786e1051a39Sopenharmony_ci       "1"
2787e1051a39Sopenharmony_ci   },
2788e1051a39Sopenharmony_ci   {   /* between sixth and seventh iteration */
2789e1051a39Sopenharmony_ci       "1977953647322612860406858017869125467496941904523063466791308891"
2790e1051a39Sopenharmony_ci       "1172796739058531929470539758361774569875505293428856181093904091"
2791e1051a39Sopenharmony_ci       "33788264851714311303725089",
2792e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2793e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2794e1051a39Sopenharmony_ci       "05973284973216824503042158",
2795e1051a39Sopenharmony_ci       "6703903964971298549787012499102923063739682910296196688861780721"
2796e1051a39Sopenharmony_ci       "8608820150367734884009371490834517138450159290932430254268769414"
2797e1051a39Sopenharmony_ci       "05973284973216824503042159",
2798e1051a39Sopenharmony_ci       "1"
2799e1051a39Sopenharmony_ci   },
2800e1051a39Sopenharmony_ci   {   /* between seventh and eighth iteration */
2801e1051a39Sopenharmony_ci       "6456987954117763835533395796948878140715006860263624787492985786"
2802e1051a39Sopenharmony_ci       "8514630216966738305923915688821526449499763719943997120302368211"
2803e1051a39Sopenharmony_ci       "04813318117996225041943964",
2804e1051a39Sopenharmony_ci       "1340780792994259709957402499820584612747936582059239337772356144"
2805e1051a39Sopenharmony_ci       "3721764030073546976801874298166903427690031858186486050853753882"
2806e1051a39Sopenharmony_ci       "811946551499689575296532556",
2807e1051a39Sopenharmony_ci       "1340780792994259709957402499820584612747936582059239337772356144"
2808e1051a39Sopenharmony_ci       "3721764030073546976801874298166903427690031858186486050853753882"
2809e1051a39Sopenharmony_ci       "811946551499689575296532557",
2810e1051a39Sopenharmony_ci       "1"
2811e1051a39Sopenharmony_ci   }
2812e1051a39Sopenharmony_ci};
2813e1051a39Sopenharmony_ci
2814e1051a39Sopenharmony_cistatic int test_mod_exp(int i)
2815e1051a39Sopenharmony_ci{
2816e1051a39Sopenharmony_ci    const MOD_EXP_TEST *test = &ModExpTests[i];
2817e1051a39Sopenharmony_ci    int res = 0;
2818e1051a39Sopenharmony_ci    BIGNUM* result = NULL;
2819e1051a39Sopenharmony_ci    BIGNUM *base = NULL, *exponent = NULL, *modulo = NULL;
2820e1051a39Sopenharmony_ci    char *s = NULL;
2821e1051a39Sopenharmony_ci
2822e1051a39Sopenharmony_ci    if (!TEST_ptr(result = BN_new())
2823e1051a39Sopenharmony_ci            || !TEST_true(BN_dec2bn(&base, test->base))
2824e1051a39Sopenharmony_ci            || !TEST_true(BN_dec2bn(&exponent, test->exp))
2825e1051a39Sopenharmony_ci            || !TEST_true(BN_dec2bn(&modulo, test->mod)))
2826e1051a39Sopenharmony_ci        goto err;
2827e1051a39Sopenharmony_ci
2828e1051a39Sopenharmony_ci    if (!TEST_int_eq(BN_mod_exp(result, base, exponent, modulo, ctx), 1))
2829e1051a39Sopenharmony_ci        goto err;
2830e1051a39Sopenharmony_ci
2831e1051a39Sopenharmony_ci    if (!TEST_ptr(s = BN_bn2dec(result)))
2832e1051a39Sopenharmony_ci        goto err;
2833e1051a39Sopenharmony_ci
2834e1051a39Sopenharmony_ci    if (!TEST_mem_eq(s, strlen(s), test->res, strlen(test->res)))
2835e1051a39Sopenharmony_ci        goto err;
2836e1051a39Sopenharmony_ci
2837e1051a39Sopenharmony_ci    res = 1;
2838e1051a39Sopenharmony_ci
2839e1051a39Sopenharmony_ci err:
2840e1051a39Sopenharmony_ci    OPENSSL_free(s);
2841e1051a39Sopenharmony_ci    BN_free(result);
2842e1051a39Sopenharmony_ci    BN_free(base);
2843e1051a39Sopenharmony_ci    BN_free(exponent);
2844e1051a39Sopenharmony_ci    BN_free(modulo);
2845e1051a39Sopenharmony_ci    return res;
2846e1051a39Sopenharmony_ci}
2847e1051a39Sopenharmony_ci
2848e1051a39Sopenharmony_cistatic int test_mod_exp_consttime(int i)
2849e1051a39Sopenharmony_ci{
2850e1051a39Sopenharmony_ci    const MOD_EXP_TEST *test = &ModExpTests[i];
2851e1051a39Sopenharmony_ci    int res = 0;
2852e1051a39Sopenharmony_ci    BIGNUM* result = NULL;
2853e1051a39Sopenharmony_ci    BIGNUM *base = NULL, *exponent = NULL, *modulo = NULL;
2854e1051a39Sopenharmony_ci    char *s = NULL;
2855e1051a39Sopenharmony_ci
2856e1051a39Sopenharmony_ci    if (!TEST_ptr(result = BN_new())
2857e1051a39Sopenharmony_ci            || !TEST_true(BN_dec2bn(&base, test->base))
2858e1051a39Sopenharmony_ci            || !TEST_true(BN_dec2bn(&exponent, test->exp))
2859e1051a39Sopenharmony_ci            || !TEST_true(BN_dec2bn(&modulo, test->mod)))
2860e1051a39Sopenharmony_ci        goto err;
2861e1051a39Sopenharmony_ci
2862e1051a39Sopenharmony_ci    BN_set_flags(base, BN_FLG_CONSTTIME);
2863e1051a39Sopenharmony_ci    BN_set_flags(exponent, BN_FLG_CONSTTIME);
2864e1051a39Sopenharmony_ci    BN_set_flags(modulo, BN_FLG_CONSTTIME);
2865e1051a39Sopenharmony_ci
2866e1051a39Sopenharmony_ci    if (!TEST_int_eq(BN_mod_exp(result, base, exponent, modulo, ctx), 1))
2867e1051a39Sopenharmony_ci        goto err;
2868e1051a39Sopenharmony_ci
2869e1051a39Sopenharmony_ci    if (!TEST_ptr(s = BN_bn2dec(result)))
2870e1051a39Sopenharmony_ci        goto err;
2871e1051a39Sopenharmony_ci
2872e1051a39Sopenharmony_ci    if (!TEST_mem_eq(s, strlen(s), test->res, strlen(test->res)))
2873e1051a39Sopenharmony_ci        goto err;
2874e1051a39Sopenharmony_ci
2875e1051a39Sopenharmony_ci    res = 1;
2876e1051a39Sopenharmony_ci
2877e1051a39Sopenharmony_ci err:
2878e1051a39Sopenharmony_ci    OPENSSL_free(s);
2879e1051a39Sopenharmony_ci    BN_free(result);
2880e1051a39Sopenharmony_ci    BN_free(base);
2881e1051a39Sopenharmony_ci    BN_free(exponent);
2882e1051a39Sopenharmony_ci    BN_free(modulo);
2883e1051a39Sopenharmony_ci    return res;
2884e1051a39Sopenharmony_ci}
2885e1051a39Sopenharmony_ci
2886e1051a39Sopenharmony_ci/*
2887e1051a39Sopenharmony_ci * Regression test to ensure BN_mod_exp2_mont fails safely if argument m is
2888e1051a39Sopenharmony_ci * zero.
2889e1051a39Sopenharmony_ci */
2890e1051a39Sopenharmony_cistatic int test_mod_exp2_mont(void)
2891e1051a39Sopenharmony_ci{
2892e1051a39Sopenharmony_ci    int res = 0;
2893e1051a39Sopenharmony_ci    BIGNUM *exp_result = NULL;
2894e1051a39Sopenharmony_ci    BIGNUM *exp_a1 = NULL, *exp_p1 = NULL, *exp_a2 = NULL, *exp_p2 = NULL,
2895e1051a39Sopenharmony_ci           *exp_m = NULL;
2896e1051a39Sopenharmony_ci
2897e1051a39Sopenharmony_ci    if (!TEST_ptr(exp_result = BN_new())
2898e1051a39Sopenharmony_ci            || !TEST_ptr(exp_a1 = BN_new())
2899e1051a39Sopenharmony_ci            || !TEST_ptr(exp_p1 = BN_new())
2900e1051a39Sopenharmony_ci            || !TEST_ptr(exp_a2 = BN_new())
2901e1051a39Sopenharmony_ci            || !TEST_ptr(exp_p2 = BN_new())
2902e1051a39Sopenharmony_ci            || !TEST_ptr(exp_m = BN_new()))
2903e1051a39Sopenharmony_ci        goto err;
2904e1051a39Sopenharmony_ci
2905e1051a39Sopenharmony_ci    if (!TEST_true(BN_one(exp_a1))
2906e1051a39Sopenharmony_ci            || !TEST_true(BN_one(exp_p1))
2907e1051a39Sopenharmony_ci            || !TEST_true(BN_one(exp_a2))
2908e1051a39Sopenharmony_ci            || !TEST_true(BN_one(exp_p2)))
2909e1051a39Sopenharmony_ci        goto err;
2910e1051a39Sopenharmony_ci
2911e1051a39Sopenharmony_ci    BN_zero(exp_m);
2912e1051a39Sopenharmony_ci
2913e1051a39Sopenharmony_ci    /* input of 0 is even, so must fail */
2914e1051a39Sopenharmony_ci    if (!TEST_int_eq(BN_mod_exp2_mont(exp_result, exp_a1, exp_p1, exp_a2,
2915e1051a39Sopenharmony_ci                exp_p2, exp_m, ctx, NULL), 0))
2916e1051a39Sopenharmony_ci        goto err;
2917e1051a39Sopenharmony_ci
2918e1051a39Sopenharmony_ci    res = 1;
2919e1051a39Sopenharmony_ci
2920e1051a39Sopenharmony_cierr:
2921e1051a39Sopenharmony_ci    BN_free(exp_result);
2922e1051a39Sopenharmony_ci    BN_free(exp_a1);
2923e1051a39Sopenharmony_ci    BN_free(exp_p1);
2924e1051a39Sopenharmony_ci    BN_free(exp_a2);
2925e1051a39Sopenharmony_ci    BN_free(exp_p2);
2926e1051a39Sopenharmony_ci    BN_free(exp_m);
2927e1051a39Sopenharmony_ci    return res;
2928e1051a39Sopenharmony_ci}
2929e1051a39Sopenharmony_ci
2930e1051a39Sopenharmony_cistatic int file_test_run(STANZA *s)
2931e1051a39Sopenharmony_ci{
2932e1051a39Sopenharmony_ci    static const FILETEST filetests[] = {
2933e1051a39Sopenharmony_ci        {"Sum", file_sum},
2934e1051a39Sopenharmony_ci        {"LShift1", file_lshift1},
2935e1051a39Sopenharmony_ci        {"LShift", file_lshift},
2936e1051a39Sopenharmony_ci        {"RShift", file_rshift},
2937e1051a39Sopenharmony_ci        {"Square", file_square},
2938e1051a39Sopenharmony_ci        {"Product", file_product},
2939e1051a39Sopenharmony_ci        {"Quotient", file_quotient},
2940e1051a39Sopenharmony_ci        {"ModMul", file_modmul},
2941e1051a39Sopenharmony_ci        {"ModExp", file_modexp},
2942e1051a39Sopenharmony_ci        {"Exp", file_exp},
2943e1051a39Sopenharmony_ci        {"ModSqrt", file_modsqrt},
2944e1051a39Sopenharmony_ci        {"GCD", file_gcd},
2945e1051a39Sopenharmony_ci    };
2946e1051a39Sopenharmony_ci    int numtests = OSSL_NELEM(filetests);
2947e1051a39Sopenharmony_ci    const FILETEST *tp = filetests;
2948e1051a39Sopenharmony_ci
2949e1051a39Sopenharmony_ci    for ( ; --numtests >= 0; tp++) {
2950e1051a39Sopenharmony_ci        if (findattr(s, tp->name) != NULL) {
2951e1051a39Sopenharmony_ci            if (!tp->func(s)) {
2952e1051a39Sopenharmony_ci                TEST_info("%s:%d: Failed %s test",
2953e1051a39Sopenharmony_ci                          s->test_file, s->start, tp->name);
2954e1051a39Sopenharmony_ci                return 0;
2955e1051a39Sopenharmony_ci            }
2956e1051a39Sopenharmony_ci            return 1;
2957e1051a39Sopenharmony_ci        }
2958e1051a39Sopenharmony_ci    }
2959e1051a39Sopenharmony_ci    TEST_info("%s:%d: Unknown test", s->test_file, s->start);
2960e1051a39Sopenharmony_ci    return 0;
2961e1051a39Sopenharmony_ci}
2962e1051a39Sopenharmony_ci
2963e1051a39Sopenharmony_cistatic int run_file_tests(int i)
2964e1051a39Sopenharmony_ci{
2965e1051a39Sopenharmony_ci    STANZA *s = NULL;
2966e1051a39Sopenharmony_ci    char *testfile = test_get_argument(i);
2967e1051a39Sopenharmony_ci    int c;
2968e1051a39Sopenharmony_ci
2969e1051a39Sopenharmony_ci    if (!TEST_ptr(s = OPENSSL_zalloc(sizeof(*s))))
2970e1051a39Sopenharmony_ci        return 0;
2971e1051a39Sopenharmony_ci    if (!test_start_file(s, testfile)) {
2972e1051a39Sopenharmony_ci        OPENSSL_free(s);
2973e1051a39Sopenharmony_ci        return 0;
2974e1051a39Sopenharmony_ci    }
2975e1051a39Sopenharmony_ci
2976e1051a39Sopenharmony_ci    /* Read test file. */
2977e1051a39Sopenharmony_ci    while (!BIO_eof(s->fp) && test_readstanza(s)) {
2978e1051a39Sopenharmony_ci        if (s->numpairs == 0)
2979e1051a39Sopenharmony_ci            continue;
2980e1051a39Sopenharmony_ci        if (!file_test_run(s))
2981e1051a39Sopenharmony_ci            s->errors++;
2982e1051a39Sopenharmony_ci        s->numtests++;
2983e1051a39Sopenharmony_ci        test_clearstanza(s);
2984e1051a39Sopenharmony_ci    }
2985e1051a39Sopenharmony_ci    test_end_file(s);
2986e1051a39Sopenharmony_ci    c = s->errors;
2987e1051a39Sopenharmony_ci    OPENSSL_free(s);
2988e1051a39Sopenharmony_ci
2989e1051a39Sopenharmony_ci    return c == 0;
2990e1051a39Sopenharmony_ci}
2991e1051a39Sopenharmony_ci
2992e1051a39Sopenharmony_citypedef enum OPTION_choice {
2993e1051a39Sopenharmony_ci    OPT_ERR = -1,
2994e1051a39Sopenharmony_ci    OPT_EOF = 0,
2995e1051a39Sopenharmony_ci    OPT_STOCHASTIC_TESTS,
2996e1051a39Sopenharmony_ci    OPT_TEST_ENUM
2997e1051a39Sopenharmony_ci} OPTION_CHOICE;
2998e1051a39Sopenharmony_ci
2999e1051a39Sopenharmony_ciconst OPTIONS *test_get_options(void)
3000e1051a39Sopenharmony_ci{
3001e1051a39Sopenharmony_ci    static const OPTIONS test_options[] = {
3002e1051a39Sopenharmony_ci        OPT_TEST_OPTIONS_WITH_EXTRA_USAGE("[file...]\n"),
3003e1051a39Sopenharmony_ci        { "stochastic", OPT_STOCHASTIC_TESTS, '-', "Run stochastic tests" },
3004e1051a39Sopenharmony_ci        { OPT_HELP_STR, 1, '-',
3005e1051a39Sopenharmony_ci          "file\tFile to run tests on. Normal tests are not run\n" },
3006e1051a39Sopenharmony_ci        { NULL }
3007e1051a39Sopenharmony_ci    };
3008e1051a39Sopenharmony_ci    return test_options;
3009e1051a39Sopenharmony_ci}
3010e1051a39Sopenharmony_ci
3011e1051a39Sopenharmony_ciint setup_tests(void)
3012e1051a39Sopenharmony_ci{
3013e1051a39Sopenharmony_ci    OPTION_CHOICE o;
3014e1051a39Sopenharmony_ci    int n, stochastic = 0;
3015e1051a39Sopenharmony_ci
3016e1051a39Sopenharmony_ci    while ((o = opt_next()) != OPT_EOF) {
3017e1051a39Sopenharmony_ci        switch (o) {
3018e1051a39Sopenharmony_ci        case OPT_STOCHASTIC_TESTS:
3019e1051a39Sopenharmony_ci            stochastic = 1;
3020e1051a39Sopenharmony_ci            break;
3021e1051a39Sopenharmony_ci        case OPT_TEST_CASES:
3022e1051a39Sopenharmony_ci           break;
3023e1051a39Sopenharmony_ci        default:
3024e1051a39Sopenharmony_ci        case OPT_ERR:
3025e1051a39Sopenharmony_ci            return 0;
3026e1051a39Sopenharmony_ci        }
3027e1051a39Sopenharmony_ci    }
3028e1051a39Sopenharmony_ci    n  = test_get_argument_count();
3029e1051a39Sopenharmony_ci
3030e1051a39Sopenharmony_ci    if (!TEST_ptr(ctx = BN_CTX_new()))
3031e1051a39Sopenharmony_ci        return 0;
3032e1051a39Sopenharmony_ci
3033e1051a39Sopenharmony_ci    if (n == 0) {
3034e1051a39Sopenharmony_ci        ADD_TEST(test_sub);
3035e1051a39Sopenharmony_ci        ADD_TEST(test_div_recip);
3036e1051a39Sopenharmony_ci        ADD_ALL_TESTS(test_signed_mod_replace_ab, OSSL_NELEM(signed_mod_tests));
3037e1051a39Sopenharmony_ci        ADD_ALL_TESTS(test_signed_mod_replace_ba, OSSL_NELEM(signed_mod_tests));
3038e1051a39Sopenharmony_ci        ADD_TEST(test_mod);
3039e1051a39Sopenharmony_ci        ADD_TEST(test_modexp_mont5);
3040e1051a39Sopenharmony_ci        ADD_TEST(test_kronecker);
3041e1051a39Sopenharmony_ci        ADD_TEST(test_rand);
3042e1051a39Sopenharmony_ci        ADD_TEST(test_bn2padded);
3043e1051a39Sopenharmony_ci        ADD_TEST(test_dec2bn);
3044e1051a39Sopenharmony_ci        ADD_TEST(test_hex2bn);
3045e1051a39Sopenharmony_ci        ADD_TEST(test_asc2bn);
3046e1051a39Sopenharmony_ci        ADD_ALL_TESTS(test_mpi, (int)OSSL_NELEM(kMPITests));
3047e1051a39Sopenharmony_ci        ADD_TEST(test_negzero);
3048e1051a39Sopenharmony_ci        ADD_TEST(test_badmod);
3049e1051a39Sopenharmony_ci        ADD_TEST(test_expmodzero);
3050e1051a39Sopenharmony_ci        ADD_TEST(test_expmodone);
3051e1051a39Sopenharmony_ci        ADD_ALL_TESTS(test_smallprime, 16);
3052e1051a39Sopenharmony_ci        ADD_ALL_TESTS(test_smallsafeprime, 16);
3053e1051a39Sopenharmony_ci        ADD_TEST(test_swap);
3054e1051a39Sopenharmony_ci        ADD_TEST(test_ctx_consttime_flag);
3055e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC2M
3056e1051a39Sopenharmony_ci        ADD_TEST(test_gf2m_add);
3057e1051a39Sopenharmony_ci        ADD_TEST(test_gf2m_mod);
3058e1051a39Sopenharmony_ci        ADD_TEST(test_gf2m_mul);
3059e1051a39Sopenharmony_ci        ADD_TEST(test_gf2m_sqr);
3060e1051a39Sopenharmony_ci        ADD_TEST(test_gf2m_modinv);
3061e1051a39Sopenharmony_ci        ADD_TEST(test_gf2m_moddiv);
3062e1051a39Sopenharmony_ci        ADD_TEST(test_gf2m_modexp);
3063e1051a39Sopenharmony_ci        ADD_TEST(test_gf2m_modsqrt);
3064e1051a39Sopenharmony_ci        ADD_TEST(test_gf2m_modsolvequad);
3065e1051a39Sopenharmony_ci#endif
3066e1051a39Sopenharmony_ci        ADD_ALL_TESTS(test_is_prime, (int)OSSL_NELEM(primes));
3067e1051a39Sopenharmony_ci        ADD_ALL_TESTS(test_not_prime, (int)OSSL_NELEM(not_primes));
3068e1051a39Sopenharmony_ci        ADD_TEST(test_gcd_prime);
3069e1051a39Sopenharmony_ci        ADD_ALL_TESTS(test_mod_exp, (int)OSSL_NELEM(ModExpTests));
3070e1051a39Sopenharmony_ci        ADD_ALL_TESTS(test_mod_exp_consttime, (int)OSSL_NELEM(ModExpTests));
3071e1051a39Sopenharmony_ci        ADD_TEST(test_mod_exp2_mont);
3072e1051a39Sopenharmony_ci        if (stochastic)
3073e1051a39Sopenharmony_ci            ADD_TEST(test_rand_range);
3074e1051a39Sopenharmony_ci    } else {
3075e1051a39Sopenharmony_ci        ADD_ALL_TESTS(run_file_tests, n);
3076e1051a39Sopenharmony_ci    }
3077e1051a39Sopenharmony_ci    return 1;
3078e1051a39Sopenharmony_ci}
3079e1051a39Sopenharmony_ci
3080e1051a39Sopenharmony_civoid cleanup_tests(void)
3081e1051a39Sopenharmony_ci{
3082e1051a39Sopenharmony_ci    BN_CTX_free(ctx);
3083e1051a39Sopenharmony_ci}
3084