Flatten structure of libcrypto/bn tests
authortb <tb@openbsd.org>
Thu, 1 Dec 2022 20:50:10 +0000 (20:50 +0000)
committertb <tb@openbsd.org>
Thu, 1 Dec 2022 20:50:10 +0000 (20:50 +0000)
The bn tests were distributed into three subdirectories rather randomly.
It's cleaner and easier to maintain if all this is in a single directory.
Use consistent names for the .c files, unify handling of the tests with
the exception of bn_test, which is special.

Discussed with jsing

25 files changed:
regress/lib/libcrypto/bn/Makefile
regress/lib/libcrypto/bn/addsub/Makefile [deleted file]
regress/lib/libcrypto/bn/addsub/bnaddsub.c [deleted file]
regress/lib/libcrypto/bn/bn_add_sub.c [new file with mode: 0644]
regress/lib/libcrypto/bn/bn_isqrt.c [new file with mode: 0644]
regress/lib/libcrypto/bn/bn_mod_exp2_mont.c [new file with mode: 0644]
regress/lib/libcrypto/bn/bn_mod_sqrt.c [new file with mode: 0644]
regress/lib/libcrypto/bn/bn_mont.c [new file with mode: 0644]
regress/lib/libcrypto/bn/bn_primes.c [new file with mode: 0644]
regress/lib/libcrypto/bn/bn_rand_interval.c [new file with mode: 0644]
regress/lib/libcrypto/bn/bn_test.c [new file with mode: 0644]
regress/lib/libcrypto/bn/bn_to_string.c [new file with mode: 0644]
regress/lib/libcrypto/bn/bn_unit.c [new file with mode: 0644]
regress/lib/libcrypto/bn/general/Makefile [deleted file]
regress/lib/libcrypto/bn/general/bn_isqrt.c [deleted file]
regress/lib/libcrypto/bn/general/bn_mod_exp2_mont.c [deleted file]
regress/lib/libcrypto/bn/general/bn_mod_sqrt.c [deleted file]
regress/lib/libcrypto/bn/general/bn_primes.c [deleted file]
regress/lib/libcrypto/bn/general/bn_to_string.c [deleted file]
regress/lib/libcrypto/bn/general/bn_unit.c [deleted file]
regress/lib/libcrypto/bn/general/bntest.c [deleted file]
regress/lib/libcrypto/bn/mont/Makefile [deleted file]
regress/lib/libcrypto/bn/mont/mont.c [deleted file]
regress/lib/libcrypto/bn/rand/Makefile [deleted file]
regress/lib/libcrypto/bn/rand/bn_rand_interval.c [deleted file]

index 89c8d78..971ace1 100644 (file)
@@ -1,20 +1,58 @@
-#      $OpenBSD: Makefile,v 1.7 2022/11/30 02:51:05 jsing Exp $
+#      $OpenBSD: Makefile,v 1.8 2022/12/01 20:50:10 tb Exp $
 
-SUBDIR= \
-       addsub \
-       general \
-       mont \
-       rand
+PROGS +=       bn_add_sub
+PROGS +=       bn_cmp
+PROGS +=       bn_isqrt
+PROGS +=       bn_mod_exp2_mont
+PROGS +=       bn_mod_sqrt
+PROGS +=       bn_mont
+PROGS +=       bn_primes
+PROGS +=       bn_rand_interval
+PROGS +=       bn_to_string
+PROGS +=       bn_unit
 
-PROGS+= bn_cmp
+STATIC_LINK += bn_isqrt
+STATIC_LINK += bn_primes
+STATIC_LINK += bn_to_string
+STATIC_LINK += bn_rand_interval
 
-LDADD=         -lcrypto
-DPADD=         ${LIBCRYPTO}
-WARNINGS=      Yes
-CFLAGS+=       -Wall -Wundef -Werror
+LDADD =                -lcrypto
+DPADD =                ${LIBCRYPTO}
+WARNINGS =     Yes
+CFLAGS +=      -Wall -Wundef -Werror
+CFLAGS +=      -I${.CURDIR}/../../../../lib/libcrypto/bn/
 
-REGRESS_TARGETS += run-bn_cmp
-run-bn_cmp: bn_cmp
-       ./bn_cmp
+.for p in ${PROGS}
+REGRESS_TARGETS +=     run-$p
+.PHONY +=              run-$p
+
+run-$p: $p
+       ./$p
+.endfor
+
+isqrt-print-tables: bn_isqrt
+       @./bn_isqrt -C
+
+# Keep bn_test last since it is special
+PROGS +=       bn_test
+STATIC_LINK += bn_test
+CLEANFILES +=  bn_test.out bc.out
+
+REGRESS_TARGETS +=     run-bn_test
+.PHONY:                run-bn_test
+run-bn_test bntest.out: bn_test
+       ./bn_test -out bn_test.out
+
+REGRESS_TARGETS +=     run-bc
+.PHONY:                run-bc
+run-bc: bn_test.out
+       bc < $> | tee bc.out | grep -v '^0$$'
+       ! grep -v '^test ' <bc.out | grep -v '^0$$'
+
+.for p in ${STATIC_LINK}
+LDADD_$p +=    ${CRYPTO_INT}
+.endfor
+
+.PHONY: isqrt-print-tables
 
 .include <bsd.regress.mk>
diff --git a/regress/lib/libcrypto/bn/addsub/Makefile b/regress/lib/libcrypto/bn/addsub/Makefile
deleted file mode 100644 (file)
index 382e776..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#      $OpenBSD: Makefile,v 1.2 2022/06/19 17:08:19 tb Exp $
-
-.include "../../Makefile.inc"
-
-PROG=          bnaddsub
-LDADD=         ${LIBCRYPTO}
-DPADD=         ${LIBCRYPTO}
-WARNINGS=      Yes
-CFLAGS+=       -Werror
-
-.include <bsd.regress.mk>
diff --git a/regress/lib/libcrypto/bn/addsub/bnaddsub.c b/regress/lib/libcrypto/bn/addsub/bnaddsub.c
deleted file mode 100644 (file)
index e23821e..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/*     $OpenBSD: bnaddsub.c,v 1.3 2018/07/23 17:15:21 tb Exp $ */
-/*
- * Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* Test basic functionality of BN_add(), BN_sub(), BN_uadd() and BN_usub() */
-
-#include <err.h>
-#include <stdio.h>
-
-#include <openssl/bio.h>
-#include <openssl/bn.h>
-#include <openssl/err.h>
-
-#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
-
-BIO *bio_err;
-
-struct hexinput_st {
-       const char      *a_hex;
-       const char      *b_hex;
-       const char      *e_hex;         /* expected result */
-       const char       ret;           /* check return value */
-       int              compare;       /* use BN_cmp() to verify results */
-};
-
-int bn_op_test(int (*)(BIGNUM *, const BIGNUM *, const BIGNUM *),
-    struct hexinput_st[], unsigned int, const char *);
-void print_failure_case(BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, int,
-    const char *);
-
-struct hexinput_st test_bn_add[] = {
-       {
-               "F",
-               "F",
-               "1E",
-               1,
-               1,
-       },
-       {
-               "FFFFFFFFFFFFFFFFFFF",
-               "1",
-               "10000000000000000000",
-               1,
-               1,
-       },
-       {
-               "7878787878787878",
-               "1010101010101010",
-               "8888888888888888",
-               1,
-               1,
-       },
-       {
-               "FFFFFFFFFFFFFFFF0000000000000000",
-               "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
-               "1FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
-               1,
-               1,
-       },
-       {
-               "F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0",
-               "10101010101010101010101010101010",
-               "101010101010101010101010101010100",
-               1,
-               1,
-       },
-};
-
-struct hexinput_st test_bn_sub[] = {
-       {
-               "10",
-               "1",
-               "F",
-               1,
-               1,
-       },
-       {
-               "10",
-               "1",
-               "E",
-               1,
-               0,
-       },
-       {
-               "100000000001000000000",
-               "11100000001",
-               "FFFFFFFFFEFEFFFFFFFF",
-               1,
-               1,
-       },
-       {
-               "-FFFFFFFFFFFFFFFFFFFF",
-               "1",
-               "-100000000000000000000",
-               1,
-               1,
-       },
-};
-
-struct hexinput_st test_bn_usub[] = {
-       {
-               "10",
-               "1",
-               "F",
-               1,
-               1,
-       },
-       {
-               "10",
-               "1",
-               "E",
-               1,
-               0,
-       },
-       {
-               "100000000001000000000",
-               "11100000001",
-               "FFFFFFFFFEFEFFFFFFFF",
-               1,
-               1,
-       },
-       {
-               "100000000000000000000",
-               "1",
-               "FFFFFFFFFFFFFFFFFFFF",
-               1,
-               1,
-       },
-       {
-               "0",
-               "1",
-               "0",
-               0,
-               0,
-       },
-};
-
-void
-print_failure_case(BIGNUM *a, BIGNUM *b, BIGNUM *e, BIGNUM *r, int i,
-    const char *testname)
-{
-       BIO_printf(bio_err, "%s #%d failed:", testname, i);
-       BIO_printf(bio_err, "\na = ");
-       BN_print(bio_err, a);
-       BIO_printf(bio_err, "\nb = ");
-       BN_print(bio_err, b);
-       BIO_printf(bio_err, "\nexpected: e = ");
-       BN_print(bio_err, e);
-       BIO_printf(bio_err, "\nobtained: r = ");
-       BN_print(bio_err, r);
-       BIO_printf(bio_err, "\n");
-}
-
-int
-bn_op_test(int (*bn_op)(BIGNUM *, const BIGNUM *, const BIGNUM *),
-    struct hexinput_st tests[], unsigned int ntests, const char *testname)
-{
-       BIGNUM          *a = NULL, *b = NULL, *e = NULL, *r = NULL;
-       unsigned int     i;
-       int              failed = 0;
-
-       if (((a = BN_new()) == NULL) ||
-           ((b = BN_new()) == NULL) ||
-           ((e = BN_new()) == NULL) ||
-           ((r = BN_new()) == NULL)) {
-               failed = 1;
-               ERR_print_errors(bio_err);
-               goto err;
-       }
-
-       for (i = 0; i < ntests; i++) {
-               int print = 0;
-
-               if (!BN_hex2bn(&a, tests[i].a_hex) ||
-                   !BN_hex2bn(&b, tests[i].b_hex) ||
-                   !BN_hex2bn(&e, tests[i].e_hex)) {
-                       print = 1;
-                       ERR_print_errors(bio_err);
-               }
-
-               if (tests[i].ret != bn_op(r, a, b))
-                       print = 1;
-               if (tests[i].compare == 1 && BN_cmp(e, r) != 0)
-                       print = 1;
-               if (print) {
-                       failed = 1;
-                       print_failure_case(a, b, e, r, i, testname);
-               }
-       }
-
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(e);
-       BN_free(r);
-       return failed;
-}
-
-int
-main(int argc, char *argv[])
-{
-       int failed = 0;
-
-       if ((bio_err = BIO_new_fp(stderr, BIO_NOCLOSE)) == NULL) {
-               fprintf(stderr, "bnaddsub: failed to initialize bio_err");
-               return 1;
-       }
-
-       if (bn_op_test(BN_add, test_bn_add, nitems(test_bn_add),
-           "BN_add with test_bn_add[]"))
-               failed = 1;
-       if (bn_op_test(BN_uadd, test_bn_add, nitems(test_bn_add),
-           "BN_uadd with test_bn_add[]"))
-               failed = 1;
-       if (bn_op_test(BN_sub, test_bn_sub, nitems(test_bn_sub),
-           "BN_sub with test_bn_sub[]"))
-               failed = 1;
-       if (bn_op_test(BN_usub, test_bn_usub, nitems(test_bn_usub),
-           "BN_usub with test_bn_usub[]"))
-               failed = 1;
-
-       return failed;
-}
diff --git a/regress/lib/libcrypto/bn/bn_add_sub.c b/regress/lib/libcrypto/bn/bn_add_sub.c
new file mode 100644 (file)
index 0000000..f13129a
--- /dev/null
@@ -0,0 +1,236 @@
+/*     $OpenBSD: bn_add_sub.c,v 1.1 2022/12/01 20:50:10 tb Exp $       */
+/*
+ * Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Test basic functionality of BN_add(), BN_sub(), BN_uadd() and BN_usub() */
+
+#include <err.h>
+#include <stdio.h>
+
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/err.h>
+
+#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
+
+BIO *bio_err;
+
+struct hexinput_st {
+       const char      *a_hex;
+       const char      *b_hex;
+       const char      *e_hex;         /* expected result */
+       const char       ret;           /* check return value */
+       int              compare;       /* use BN_cmp() to verify results */
+};
+
+int bn_op_test(int (*)(BIGNUM *, const BIGNUM *, const BIGNUM *),
+    struct hexinput_st[], unsigned int, const char *);
+void print_failure_case(BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, int,
+    const char *);
+
+struct hexinput_st test_bn_add[] = {
+       {
+               "F",
+               "F",
+               "1E",
+               1,
+               1,
+       },
+       {
+               "FFFFFFFFFFFFFFFFFFF",
+               "1",
+               "10000000000000000000",
+               1,
+               1,
+       },
+       {
+               "7878787878787878",
+               "1010101010101010",
+               "8888888888888888",
+               1,
+               1,
+       },
+       {
+               "FFFFFFFFFFFFFFFF0000000000000000",
+               "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+               "1FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+               1,
+               1,
+       },
+       {
+               "F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0",
+               "10101010101010101010101010101010",
+               "101010101010101010101010101010100",
+               1,
+               1,
+       },
+};
+
+struct hexinput_st test_bn_sub[] = {
+       {
+               "10",
+               "1",
+               "F",
+               1,
+               1,
+       },
+       {
+               "10",
+               "1",
+               "E",
+               1,
+               0,
+       },
+       {
+               "100000000001000000000",
+               "11100000001",
+               "FFFFFFFFFEFEFFFFFFFF",
+               1,
+               1,
+       },
+       {
+               "-FFFFFFFFFFFFFFFFFFFF",
+               "1",
+               "-100000000000000000000",
+               1,
+               1,
+       },
+};
+
+struct hexinput_st test_bn_usub[] = {
+       {
+               "10",
+               "1",
+               "F",
+               1,
+               1,
+       },
+       {
+               "10",
+               "1",
+               "E",
+               1,
+               0,
+       },
+       {
+               "100000000001000000000",
+               "11100000001",
+               "FFFFFFFFFEFEFFFFFFFF",
+               1,
+               1,
+       },
+       {
+               "100000000000000000000",
+               "1",
+               "FFFFFFFFFFFFFFFFFFFF",
+               1,
+               1,
+       },
+       {
+               "0",
+               "1",
+               "0",
+               0,
+               0,
+       },
+};
+
+void
+print_failure_case(BIGNUM *a, BIGNUM *b, BIGNUM *e, BIGNUM *r, int i,
+    const char *testname)
+{
+       BIO_printf(bio_err, "%s #%d failed:", testname, i);
+       BIO_printf(bio_err, "\na = ");
+       BN_print(bio_err, a);
+       BIO_printf(bio_err, "\nb = ");
+       BN_print(bio_err, b);
+       BIO_printf(bio_err, "\nexpected: e = ");
+       BN_print(bio_err, e);
+       BIO_printf(bio_err, "\nobtained: r = ");
+       BN_print(bio_err, r);
+       BIO_printf(bio_err, "\n");
+}
+
+int
+bn_op_test(int (*bn_op)(BIGNUM *, const BIGNUM *, const BIGNUM *),
+    struct hexinput_st tests[], unsigned int ntests, const char *testname)
+{
+       BIGNUM          *a = NULL, *b = NULL, *e = NULL, *r = NULL;
+       unsigned int     i;
+       int              failed = 0;
+
+       if (((a = BN_new()) == NULL) ||
+           ((b = BN_new()) == NULL) ||
+           ((e = BN_new()) == NULL) ||
+           ((r = BN_new()) == NULL)) {
+               failed = 1;
+               ERR_print_errors(bio_err);
+               goto err;
+       }
+
+       for (i = 0; i < ntests; i++) {
+               int print = 0;
+
+               if (!BN_hex2bn(&a, tests[i].a_hex) ||
+                   !BN_hex2bn(&b, tests[i].b_hex) ||
+                   !BN_hex2bn(&e, tests[i].e_hex)) {
+                       print = 1;
+                       ERR_print_errors(bio_err);
+               }
+
+               if (tests[i].ret != bn_op(r, a, b))
+                       print = 1;
+               if (tests[i].compare == 1 && BN_cmp(e, r) != 0)
+                       print = 1;
+               if (print) {
+                       failed = 1;
+                       print_failure_case(a, b, e, r, i, testname);
+               }
+       }
+
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(e);
+       BN_free(r);
+       return failed;
+}
+
+int
+main(int argc, char *argv[])
+{
+       int failed = 0;
+
+       if ((bio_err = BIO_new_fp(stderr, BIO_NOCLOSE)) == NULL) {
+               fprintf(stderr, "bnaddsub: failed to initialize bio_err");
+               return 1;
+       }
+
+       if (bn_op_test(BN_add, test_bn_add, nitems(test_bn_add),
+           "BN_add with test_bn_add[]"))
+               failed = 1;
+       if (bn_op_test(BN_uadd, test_bn_add, nitems(test_bn_add),
+           "BN_uadd with test_bn_add[]"))
+               failed = 1;
+       if (bn_op_test(BN_sub, test_bn_sub, nitems(test_bn_sub),
+           "BN_sub with test_bn_sub[]"))
+               failed = 1;
+       if (bn_op_test(BN_usub, test_bn_usub, nitems(test_bn_usub),
+           "BN_usub with test_bn_usub[]"))
+               failed = 1;
+
+       return failed;
+}
diff --git a/regress/lib/libcrypto/bn/bn_isqrt.c b/regress/lib/libcrypto/bn/bn_isqrt.c
new file mode 100644 (file)
index 0000000..a730322
--- /dev/null
@@ -0,0 +1,327 @@
+/*     $OpenBSD: bn_isqrt.c,v 1.1 2022/12/01 20:50:10 tb Exp $ */
+/*
+ * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <err.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <openssl/bn.h>
+
+#include "bn_local.h"
+
+#define N_TESTS                400
+
+/* Sample squares between 2^128 and 2^4096. */
+#define LOWER_BITS     128
+#define UPPER_BITS     4096
+
+extern const uint8_t is_square_mod_11[];
+extern const uint8_t is_square_mod_63[];
+extern const uint8_t is_square_mod_64[];
+extern const uint8_t is_square_mod_65[];
+
+static void
+hexdump(const unsigned char *buf, size_t len)
+{
+       size_t i;
+
+       for (i = 1; i <= len; i++)
+               fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
+
+       if (len % 8)
+               fprintf(stderr, "\n");
+}
+
+static const uint8_t *
+get_table(int modulus)
+{
+       switch (modulus) {
+       case 11:
+               return is_square_mod_11;
+       case 63:
+               return is_square_mod_63;
+       case 64:
+               return is_square_mod_64;
+       case 65:
+               return is_square_mod_65;
+       default:
+               return NULL;
+       }
+}
+
+static int
+check_tables(int print)
+{
+       int fill[] = {11, 63, 64, 65};
+       const uint8_t *table;
+       uint8_t q[65];
+       size_t i;
+       int j;
+       int failed = 0;
+
+       for (i = 0; i < sizeof(fill) / sizeof(fill[0]); i++) {
+               memset(q, 0, sizeof(q));
+
+               for (j = 0; j < fill[i]; j++)
+                       q[(j * j) % fill[i]] = 1;
+
+               if ((table = get_table(fill[i])) == NULL) {
+                       fprintf(stderr, "failed to get table %d\n", fill[i]);
+                       failed |= 1;
+                       continue;
+               }
+
+               if (memcmp(table, q, fill[i]) != 0) {
+                       fprintf(stderr, "table %d does not match:\n", fill[i]);
+                       fprintf(stderr, "want:\n");
+                       hexdump(table, fill[i]);
+                       fprintf(stderr, "got:\n");
+                       hexdump(q, fill[i]);
+                       failed |= 1;
+                       continue;
+               }
+
+               if (!print)
+                       continue;
+
+               printf("const uint8_t is_square_mod_%d[] = {\n\t", fill[i]);
+               for (j = 0; j < fill[i]; j++) {
+                       const char *end = " ";
+
+                       if (j % 16 == 15)
+                               end = "\n\t";
+                       if (j + 1 == fill[i])
+                               end = "";
+
+                       printf("%d,%s", q[j], end);
+               }
+               printf("\n};\nCTASSERT(sizeof(is_square_mod_%d) == %d);\n\n",
+                   fill[i], fill[i]);
+       }
+
+       return failed;
+}
+
+static int
+validate_tables(void)
+{
+       int fill[] = {11, 63, 64, 65};
+       const uint8_t *table;
+       size_t i;
+       int j, k;
+       int failed = 0;
+
+       for (i = 0; i < sizeof(fill) / sizeof(fill[0]); i++) {
+               if ((table = get_table(fill[i])) == NULL) {
+                       fprintf(stderr, "failed to get table %d\n", fill[i]);
+                       failed |= 1;
+                       continue;
+               }
+
+               for (j = 0; j < fill[i]; j++) {
+                       for (k = 0; k < fill[i]; k++) {
+                               if (j == (k * k) % fill[i])
+                                       break;
+                       }
+
+                       if (table[j] == 0 && k < fill[i]) {
+                               fprintf(stderr, "%d == %d^2 (mod %d)", j, k,
+                                   fill[i]);
+                               failed |= 1;
+                       }
+                       if (table[j] == 1 && k == fill[i]) {
+                               fprintf(stderr, "%d not a square (mod %d)", j,
+                                   fill[i]);
+                               failed |= 1;
+                       }
+               }
+       }
+
+       return failed;
+}
+
+/*
+ * Choose a random number n of bit length between LOWER_BITS and UPPER_BITS and
+ * check that n == isqrt(n^2). Random numbers n^2 <= testcase < (n + 1)^2 are
+ * checked to have isqrt(testcase) == n.
+ */
+static int
+isqrt_test(void)
+{
+       BN_CTX *ctx;
+       BIGNUM *n, *n_sqr, *lower, *upper, *testcase, *isqrt;
+       int cmp, i, is_perfect_square;
+       int failed = 0;
+
+       if ((ctx = BN_CTX_new()) == NULL)
+               errx(1, "BN_CTX_new");
+
+       BN_CTX_start(ctx);
+
+       if ((lower = BN_CTX_get(ctx)) == NULL)
+               errx(1, "lower = BN_CTX_get(ctx)");
+       if ((upper = BN_CTX_get(ctx)) == NULL)
+               errx(1, "upper = BN_CTX_get(ctx)");
+       if ((n = BN_CTX_get(ctx)) == NULL)
+               errx(1, "n = BN_CTX_get(ctx)");
+       if ((n_sqr = BN_CTX_get(ctx)) == NULL)
+               errx(1, "n = BN_CTX_get(ctx)");
+       if ((isqrt = BN_CTX_get(ctx)) == NULL)
+               errx(1, "result = BN_CTX_get(ctx)");
+       if ((testcase = BN_CTX_get(ctx)) == NULL)
+               errx(1, "testcase = BN_CTX_get(ctx)");
+
+       /* lower = 2^LOWER_BITS, upper = 2^UPPER_BITS. */
+       if (!BN_set_bit(lower, LOWER_BITS))
+               errx(1, "BN_set_bit(lower, %d)", LOWER_BITS);
+       if (!BN_set_bit(upper, UPPER_BITS))
+               errx(1, "BN_set_bit(upper, %d)", UPPER_BITS);
+
+       if (!bn_rand_interval(n, lower, upper))
+               errx(1, "bn_rand_interval n");
+
+       /* n_sqr = n^2 */
+       if (!BN_sqr(n_sqr, n, ctx))
+               errx(1, "BN_sqr");
+
+       if (!bn_isqrt(isqrt, &is_perfect_square, n_sqr, ctx))
+               errx(1, "bn_isqrt n_sqr");
+
+       if ((cmp = BN_cmp(n, isqrt)) != 0 || !is_perfect_square) {
+               fprintf(stderr, "n = ");
+               BN_print_fp(stderr, n);
+               fprintf(stderr, "\nn^2 is_perfect_square: %d, cmp: %d\n",
+                   is_perfect_square, cmp);
+               failed = 1;
+       }
+
+       /* upper = 2 * n + 1 */
+       if (!BN_lshift1(upper, n))
+               errx(1, "BN_lshift1(upper, n)");
+       if (!BN_add_word(upper, 1))
+               errx(1, "BN_sub_word(upper, 1)");
+
+       /* upper = (n + 1)^2 = n^2 + upper */
+       if (!BN_add(upper, n_sqr, upper))
+               errx(1, "BN_add");
+
+       /*
+        * Check that isqrt((n + 1)^2) - 1 == n.
+        */
+
+       if (!bn_isqrt(isqrt, &is_perfect_square, upper, ctx))
+               errx(1, "bn_isqrt(upper)");
+
+       if (!BN_sub_word(isqrt, 1))
+               errx(1, "BN_add_word(isqrt, 1)");
+
+       if ((cmp = BN_cmp(n, isqrt)) != 0 || !is_perfect_square) {
+               fprintf(stderr, "n = ");
+               BN_print_fp(stderr, n);
+               fprintf(stderr, "\n(n + 1)^2 is_perfect_square: %d, cmp: %d\n",
+                   is_perfect_square, cmp);
+               failed = 1;
+       }
+
+       /*
+        * Test N_TESTS random numbers n^2 <= testcase < (n + 1)^2 and check
+        * that their isqrt is n.
+        */
+
+       for (i = 0; i < N_TESTS; i++) {
+               if (!bn_rand_interval(testcase, n_sqr, upper))
+                       errx(1, "bn_rand_interval testcase");
+
+               if (!bn_isqrt(isqrt, &is_perfect_square, testcase, ctx))
+                       errx(1, "bn_isqrt testcase");
+
+               if ((cmp = BN_cmp(n, isqrt)) != 0 ||
+                   (is_perfect_square && BN_cmp(n_sqr, testcase) != 0)) {
+                       fprintf(stderr, "n = ");
+                       BN_print_fp(stderr, n);
+                       fprintf(stderr, "\ntestcase = ");
+                       BN_print_fp(stderr, testcase);
+                       fprintf(stderr,
+                           "\ntestcase is_perfect_square: %d, cmp: %d\n",
+                           is_perfect_square, cmp);
+                       failed = 1;
+               }
+       }
+
+       /*
+        * Finally check that isqrt(n^2 - 1) + 1 == n.
+        */
+
+       if (!BN_sub(testcase, n_sqr, BN_value_one()))
+               errx(1, "BN_sub(testcase, n_sqr, 1)");
+
+       if (!bn_isqrt(isqrt, &is_perfect_square, testcase, ctx))
+               errx(1, "bn_isqrt(n_sqr - 1)");
+
+       if (!BN_add_word(isqrt, 1))
+               errx(1, "BN_add_word(isqrt, 1)");
+
+       if ((cmp = BN_cmp(n, isqrt)) != 0 || is_perfect_square) {
+               fprintf(stderr, "n = ");
+               BN_print_fp(stderr, n);
+               fprintf(stderr, "\nn_sqr - 1 is_perfect_square: %d, cmp: %d\n",
+                   is_perfect_square, cmp);
+               failed = 1;
+       }
+
+       BN_CTX_end(ctx);
+       BN_CTX_free(ctx);
+
+       return failed;
+}
+
+static void
+usage(void)
+{
+       fprintf(stderr, "usage: bn_isqrt [-C]\n");
+       exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+       size_t i;
+       int ch;
+       int failed = 0, print = 0;
+
+       while ((ch = getopt(argc, argv, "C")) != -1) {
+               switch (ch) {
+               case 'C':
+                       print = 1;
+                       break;
+               default:
+                       usage();
+                       break;
+               }
+       }
+
+       if (print)
+               return check_tables(1);
+
+       for (i = 0; i < N_TESTS; i++)
+               failed |= isqrt_test();
+
+       failed |= check_tables(0);
+       failed |= validate_tables();
+
+       return failed;
+}
diff --git a/regress/lib/libcrypto/bn/bn_mod_exp2_mont.c b/regress/lib/libcrypto/bn/bn_mod_exp2_mont.c
new file mode 100644 (file)
index 0000000..0fa2b96
--- /dev/null
@@ -0,0 +1,43 @@
+/*     $OpenBSD: bn_mod_exp2_mont.c,v 1.1 2022/12/01 20:50:10 tb Exp $ */
+/*
+ * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <err.h>
+
+#include <openssl/bn.h>
+
+/*
+ * Small test for a crash reported by Guido Vranken, fixed in bn_exp2.c r1.13.
+ * https://github.com/openssl/openssl/issues/17648
+ */
+
+int
+main(void)
+{
+       BIGNUM *m;
+
+       if ((m = BN_new()) == NULL)
+               errx(1, "BN_new");
+
+       BN_zero_ex(m);
+
+       if (BN_mod_exp2_mont(NULL, NULL, NULL, NULL, NULL, m, NULL, NULL))
+               errx(1, "BN_mod_exp2_mont succeeded");
+
+       BN_free(m);
+
+       return 0;
+}
diff --git a/regress/lib/libcrypto/bn/bn_mod_sqrt.c b/regress/lib/libcrypto/bn/bn_mod_sqrt.c
new file mode 100644 (file)
index 0000000..e193755
--- /dev/null
@@ -0,0 +1,129 @@
+/*     $OpenBSD: bn_mod_sqrt.c,v 1.1 2022/12/01 20:50:10 tb Exp $ */
+/*
+ * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <openssl/bn.h>
+
+/* Test that sqrt * sqrt = A (mod p) where p is a prime */
+struct mod_sqrt_test {
+       const char *sqrt;
+       const char *a;
+       const char *p;
+       int bn_mod_sqrt_fails;
+} mod_sqrt_test_data[] = {
+       {
+               .sqrt = "1",
+               .a = "1",
+               .p = "2",
+               .bn_mod_sqrt_fails = 0,
+       },
+       {
+               .sqrt = "-1",
+               .a = "20a7ee",
+               .p = "460201", /* 460201 == 4D5 * E7D */
+               .bn_mod_sqrt_fails = 1,
+       },
+       {
+               .sqrt = "-1",
+               .a = "65bebdb00a96fc814ec44b81f98b59fba3c30203928fa521"
+                    "4c51e0a97091645280c947b005847f239758482b9bfc45b0"
+                    "66fde340d1fe32fc9c1bf02e1b2d0ed",
+               .p = "9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e2"
+                    "46b41c32f71e951f",
+               .bn_mod_sqrt_fails = 1,
+       },
+};
+
+const size_t N_TESTS = sizeof(mod_sqrt_test_data) / sizeof(*mod_sqrt_test_data);
+
+int mod_sqrt_test(struct mod_sqrt_test *test);
+
+int
+mod_sqrt_test(struct mod_sqrt_test *test)
+{
+       BN_CTX *ctx = NULL;
+       BIGNUM *a = NULL, *p = NULL, *want = NULL, *got = NULL, *diff = NULL;
+       int failed = 1;
+
+       if ((ctx = BN_CTX_new()) == NULL) {
+               fprintf(stderr, "BN_CTX_new failed\n");
+               goto out;
+       }
+
+       if (!BN_hex2bn(&a, test->a)) {
+               fprintf(stderr, "BN_hex2bn(a) failed\n");
+               goto out;
+       }
+       if (!BN_hex2bn(&p, test->p)) {
+               fprintf(stderr, "BN_hex2bn(p) failed\n");
+               goto out;
+       }
+       if (!BN_hex2bn(&want, test->sqrt)) {
+               fprintf(stderr, "BN_hex2bn(want) failed\n");
+               goto out;
+       }
+
+       if (((got = BN_mod_sqrt(NULL, a, p, ctx)) == NULL) !=
+          test->bn_mod_sqrt_fails) {
+               fprintf(stderr, "BN_mod_sqrt %s unexpectedly\n",
+                   test->bn_mod_sqrt_fails ? "succeeded" : "failed");
+               goto out;
+       }
+
+       if (test->bn_mod_sqrt_fails) {
+               failed = 0;
+               goto out;
+       }
+
+       if ((diff = BN_new()) == NULL) {
+               fprintf(stderr, "diff = BN_new() failed\n");
+               goto out;
+       }
+
+       if (!BN_mod_sub(diff, want, got, p, ctx)) {
+               fprintf(stderr, "BN_mod_sub failed\n");
+               goto out;
+       }
+
+       if (!BN_is_zero(diff)) {
+               fprintf(stderr, "want != got\n");
+               goto out;
+       }
+
+       failed = 0;
+
+ out:
+       BN_CTX_free(ctx);
+       BN_free(a);
+       BN_free(p);
+       BN_free(want);
+       BN_free(got);
+       BN_free(diff);
+
+       return failed;
+}
+
+int
+main(void)
+{
+       size_t i;
+       int failed = 0;
+
+       for (i = 0; i < N_TESTS; i++)
+               failed |= mod_sqrt_test(&mod_sqrt_test_data[i]);
+
+       return failed;
+}
diff --git a/regress/lib/libcrypto/bn/bn_mont.c b/regress/lib/libcrypto/bn/bn_mont.c
new file mode 100644 (file)
index 0000000..d7c8f95
--- /dev/null
@@ -0,0 +1,84 @@
+/*     $OpenBSD: bn_mont.c,v 1.1 2022/12/01 20:50:10 tb Exp $  */
+
+/*
+ * Copyright (c) 2014 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include <openssl/dh.h>
+#include <openssl/err.h>
+
+/*
+ * Test for proper bn_mul_mont behaviour when operands are of vastly different
+ * sizes.
+ */
+
+int
+main(int argc, char *argv[])
+{
+       DH *dh = NULL;
+       BIGNUM *priv_key = NULL;
+       unsigned char *key = NULL;
+       unsigned char r[32 + 16 * 8];
+       size_t privsz;
+
+       arc4random_buf(r, sizeof(r));
+
+       for (privsz = 32; privsz <= sizeof(r); privsz += 8) {
+               dh = DH_new();
+               if (dh == NULL)
+                       goto err;
+               if (DH_generate_parameters_ex(dh, 32, DH_GENERATOR_2,
+                   NULL) == 0)
+                       goto err;
+
+               /* force private key to be much larger than public one */
+               priv_key = BN_bin2bn(r, privsz, NULL);
+               if (priv_key == NULL)
+                       goto err;
+
+               if (!DH_set0_key(dh, NULL, priv_key))
+                       goto err;
+               priv_key = NULL;
+
+               if (DH_generate_key(dh) == 0)
+                       goto err;
+               key = malloc(DH_size(dh));
+               if (key == NULL)
+                       err(1, "malloc");
+               if (DH_compute_key(key, DH_get0_pub_key(dh), dh) == -1)
+                       goto err;
+
+               free(key);
+               key = NULL;
+               DH_free(dh);
+               dh = NULL;
+       }
+
+       return 0;
+
+ err:
+       ERR_print_errors_fp(stderr);
+       free(key);
+       BN_free(priv_key);
+       DH_free(dh);
+       return 1;
+}
diff --git a/regress/lib/libcrypto/bn/bn_primes.c b/regress/lib/libcrypto/bn/bn_primes.c
new file mode 100644 (file)
index 0000000..e9a91ba
--- /dev/null
@@ -0,0 +1,184 @@
+/*     $OpenBSD: bn_primes.c,v 1.1 2022/12/01 20:50:10 tb Exp $ */
+/*
+ * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <openssl/bn.h>
+
+#include "bn_prime.h"
+
+static int
+test_bn_is_prime_fasttest(int do_trial_division)
+{
+       BIGNUM *n = NULL;
+       char *descr = NULL;
+       uint16_t i, j, max;
+       int is_prime, ret;
+       int failed = 1;
+
+       if (asprintf(&descr, "with%s trial divisions",
+           do_trial_division ? "" : "out") == -1) {
+               descr = NULL;
+               fprintf(stderr, "asprintf failed\n");
+               goto err;
+       }
+
+       if ((n = BN_new()) == NULL) {
+               fprintf(stderr, "BN_new failed\n");
+               goto err;
+       }
+
+       max = primes[NUMPRIMES - 1] + 1;
+
+       failed = 0;
+       for (i = 1, j = 0; i < max && j < NUMPRIMES; i++) {
+               if (!BN_set_word(n, i)) {
+                       fprintf(stderr, "BN_set_word(%d) failed", i);
+                       failed = 1;
+                       goto err;
+               }
+
+               is_prime = i == primes[j];
+               if (is_prime)
+                       j++;
+
+               ret = BN_is_prime_fasttest_ex(n, BN_prime_checks, NULL,
+                   do_trial_division, NULL);
+               if (ret != is_prime) {
+                       fprintf(stderr,
+                           "BN_is_prime_fasttest_ex(%d) %s: want %d, got %d\n",
+                           i, descr, is_prime, ret);
+                       failed = 1;
+               }
+       }
+
+       if (i < max || j < NUMPRIMES) {
+               fprintf(stderr, "%s: %d < %d or %d < %d\n", descr, i, max, j,
+                   NUMPRIMES);
+               failed = 1;
+       }
+
+ err:
+       BN_free(n);
+       free(descr);
+       return failed;
+}
+
+#define BN_PRIME_FN_INIT(a) { .fn = a, .name = #a }
+
+static const struct test_dynamic_api {
+       BIGNUM *(*fn)(BIGNUM *);
+       const char *name;
+} dynamic_api_data[] = {
+       BN_PRIME_FN_INIT(BN_get_rfc2409_prime_1024),
+       BN_PRIME_FN_INIT(BN_get_rfc2409_prime_768),
+       BN_PRIME_FN_INIT(BN_get_rfc3526_prime_1536),
+       BN_PRIME_FN_INIT(BN_get_rfc3526_prime_2048),
+       BN_PRIME_FN_INIT(BN_get_rfc3526_prime_3072),
+       BN_PRIME_FN_INIT(BN_get_rfc3526_prime_4096),
+       BN_PRIME_FN_INIT(BN_get_rfc3526_prime_6144),
+       BN_PRIME_FN_INIT(BN_get_rfc3526_prime_8192),
+};
+
+#define N_DYNAMIC_TESTS (sizeof(dynamic_api_data) / sizeof(dynamic_api_data[0]))
+
+static const struct test_const_api {
+       const BIGNUM *(*fn)(void);
+       const char *name;
+} const_api_data[] = {
+       BN_PRIME_FN_INIT(BN_get0_nist_prime_192),
+       BN_PRIME_FN_INIT(BN_get0_nist_prime_224),
+       BN_PRIME_FN_INIT(BN_get0_nist_prime_256),
+       BN_PRIME_FN_INIT(BN_get0_nist_prime_384),
+       BN_PRIME_FN_INIT(BN_get0_nist_prime_521),
+};
+
+#define N_CONST_TESTS (sizeof(const_api_data) / sizeof(const_api_data[0]))
+
+static int
+test_prime_dynamic_api(const struct test_dynamic_api *tc)
+{
+       BIGNUM *prime;
+       int ret;
+       int failed = 1;
+
+       if ((prime = tc->fn(NULL)) == NULL) {
+               fprintf(stderr, "%s failed\n", tc->name);
+               goto err;
+       }
+
+       if ((ret = BN_is_prime_fasttest_ex(prime, 1, NULL, 1, NULL)) != 1) {
+               fprintf(stderr, "%s: %s want 1, got %d\n", tc->name,
+                   "BN_is_prime_fasttest_ex", ret);
+               goto err;
+       }
+
+       failed = 0;
+
+ err:
+       BN_free(prime);
+       return failed;
+}
+
+static int
+test_prime_const_api(const struct test_const_api *tc)
+{
+       const BIGNUM *prime;
+       int ret;
+       int failed = 1;
+
+       if ((prime = tc->fn()) == NULL) {
+               fprintf(stderr, "%s failed\n", tc->name);
+               goto err;
+       }
+
+       if ((ret = BN_is_prime_fasttest_ex(prime, 1, NULL, 1, NULL)) != 1) {
+               fprintf(stderr, "%s: %s: want 1, got %d\n", tc->name,
+                   "BN_is_prime_fasttest_ex", ret);
+               goto err;
+       }
+
+       failed = 0;
+
+ err:
+       return failed;
+}
+
+static int
+test_prime_constants(void)
+{
+       size_t i;
+       int failed = 0;
+
+       for (i = 0; i < N_DYNAMIC_TESTS; i++)
+               failed |= test_prime_dynamic_api(&dynamic_api_data[i]);
+
+       for (i = 0; i < N_CONST_TESTS; i++)
+               failed |= test_prime_const_api(&const_api_data[i]);
+
+       return failed;
+}
+
+int
+main(void)
+{
+       int failed = 0;
+
+       failed |= test_bn_is_prime_fasttest(0);
+       failed |= test_bn_is_prime_fasttest(1);
+       failed |= test_prime_constants();
+
+       return failed;
+}
diff --git a/regress/lib/libcrypto/bn/bn_rand_interval.c b/regress/lib/libcrypto/bn/bn_rand_interval.c
new file mode 100644 (file)
index 0000000..032edfb
--- /dev/null
@@ -0,0 +1,112 @@
+/*     $OpenBSD: bn_rand_interval.c,v 1.1 2022/12/01 20:50:10 tb Exp $ */
+/*
+ * Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <err.h>
+#include <stdio.h>
+
+#include <openssl/bn.h>
+
+#define NUM_TESTS 1000000
+
+int bn_rand_interval(BIGNUM *rnd, const BIGNUM *lower_incl,
+    const BIGNUM *upper_excl);
+void print_triple(BIGNUM *a, BIGNUM *b, BIGNUM *x);
+
+void
+print_triple(BIGNUM *a, BIGNUM *b, BIGNUM *x) {
+       if (a != NULL) {
+               printf("a = ");
+               BN_print_fp(stdout, a);
+               printf("\n");
+       }
+
+       if (b != NULL) {
+               printf("b = ");
+               BN_print_fp(stdout, b);
+               printf("\n");
+       }
+
+       if (x != NULL) {
+               printf("x = ");
+               BN_print_fp(stdout, x);
+               printf("\n");
+       }
+}
+
+int
+main(int argc, char *argv[])
+{
+       BIGNUM *a, *b, *x;
+       int i, success = 1;
+
+       if ((a = BN_new()) == NULL)
+               errx(1, "BN_new(a)");
+       if ((b = BN_new()) == NULL)
+               errx(1, "BN_new(b)");
+       if ((x = BN_new()) == NULL)
+               errx(1, "BN_new(c)");
+
+       for (i = 0; i < NUM_TESTS; i++) {
+               if (!BN_rand(a, 256, 0, 0))
+                       errx(1, "BN_rand(a)");
+
+               if (bn_rand_interval(x, a, a) != 0) {
+                       success = 0;
+
+                       printf("bn_rand_interval(a == a) succeeded\n");
+                       print_triple(a, NULL, x);
+               }
+
+               if (!BN_rand(b, 256, 0, 0))
+                       errx(1, "BN_rand(b)");
+
+               switch(BN_cmp(a, b)) {
+               case 0:         /* a == b */
+                       continue;
+
+               case 1:         /* a > b */
+                       BN_swap(a, b);
+                       break;
+
+               default:        /* a < b */
+                       break;
+               }
+
+               if (!bn_rand_interval(x, a, b))
+                       errx(1, "bn_rand_interval() failed");
+
+               if (BN_cmp(x, a) < 0 || BN_cmp(x, b) >= 0) {
+                       success = 0;
+
+                       printf("generated number x not inside [a,b)\n");
+                       print_triple(a, b, x);
+               }
+
+               if (bn_rand_interval(x, b, a) != 0) {
+                       success = 0;
+
+                       printf("bn_rand_interval(x, b, a) succeeded\n");
+                       print_triple(a, b, x);
+               }
+       }
+
+       BN_free(a);
+       BN_free(b);
+       BN_free(x);
+
+       return 1 - success;
+}
diff --git a/regress/lib/libcrypto/bn/bn_test.c b/regress/lib/libcrypto/bn/bn_test.c
new file mode 100644 (file)
index 0000000..c1fedde
--- /dev/null
@@ -0,0 +1,2624 @@
+/*     $OpenBSD: bn_test.c,v 1.1 2022/12/01 20:50:10 tb Exp $  */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the Eric Young open source
+ * license provided above.
+ *
+ * The binary polynomial arithmetic software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+/* Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code */
+#ifdef OPENSSL_NO_DEPRECATED
+#undef OPENSSL_NO_DEPRECATED
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+
+int BN_mod_exp_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+    const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_exp_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+    const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_exp_mont_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_mont_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+
+int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom);
+
+const int num0 = 100; /* number of tests */
+const int num1 = 50;  /* additional tests for some functions */
+const int num2 = 5;   /* number of tests for slow functions */
+
+int test_add(BIO *bp);
+int test_sub(BIO *bp);
+int test_lshift1(BIO *bp);
+int test_lshift(BIO *bp, BN_CTX *ctx, BIGNUM *a_);
+int test_rshift1(BIO *bp);
+int test_rshift(BIO *bp, BN_CTX *ctx);
+int test_div(BIO *bp, BN_CTX *ctx);
+int test_div_word(BIO *bp);
+int test_div_recp(BIO *bp, BN_CTX *ctx);
+int test_mul(BIO *bp);
+int test_sqr(BIO *bp, BN_CTX *ctx);
+int test_mont(BIO *bp, BN_CTX *ctx);
+int test_mod(BIO *bp, BN_CTX *ctx);
+int test_mod_mul(BIO *bp, BN_CTX *ctx);
+int test_mod_exp(BIO *bp, BN_CTX *ctx);
+int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx);
+int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx);
+int test_mod_exp_sizes(BIO *bp, BN_CTX *ctx);
+int test_exp(BIO *bp, BN_CTX *ctx);
+int test_gf2m_add(BIO *bp);
+int test_gf2m_mod(BIO *bp);
+int test_gf2m_mod_mul(BIO *bp, BN_CTX *ctx);
+int test_gf2m_mod_sqr(BIO *bp, BN_CTX *ctx);
+int test_gf2m_mod_inv(BIO *bp, BN_CTX *ctx);
+int test_gf2m_mod_div(BIO *bp, BN_CTX *ctx);
+int test_gf2m_mod_exp(BIO *bp, BN_CTX *ctx);
+int test_gf2m_mod_sqrt(BIO *bp, BN_CTX *ctx);
+int test_gf2m_mod_solve_quad(BIO *bp, BN_CTX *ctx);
+int test_kron(BIO *bp, BN_CTX *ctx);
+int test_sqrt(BIO *bp, BN_CTX *ctx);
+int rand_neg(void);
+static int results = 0;
+
+static unsigned char lst[] =
+       "\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
+       "\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
+
+#define PRINT_ERROR printf("Error in %s [%s:%d]\n", __func__, __FILE__,        \
+               __LINE__)
+
+#define CHECK_GOTO(a) do {                                             \
+       if (!(a)) {                                                     \
+               PRINT_ERROR;                                            \
+               rc = 0;                                                 \
+               goto err;                                               \
+       }                                                               \
+} while (0)
+
+static void
+message(BIO *out, char *m)
+{
+       fprintf(stderr, "test %s\n", m);
+       BIO_puts(out, "print \"test ");
+       BIO_puts(out, m);
+       BIO_puts(out, "\\n\"\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+       BN_CTX *ctx;
+       BIO *out;
+       char *outfile = NULL;
+
+       results = 0;
+
+       argc--;
+       argv++;
+       while (argc >= 1) {
+               if (strcmp(*argv, "-results") == 0)
+                       results = 1;
+               else if (strcmp(*argv, "-out") == 0) {
+                       if (--argc < 1)
+                               break;
+                       outfile= *(++argv);
+               }
+               argc--;
+               argv++;
+       }
+
+
+       ctx = BN_CTX_new();
+       if (ctx == NULL)
+               exit(1);
+
+       out = BIO_new(BIO_s_file());
+       if (out == NULL)
+               exit(1);
+       if (outfile == NULL) {
+               BIO_set_fp(out, stdout, BIO_NOCLOSE);
+       } else {
+               if (!BIO_write_filename(out, outfile)) {
+                       perror(outfile);
+                       exit(1);
+               }
+       }
+
+       if (!results)
+               BIO_puts(out, "obase=16\nibase=16\n");
+
+       message(out, "BN_add");
+       if (!test_add(out))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_sub");
+       if (!test_sub(out))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_lshift1");
+       if (!test_lshift1(out))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_lshift (fixed)");
+       if (!test_lshift(out, ctx, BN_bin2bn(lst, sizeof(lst) - 1, NULL)))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_lshift");
+       if (!test_lshift(out, ctx, NULL))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_rshift1");
+       if (!test_rshift1(out))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_rshift");
+       if (!test_rshift(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_sqr");
+       if (!test_sqr(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_mul");
+       if (!test_mul(out))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_div");
+       if (!test_div(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_div_word");
+       if (!test_div_word(out))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_div_recp");
+       if (!test_div_recp(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_mod");
+       if (!test_mod(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_mod_mul");
+       if (!test_mod_mul(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_mont");
+       if (!test_mont(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_mod_exp");
+       if (!test_mod_exp(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_mod_exp_mont_consttime");
+       if (!test_mod_exp_mont_consttime(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_mod_exp_mont5");
+       if (!test_mod_exp_mont5(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_exp");
+       if (!test_exp(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_kronecker");
+       if (!test_kron(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_mod_sqrt");
+       if (!test_sqrt(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "Modexp with different sizes");
+       if (!test_mod_exp_sizes(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+#ifndef OPENSSL_NO_EC2M
+       message(out, "BN_GF2m_add");
+       if (!test_gf2m_add(out))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_GF2m_mod");
+       if (!test_gf2m_mod(out))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_GF2m_mod_mul");
+       if (!test_gf2m_mod_mul(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_GF2m_mod_sqr");
+       if (!test_gf2m_mod_sqr(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_GF2m_mod_inv");
+       if (!test_gf2m_mod_inv(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_GF2m_mod_div");
+       if (!test_gf2m_mod_div(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_GF2m_mod_exp");
+       if (!test_gf2m_mod_exp(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_GF2m_mod_sqrt");
+       if (!test_gf2m_mod_sqrt(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+
+       message(out, "BN_GF2m_mod_solve_quad");
+       if (!test_gf2m_mod_solve_quad(out, ctx))
+               goto err;
+       (void)BIO_flush(out);
+#endif
+       BN_CTX_free(ctx);
+       BIO_free(out);
+
+       exit(0);
+ err:
+       BIO_puts(out, "1\n"); /* make sure the Perl script fed by bc notices
+                              * the failure, see test_bn in test/Makefile.ssl*/
+
+       (void)BIO_flush(out);
+       ERR_load_crypto_strings();
+       ERR_print_errors_fp(stderr);
+       exit(1);
+}
+
+int
+test_add(BIO *bp)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL;
+       int i;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_bntest_rand(b, 450 + i, 0, 0));
+               BN_set_negative(a, rand_neg());
+               BN_set_negative(b, rand_neg());
+               CHECK_GOTO(BN_add(c, a, b));
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " + ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, c));
+                       BIO_puts(bp, "\n");
+               }
+               BN_set_negative(a, !BN_is_negative(a));
+               BN_set_negative(b, !BN_is_negative(b));
+               CHECK_GOTO(BN_add(c, c, b));
+               CHECK_GOTO(BN_add(c, c, a));
+               if (!BN_is_zero(c)) {
+                       fprintf(stderr, "Add test failed!\n");
+                       rc = 0;
+                       break;
+               }
+       }
+
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+
+       return rc;
+}
+
+int
+test_sub(BIO *bp)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL;
+       int i;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+
+       for (i = 0; i < num0 + num1; i++) {
+               if (i < num1) {
+                       CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
+                       CHECK_GOTO(BN_copy(b, a));
+                       if (BN_set_bit(a, i) == 0) {
+                               rc = 0;
+                               break;
+                       }
+                       CHECK_GOTO(BN_add_word(b, i));
+               } else {
+                       CHECK_GOTO(BN_bntest_rand(b, 400 + i - num1, 0, 0));
+                       BN_set_negative(a, rand_neg());
+                       BN_set_negative(b, rand_neg());
+               }
+               CHECK_GOTO(BN_sub(c, a, b));
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " - ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, c));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_add(c, c, b));
+               CHECK_GOTO(BN_sub(c, c, a));
+               if (!BN_is_zero(c)) {
+                       fprintf(stderr, "Subtract test failed!\n");
+                       rc = 0;
+                       break;
+               }
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       return (rc);
+}
+
+int
+test_div(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
+       int i;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_one(a));
+       CHECK_GOTO(BN_zero(b));
+
+       if (BN_div(d, c, a, b, ctx)) {
+               fprintf(stderr, "Division by zero succeeded!\n");
+               return (0);
+       }
+
+       for (i = 0; i < num0 + num1; i++) {
+               if (i < num1) {
+                       CHECK_GOTO(BN_bntest_rand(a, 400, 0, 0));
+                       CHECK_GOTO(BN_copy(b, a));
+                       CHECK_GOTO(BN_lshift(a, a, i));
+                       CHECK_GOTO(BN_add_word(a, i));
+               } else
+                       CHECK_GOTO(BN_bntest_rand(b, 50 + 3 * (i - num1), 0, 0));
+               BN_set_negative(a, rand_neg());
+               BN_set_negative(b, rand_neg());
+               CHECK_GOTO(BN_div(d, c, a, b, ctx));
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " / ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, d));
+                       BIO_puts(bp, "\n");
+
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " % ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, c));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_mul(e, d, b, ctx));
+               CHECK_GOTO(BN_add(d, e, c));
+               CHECK_GOTO(BN_sub(d, d, a));
+               if (!BN_is_zero(d)) {
+                       fprintf(stderr, "Division test failed!\n");
+                       rc = 0;
+                       break;
+               }
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       return (rc);
+}
+
+static void
+print_word(BIO *bp, BN_ULONG w)
+{
+#ifdef SIXTY_FOUR_BIT
+       if (sizeof(w) > sizeof(unsigned long)) {
+               unsigned long h = (unsigned long)(w >> 32), l = (unsigned long)(w);
+
+               if (h)
+                       BIO_printf(bp, "%lX%08lX", h, l);
+               else
+                       BIO_printf(bp, "%lX", l);
+               return;
+       }
+#endif
+       BIO_printf(bp, BN_HEX_FMT1, w);
+}
+
+int
+test_div_word(BIO *bp)
+{
+       BIGNUM *a = NULL, *b = NULL;
+       BN_ULONG r, rmod, s = 0;
+       int i;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+
+       for (i = 0; i < num0; i++) {
+               do {
+                       if (!BN_bntest_rand(a, 512, -1, 0) ||
+                           !BN_bntest_rand(b, BN_BITS2, -1, 0)) {
+                               rc = 0;
+                               break;
+                       }
+                       s = BN_get_word(b);
+               } while (!s);
+
+               if (!BN_copy(b, a)) {
+                       rc = 0;
+                       break;
+               }
+
+               rmod = BN_mod_word(b, s);
+               r = BN_div_word(b, s);
+
+               if (r == (BN_ULONG)-1 || rmod == (BN_ULONG)-1) {
+                       rc = 0;
+                       break;
+               }
+
+               if (rmod != r) {
+                       fprintf(stderr, "Mod (word) test failed!\n");
+                       rc = 0;
+                       break;
+               }
+
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " / ");
+                               print_word(bp, s);
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, b));
+                       BIO_puts(bp, "\n");
+
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " % ");
+                               print_word(bp, s);
+                               BIO_puts(bp, " - ");
+                       }
+                       print_word(bp, r);
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_mul_word(b, s));
+               CHECK_GOTO(BN_add_word(b, r));
+               CHECK_GOTO(BN_sub(b, a, b));
+               if (!BN_is_zero(b)) {
+                       fprintf(stderr, "Division (word) test failed!\n");
+                       rc = 0;
+                       break;
+               }
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+
+       return rc;
+}
+
+int
+test_div_recp(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
+       BN_RECP_CTX *recp = NULL;
+       int i;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+
+       if ((recp = BN_RECP_CTX_new()) == NULL)
+               goto err;
+
+       for (i = 0; i < num0 + num1; i++) {
+               if (i < num1) {
+                       CHECK_GOTO(BN_bntest_rand(a, 400, 0, 0));
+                       CHECK_GOTO(BN_copy(b, a));
+                       CHECK_GOTO(BN_lshift(a, a, i));
+                       CHECK_GOTO(BN_add_word(a, i));
+               } else
+                       CHECK_GOTO(BN_bntest_rand(b, 50 + 3 * (i - num1), 0, 0));
+               BN_set_negative(a, rand_neg());
+               BN_set_negative(b, rand_neg());
+               CHECK_GOTO(BN_RECP_CTX_set(recp, b, ctx));
+               CHECK_GOTO(BN_div_recp(d, c, a, recp, ctx));
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " / ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, d));
+                       BIO_puts(bp, "\n");
+
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " % ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, c));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_mul(e, d, b, ctx));
+               CHECK_GOTO(BN_add(d, e, c));
+               CHECK_GOTO(BN_sub(d, d, a));
+               if (!BN_is_zero(d)) {
+                       fprintf(stderr, "Reciprocal division test failed!\n");
+                       fprintf(stderr, "a=");
+                       CHECK_GOTO(BN_print_fp(stderr, a));
+                       fprintf(stderr, "\nb=");
+                       CHECK_GOTO(BN_print_fp(stderr, b));
+                       fprintf(stderr, "\n");
+                       rc = 0;
+                       break;
+               }
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       BN_RECP_CTX_free(recp);
+       return (rc);
+}
+
+int
+test_mul(BIO *bp)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
+       int i;
+       int rc = 1;
+       BN_CTX *ctx;
+
+       ctx = BN_CTX_new();
+       if (ctx == NULL)
+               exit(1);
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+
+       for (i = 0; i < num0 + num1; i++) {
+               if (i <= num1) {
+                       CHECK_GOTO(BN_bntest_rand(a, 100, 0, 0));
+                       CHECK_GOTO(BN_bntest_rand(b, 100, 0, 0));
+               } else
+                       CHECK_GOTO(BN_bntest_rand(b, i - num1, 0, 0));
+               BN_set_negative(a, rand_neg());
+               BN_set_negative(b, rand_neg());
+               CHECK_GOTO(BN_mul(c, a, b, ctx));
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " * ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, c));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_div(d, e, c, a, ctx));
+               CHECK_GOTO(BN_sub(d, d, b));
+               if (!BN_is_zero(d) || !BN_is_zero(e)) {
+                       fprintf(stderr, "Multiplication test failed!\n");
+                       rc = 0;
+                       break;
+               }
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       BN_CTX_free(ctx);
+       return (rc);
+}
+
+int
+test_sqr(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *c = NULL, *d = NULL, *e = NULL;
+       int i, rc = 0;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 40 + i * 10, 0, 0));
+               BN_set_negative(a, rand_neg());
+               CHECK_GOTO(BN_sqr(c, a, ctx));
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " * ");
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, c));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_div(d, e, c, a, ctx));
+               CHECK_GOTO(BN_sub(d, d, a));
+               if (!BN_is_zero(d) || !BN_is_zero(e)) {
+                       fprintf(stderr, "Square test failed!\n");
+                       goto err;
+               }
+       }
+
+       /* Regression test for a BN_sqr overflow bug. */
+       if (!BN_hex2bn(&a, "80000000000000008000000000000001"
+           "FFFFFFFFFFFFFFFE0000000000000000")) {
+               fprintf(stderr, "BN_hex2bn failed\n");
+               goto err;
+       }
+       CHECK_GOTO(BN_sqr(c, a, ctx));
+       if (bp != NULL) {
+               if (!results) {
+                       CHECK_GOTO(BN_print(bp, a));
+                       BIO_puts(bp, " * ");
+                       CHECK_GOTO(BN_print(bp, a));
+                       BIO_puts(bp, " - ");
+               }
+               CHECK_GOTO(BN_print(bp, c));
+               BIO_puts(bp, "\n");
+       }
+       CHECK_GOTO(BN_mul(d, a, a, ctx));
+       if (BN_cmp(c, d)) {
+               fprintf(stderr,
+                   "Square test failed: BN_sqr and BN_mul produce "
+                   "different results!\n");
+               goto err;
+       }
+
+       /* Regression test for a BN_sqr overflow bug. */
+       if (!BN_hex2bn(&a, "80000000000000000000000080000001"
+           "FFFFFFFE000000000000000000000000")) {
+               fprintf(stderr, "BN_hex2bn failed\n");
+               goto err;
+       }
+       CHECK_GOTO(BN_sqr(c, a, ctx));
+       if (bp != NULL) {
+               if (!results) {
+                       CHECK_GOTO(BN_print(bp, a));
+                       BIO_puts(bp, " * ");
+                       CHECK_GOTO(BN_print(bp, a));
+                       BIO_puts(bp, " - ");
+               }
+               CHECK_GOTO(BN_print(bp, c));
+               BIO_puts(bp, "\n");
+       }
+       CHECK_GOTO(BN_mul(d, a, a, ctx));
+       if (BN_cmp(c, d)) {
+               fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
+                               "different results!\n");
+               goto err;
+       }
+       rc = 1;
+ err:
+       BN_free(a);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       return rc;
+}
+
+int
+test_mont(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *A = NULL, *B = NULL;
+       BIGNUM *n = NULL;
+       int i;
+       int rc = 1;
+       BN_MONT_CTX *mont;
+
+       mont = BN_MONT_CTX_new();
+       if (mont == NULL)
+               return 0;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((A = BN_new()) == NULL)
+               goto err;
+       if ((B = BN_new()) == NULL)
+               goto err;
+       if ((n = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_zero(n));
+       if (BN_MONT_CTX_set(mont, n, ctx)) {
+               fprintf(stderr, "BN_MONT_CTX_set succeeded for zero modulus!\n");
+               return (0);
+       }
+
+       CHECK_GOTO(BN_set_word(n, 16));
+       if (BN_MONT_CTX_set(mont, n, ctx)) {
+               fprintf(stderr, "BN_MONT_CTX_set succeeded for even modulus!\n");
+               return (0);
+       }
+
+       CHECK_GOTO(BN_bntest_rand(a, 100, 0, 0));
+       CHECK_GOTO(BN_bntest_rand(b, 100, 0, 0));
+       for (i = 0; i < num2; i++) {
+               int bits = (200 * (i + 1)) / num2;
+
+               if (bits == 0)
+                       continue;
+               CHECK_GOTO(BN_bntest_rand(n, bits, 0, 1));
+               CHECK_GOTO(BN_MONT_CTX_set(mont, n, ctx));
+
+               CHECK_GOTO(BN_nnmod(a, a, n, ctx));
+               CHECK_GOTO(BN_nnmod(b, b, n, ctx));
+
+               CHECK_GOTO(BN_to_montgomery(A, a, mont, ctx));
+               CHECK_GOTO(BN_to_montgomery(B, b, mont, ctx));
+
+               CHECK_GOTO(BN_mod_mul_montgomery(c, A, B, mont, ctx));
+               CHECK_GOTO(BN_from_montgomery(A, c, mont, ctx));
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " * ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " % ");
+                               /* n == &mont->N */
+                               CHECK_GOTO(BN_print(bp, n));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, A));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_mod_mul(d, a, b, n, ctx));
+               CHECK_GOTO(BN_sub(d, d, A));
+               if (!BN_is_zero(d)) {
+                       fprintf(stderr, "Montgomery multiplication test failed!\n");
+                       rc = 0;
+                       break;
+               }
+       }
+ err:
+       BN_MONT_CTX_free(mont);
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       BN_free(d);
+       BN_free(A);
+       BN_free(B);
+       BN_free(n);
+       return (rc);
+}
+
+int
+test_mod(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
+       int i;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0));
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_bntest_rand(b, 450 + i * 10, 0, 0));
+               BN_set_negative(a, rand_neg());
+               BN_set_negative(b, rand_neg());
+               CHECK_GOTO(BN_mod(c, a, b, ctx));
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " % ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, c));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_div(d, e, a, b, ctx));
+               CHECK_GOTO(BN_sub(e, e, c));
+               if (!BN_is_zero(e)) {
+                       fprintf(stderr, "Modulo test failed!\n");
+                       rc = 0;
+                       break;
+               }
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       return (rc);
+}
+
+int
+test_mod_mul(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
+       int i, j;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_one(a));
+       CHECK_GOTO(BN_one(b));
+       CHECK_GOTO(BN_zero(c));
+       if (BN_mod_mul(e, a, b, c, ctx)) {
+               fprintf(stderr, "BN_mod_mul with zero modulus succeeded!\n");
+               return (0);
+       }
+
+       for (j = 0; j < 3; j++) {
+               CHECK_GOTO(BN_bntest_rand(c, 1024, 0, 0));
+               for (i = 0; i < num0; i++) {
+                       CHECK_GOTO(BN_bntest_rand(a, 475 + i * 10, 0, 0));
+                       CHECK_GOTO(BN_bntest_rand(b, 425 + i * 11, 0, 0));
+                       BN_set_negative(a, rand_neg());
+                       BN_set_negative(b, rand_neg());
+                       if (!BN_mod_mul(e, a, b, c, ctx)) {
+                               unsigned long l;
+
+                               while ((l = ERR_get_error()))
+                                       fprintf(stderr, "ERROR:%s\n",
+                                           ERR_error_string(l, NULL));
+                               exit(1);
+                       }
+                       if (bp != NULL) {
+                               if (!results) {
+                                       CHECK_GOTO(BN_print(bp, a));
+                                       BIO_puts(bp, " * ");
+                                       CHECK_GOTO(BN_print(bp, b));
+                                       BIO_puts(bp, " % ");
+                                       CHECK_GOTO(BN_print(bp, c));
+                                       if ((BN_is_negative(a) ^ BN_is_negative(b)) &&
+                                           !BN_is_zero(e)) {
+                                               /* If  (a*b) % c  is negative,  c  must be added
+                                                * in order to obtain the normalized remainder
+                                                * (new with OpenSSL 0.9.7, previous versions of
+                                                * BN_mod_mul could generate negative results)
+                                                */
+                                               BIO_puts(bp, " + ");
+                                               CHECK_GOTO(BN_print(bp, c));
+                                       }
+                                       BIO_puts(bp, " - ");
+                               }
+                               CHECK_GOTO(BN_print(bp, e));
+                               BIO_puts(bp, "\n");
+                       }
+                       CHECK_GOTO(BN_mul(d, a, b, ctx));
+                       CHECK_GOTO(BN_sub(d, d, e));
+                       CHECK_GOTO(BN_div(a, b, d, c, ctx));
+                       if (!BN_is_zero(b)) {
+                               fprintf(stderr, "Modulo multiply test failed!\n");
+                               ERR_print_errors_fp(stderr);
+                               rc = 0;
+                               goto err;
+                       }
+               }
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       return (rc);
+}
+
+int
+test_mod_exp(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
+       int i;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_one(a));
+       CHECK_GOTO(BN_one(b));
+       CHECK_GOTO(BN_zero(c));
+       if (BN_mod_exp(d, a, b, c, ctx)) {
+               fprintf(stderr, "BN_mod_exp with zero modulus succeeded!\n");
+               rc = 0;
+               goto err;
+       }
+       if (BN_mod_exp_ct(d, a, b, c, ctx)) {
+               fprintf(stderr, "BN_mod_exp_ct with zero modulus succeeded!\n");
+               rc = 0;
+               goto err;
+       }
+       if (BN_mod_exp_nonct(d, a, b, c, ctx)) {
+               fprintf(stderr, "BN_mod_exp_nonct with zero modulus succeeded!\n");
+               rc = 0;
+               goto err;
+       }
+
+       CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */
+       for (i = 0; i < num2; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
+               CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
+
+               if (!BN_mod_exp(d, a, b, c, ctx)) {
+                       rc = 0;
+                       break;
+               }
+
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " ^ ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " % ");
+                               CHECK_GOTO(BN_print(bp, c));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, d));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_exp(e, a, b, ctx));
+               CHECK_GOTO(BN_sub(e, e, d));
+               CHECK_GOTO(BN_div(a, b, e, c, ctx));
+               if (!BN_is_zero(b)) {
+                       fprintf(stderr, "Modulo exponentiation test failed!\n");
+                       rc = 0;
+                       break;
+               }
+       }
+
+       CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */
+       for (i = 0; i < num2; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
+               CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
+
+               if (!BN_mod_exp_ct(d, a, b, c, ctx)) {
+                       rc = 0;
+                       break;
+               }
+
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " ^ ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " % ");
+                               CHECK_GOTO(BN_print(bp, c));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, d));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_exp(e, a, b, ctx));
+               CHECK_GOTO(BN_sub(e, e, d));
+               CHECK_GOTO(BN_div(a, b, e, c, ctx));
+               if (!BN_is_zero(b)) {
+                       fprintf(stderr, "Modulo exponentiation test failed!\n");
+                       rc = 0;
+                       break;
+               }
+       }
+
+       CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */
+       for (i = 0; i < num2; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
+               CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
+
+               if (!BN_mod_exp_nonct(d, a, b, c, ctx)) {
+                       rc = 0;
+                       break;
+               }
+
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " ^ ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " % ");
+                               CHECK_GOTO(BN_print(bp, c));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, d));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_exp(e, a, b, ctx));
+               CHECK_GOTO(BN_sub(e, e, d));
+               CHECK_GOTO(BN_div(a, b, e, c, ctx));
+               if (!BN_is_zero(b)) {
+                       fprintf(stderr, "Modulo exponentiation test failed!\n");
+                       rc = 0;
+                       break;
+               }
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       return (rc);
+}
+
+int
+test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
+       int i;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_one(a));
+       CHECK_GOTO(BN_one(b));
+       CHECK_GOTO(BN_zero(c));
+       if (BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) {
+               fprintf(stderr, "BN_mod_exp_mont_consttime with zero modulus "
+                               "succeeded\n");
+               rc = 0;
+               goto err;
+       }
+
+       CHECK_GOTO(BN_set_word(c, 16));
+       if (BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) {
+               fprintf(stderr, "BN_mod_exp_mont_consttime with even modulus "
+                               "succeeded\n");
+               rc = 0;
+               goto err;
+       }
+
+       CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */
+       for (i = 0; i < num2; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
+               CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
+
+               if (!BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) {
+                       rc = 0;
+                       break;
+               }
+
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " ^ ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " % ");
+                               CHECK_GOTO(BN_print(bp, c));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, d));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_exp(e, a, b, ctx));
+               CHECK_GOTO(BN_sub(e, e, d));
+               CHECK_GOTO(BN_div(a, b, e, c, ctx));
+               if (!BN_is_zero(b)) {
+                       fprintf(stderr, "Modulo exponentiation test failed!\n");
+                       rc = 0;
+                       break;
+               }
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       return (rc);
+}
+
+/*
+ * Test constant-time modular exponentiation with 1024-bit inputs, which on
+ * x86_64 cause a different code branch to be taken.
+ */
+int
+test_mod_exp_mont5(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *p = NULL, *m = NULL, *d = NULL, *e = NULL;
+       BIGNUM *b = NULL, *n = NULL, *c = NULL;
+       BN_MONT_CTX *mont = NULL;
+       int len;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((p = BN_new()) == NULL)
+               goto err;
+       if ((m = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((n = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(mont = BN_MONT_CTX_new());
+
+       CHECK_GOTO(BN_bntest_rand(m, 1024, 0, 1)); /* must be odd for montgomery */
+       /* Zero exponent */
+       CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0));
+       CHECK_GOTO(BN_zero(p));
+       if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)) {
+               rc = 0;
+               goto err;
+       }
+       if (!BN_is_one(d)) {
+               fprintf(stderr, "Modular exponentiation test failed!\n");
+               rc = 0;
+               goto err;
+       }
+       /* Regression test for carry bug in mulx4x_mont */
+       len = BN_hex2bn(&a,
+           "7878787878787878787878787878787878787878787878787878787878787878"
+           "7878787878787878787878787878787878787878787878787878787878787878"
+           "7878787878787878787878787878787878787878787878787878787878787878"
+           "7878787878787878787878787878787878787878787878787878787878787878");
+       CHECK_GOTO(len);
+       len = BN_hex2bn(&b,
+           "095D72C08C097BA488C5E439C655A192EAFB6380073D8C2664668EDDB4060744"
+           "E16E57FB4EDB9AE10A0CEFCDC28A894F689A128379DB279D48A2E20849D68593"
+           "9B7803BCF46CEBF5C533FB0DD35B080593DE5472E3FE5DB951B8BFF9B4CB8F03"
+           "9CC638A5EE8CDD703719F8000E6A9F63BEED5F2FCD52FF293EA05A251BB4AB81");
+       CHECK_GOTO(len);
+       len = BN_hex2bn(&n,
+           "D78AF684E71DB0C39CFF4E64FB9DB567132CB9C50CC98009FEB820B26F2DED9B"
+           "91B9B5E2B83AE0AE4EB4E0523CA726BFBE969B89FD754F674CE99118C3F2D1C5"
+           "D81FDC7C54E02B60262B241D53C040E99E45826ECA37A804668E690E1AFC1CA4"
+           "2C9A15D84D4954425F0B7642FC0BD9D7B24E2618D2DCC9B729D944BADACFDDAF");
+       CHECK_GOTO(len);
+       CHECK_GOTO(BN_MONT_CTX_set(mont, n, ctx));
+       CHECK_GOTO(BN_mod_mul_montgomery(c, a, b, mont, ctx));
+       CHECK_GOTO(BN_mod_mul_montgomery(d, b, a, mont, ctx));
+       if (BN_cmp(c, d)) {
+               fprintf(stderr, "Montgomery multiplication test failed:"
+                   " a*b != b*a.\n");
+               rc = 0;
+               goto err;
+       }
+       /* Regression test for carry bug in sqr[x]8x_mont */
+       len = BN_hex2bn(&n,
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFF00"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "00000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF");
+       CHECK_GOTO(len);
+       len = BN_hex2bn(&a,
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFF0000000000"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "0000000000000000000000000000000000000000000000000000000000000000"
+           "000000000000000000000000000000000000000000FFFFFFFFFFFFFF00000000");
+       CHECK_GOTO(len);
+       BN_free(b);
+       CHECK_GOTO(b = BN_dup(a));
+       CHECK_GOTO(BN_MONT_CTX_set(mont, n, ctx));
+       CHECK_GOTO(BN_mod_mul_montgomery(c, a, a, mont, ctx));
+       CHECK_GOTO(BN_mod_mul_montgomery(d, a, b, mont, ctx));
+       if (BN_cmp(c, d)) {
+               fprintf(stderr, "Montgomery multiplication test failed:"
+                   " a**2 != a*a.\n");
+               rc = 0;
+               goto err;
+       }
+       /* Zero input */
+       CHECK_GOTO(BN_bntest_rand(p, 1024, 0, 0));
+       CHECK_GOTO(BN_zero(a));
+       if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)) {
+               rc = 0;
+               goto err;
+       }
+       if (!BN_is_zero(d)) {
+               fprintf(stderr, "Modular exponentiation test failed!\n");
+               rc = 0;
+               goto err;
+       }
+       /*
+        * Craft an input whose Montgomery representation is 1, i.e., shorter
+        * than the modulus m, in order to test the const time precomputation
+        * scattering/gathering.
+        */
+       CHECK_GOTO(BN_one(a));
+       CHECK_GOTO(BN_MONT_CTX_set(mont, m, ctx));
+       if (!BN_from_montgomery(e, a, mont, ctx)) {
+               rc = 0;
+               goto err;
+       }
+       if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL)) {
+               rc = 0;
+               goto err;
+       }
+       if (!BN_mod_exp_simple(a, e, p, m, ctx)) {
+               rc = 0;
+               goto err;
+       }
+       if (BN_cmp(a, d) != 0) {
+               fprintf(stderr, "Modular exponentiation test failed!\n");
+               rc = 0;
+               goto err;
+       }
+       /* Finally, some regular test vectors. */
+       CHECK_GOTO(BN_bntest_rand(e, 1024, 0, 0));
+       if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL)) {
+               rc = 0;
+               goto err;
+       }
+       if (!BN_mod_exp_simple(a, e, p, m, ctx)) {
+               rc = 0;
+               goto err;
+       }
+       if (BN_cmp(a, d) != 0) {
+               fprintf(stderr, "Modular exponentiation test failed!\n");
+               rc = 0;
+               goto err;
+       }
+ err:
+       BN_free(a);
+       BN_free(p);
+       BN_free(m);
+       BN_free(d);
+       BN_free(e);
+       BN_free(b);
+       BN_free(n);
+       BN_free(c);
+       BN_MONT_CTX_free(mont);
+       return (rc);
+}
+
+int
+test_exp(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b = NULL, *d = NULL, *e = NULL, *one = NULL;
+       int i;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+       if ((one = BN_new()) == NULL)
+               goto err;
+       CHECK_GOTO(BN_one(one));
+
+       for (i = 0; i < num2; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
+               CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
+
+               if (BN_exp(d, a, b, ctx) <= 0) {
+                       rc = 0;
+                       break;
+               }
+
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " ^ ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, d));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_one(e));
+               for (; !BN_is_zero(b); BN_sub(b, b, one))
+                       CHECK_GOTO(BN_mul(e, e, a, ctx));
+               CHECK_GOTO(BN_sub(e, e, d));
+               if (!BN_is_zero(e)) {
+                       fprintf(stderr, "Exponentiation test failed!\n");
+                       rc = 0;
+                       break;
+               }
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(d);
+       BN_free(e);
+       BN_free(one);
+       return (rc);
+}
+
+#ifndef OPENSSL_NO_EC2M
+int
+test_gf2m_add(BIO *bp)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL;
+       int i, rc = 0;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_rand(a, 512, 0, 0));
+               CHECK_GOTO(BN_copy(b, BN_value_one()));
+               BN_set_negative(a, rand_neg());
+               BN_set_negative(b, rand_neg());
+               CHECK_GOTO(BN_GF2m_add(c, a, b));
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " ^ ");
+                               CHECK_GOTO(BN_print(bp, b));
+                               BIO_puts(bp, " = ");
+                       }
+                       CHECK_GOTO(BN_print(bp, c));
+                       BIO_puts(bp, "\n");
+               }
+#endif
+               /* Test that two added values have the correct parity. */
+               if ((BN_is_odd(a) && BN_is_odd(c))
+                   || (!BN_is_odd(a) && !BN_is_odd(c))) {
+                       fprintf(stderr, "GF(2^m) addition test (a) failed!\n");
+                       goto err;
+               }
+               CHECK_GOTO(BN_GF2m_add(c, c, c));
+               /* Test that c + c = 0. */
+               if (!BN_is_zero(c)) {
+                       fprintf(stderr, "GF(2^m) addition test (b) failed!\n");
+                       goto err;
+               }
+       }
+       rc = 1;
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       return rc;
+}
+
+int
+test_gf2m_mod(BIO *bp)
+{
+       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL, *e = NULL;
+       int i, j;
+       int p0[] = { 163, 7, 6, 3, 0, -1 };
+       int p1[] = { 193, 15, 0, -1 };
+       int rc = 0;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b[0] = BN_new()) == NULL)
+               goto err;
+       if ((b[1] = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
+       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
+
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0));
+               for (j = 0; j < 2; j++) {
+                       CHECK_GOTO(BN_GF2m_mod(c, a, b[j]));
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+                       if (bp != NULL) {
+                               if (!results) {
+                                       CHECK_GOTO(BN_print(bp, a));
+                                       BIO_puts(bp, " % ");
+                                       CHECK_GOTO(BN_print(bp, b[j]));
+                                       BIO_puts(bp, " - ");
+                                       CHECK_GOTO(BN_print(bp, c));
+                                       BIO_puts(bp, "\n");
+                               }
+                       }
+#endif
+                       CHECK_GOTO(BN_GF2m_add(d, a, c));
+                       CHECK_GOTO(BN_GF2m_mod(e, d, b[j]));
+                       /* Test that a + (a mod p) mod p == 0. */
+                       if (!BN_is_zero(e)) {
+                               fprintf(stderr, "GF(2^m) modulo test failed!\n");
+                               goto err;
+                       }
+               }
+       }
+       rc = 1;
+ err:
+       BN_free(a);
+       BN_free(b[0]);
+       BN_free(b[1]);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       return rc;
+}
+
+int
+test_gf2m_mod_mul(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
+       BIGNUM *g = NULL, *h = NULL;
+       int i, j;
+       int p0[] = { 163, 7, 6, 3, 0, -1 };
+       int p1[] = { 193, 15, 0, -1 };
+       int rc = 0;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b[0] = BN_new()) == NULL)
+               goto err;
+       if ((b[1] = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+       if ((f = BN_new()) == NULL)
+               goto err;
+       if ((g = BN_new()) == NULL)
+               goto err;
+       if ((h = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
+       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
+
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0));
+               CHECK_GOTO(BN_bntest_rand(c, 1024, 0, 0));
+               CHECK_GOTO(BN_bntest_rand(d, 1024, 0, 0));
+               for (j = 0; j < 2; j++) {
+                       CHECK_GOTO(BN_GF2m_mod_mul(e, a, c, b[j], ctx));
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+                       if (bp != NULL) {
+                               if (!results) {
+                                       CHECK_GOTO(BN_print(bp, a));
+                                       BIO_puts(bp, " * ");
+                                       CHECK_GOTO(BN_print(bp, c));
+                                       BIO_puts(bp, " % ");
+                                       CHECK_GOTO(BN_print(bp, b[j]));
+                                       BIO_puts(bp, " - ");
+                                       CHECK_GOTO(BN_print(bp, e));
+                                       BIO_puts(bp, "\n");
+                               }
+                       }
+#endif
+                       CHECK_GOTO(BN_GF2m_add(f, a, d));
+                       CHECK_GOTO(BN_GF2m_mod_mul(g, f, c, b[j], ctx));
+                       CHECK_GOTO(BN_GF2m_mod_mul(h, d, c, b[j], ctx));
+                       CHECK_GOTO(BN_GF2m_add(f, e, g));
+                       CHECK_GOTO(BN_GF2m_add(f, f, h));
+                       /* Test that (a+d)*c = a*c + d*c. */
+                       if (!BN_is_zero(f)) {
+                               fprintf(stderr, "GF(2^m) modular multiplication test failed!\n");
+                               goto err;
+                       }
+               }
+       }
+       rc = 1;
+ err:
+       BN_free(a);
+       BN_free(b[0]);
+       BN_free(b[1]);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       BN_free(f);
+       BN_free(g);
+       BN_free(h);
+       return rc;
+}
+
+int
+test_gf2m_mod_sqr(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL;
+       int i, j, rc = 0;
+       int p0[] = { 163, 7, 6, 3, 0, -1 };
+       int p1[] = { 193, 15, 0, -1 };
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b[0] = BN_new()) == NULL)
+               goto err;
+       if ((b[1] = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
+       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
+
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0));
+               for (j = 0; j < 2; j++) {
+                       CHECK_GOTO(BN_GF2m_mod_sqr(c, a, b[j], ctx));
+                       CHECK_GOTO(BN_copy(d, a));
+                       CHECK_GOTO(BN_GF2m_mod_mul(d, a, d, b[j], ctx));
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+                       if (bp != NULL) {
+                               if (!results) {
+                                       CHECK_GOTO(BN_print(bp, a));
+                                       BIO_puts(bp, " ^ 2 % ");
+                                       CHECK_GOTO(BN_print(bp, b[j]));
+                                       BIO_puts(bp, " = ");
+                                       CHECK_GOTO(BN_print(bp, c));
+                                       BIO_puts(bp, "; a * a = ");
+                                       CHECK_GOTO(BN_print(bp, d));
+                                       BIO_puts(bp, "\n");
+                               }
+                       }
+#endif
+                       CHECK_GOTO(BN_GF2m_add(d, c, d));
+                       /* Test that a*a = a^2. */
+                       if (!BN_is_zero(d)) {
+                               fprintf(stderr, "GF(2^m) modular squaring test failed!\n");
+                               goto err;
+                       }
+               }
+       }
+       rc = 1;
+ err:
+       BN_free(a);
+       BN_free(b[0]);
+       BN_free(b[1]);
+       BN_free(c);
+       BN_free(d);
+       return rc;
+}
+
+int
+test_gf2m_mod_inv(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL;
+       int i, j, rc = 0;
+       int p0[] = { 163, 7, 6, 3, 0, -1 };
+       int p1[] = { 193, 15, 0, -1 };
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b[0] = BN_new()) == NULL)
+               goto err;
+       if ((b[1] = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
+       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
+
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
+               for (j = 0; j < 2; j++) {
+                       CHECK_GOTO(BN_GF2m_mod_inv(c, a, b[j], ctx));
+                       CHECK_GOTO(BN_GF2m_mod_mul(d, a, c, b[j], ctx));
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+                       if (bp != NULL) {
+                               if (!results) {
+                                       CHECK_GOTO(BN_print(bp, a));
+                                       BIO_puts(bp, " * ");
+                                       CHECK_GOTO(BN_print(bp, c));
+                                       BIO_puts(bp, " - 1 % ");
+                                       CHECK_GOTO(BN_print(bp, b[j]));
+                                       BIO_puts(bp, "\n");
+                               }
+                       }
+#endif
+                       /* Test that ((1/a)*a) = 1. */
+                       if (!BN_is_one(d)) {
+                               fprintf(stderr, "GF(2^m) modular inversion test failed!\n");
+                               goto err;
+                       }
+               }
+       }
+       rc = 1;
+ err:
+       BN_free(a);
+       BN_free(b[0]);
+       BN_free(b[1]);
+       BN_free(c);
+       BN_free(d);
+       return rc;
+}
+
+int
+test_gf2m_mod_div(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
+       int i, j, rc = 0;
+       int p0[] = { 163, 7, 6, 3, 0, -1 };
+       int p1[] = { 193, 15, 0, -1 };
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b[0] = BN_new()) == NULL)
+               goto err;
+       if ((b[1] = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+       if ((f = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
+       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
+
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
+               CHECK_GOTO(BN_bntest_rand(c, 512, 0, 0));
+               for (j = 0; j < 2; j++) {
+                       CHECK_GOTO(BN_GF2m_mod_div(d, a, c, b[j], ctx));
+                       CHECK_GOTO(BN_GF2m_mod_mul(e, d, c, b[j], ctx));
+                       CHECK_GOTO(BN_GF2m_mod_div(f, a, e, b[j], ctx));
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+                       if (bp != NULL) {
+                               if (!results) {
+                                       CHECK_GOTO(BN_print(bp, a));
+                                       BIO_puts(bp, " = ");
+                                       CHECK_GOTO(BN_print(bp, c));
+                                       BIO_puts(bp, " * ");
+                                       CHECK_GOTO(BN_print(bp, d));
+                                       BIO_puts(bp, " % ");
+                                       CHECK_GOTO(BN_print(bp, b[j]));
+                                       BIO_puts(bp, "\n");
+                               }
+                       }
+#endif
+                       /* Test that ((a/c)*c)/a = 1. */
+                       if (!BN_is_one(f)) {
+                               fprintf(stderr, "GF(2^m) modular division test failed!\n");
+                               goto err;
+                       }
+               }
+       }
+       rc = 1;
+ err:
+       BN_free(a);
+       BN_free(b[0]);
+       BN_free(b[1]);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       BN_free(f);
+       return rc;
+}
+
+int
+test_gf2m_mod_exp(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
+       int i, j, rc = 0;
+       int p0[] = { 163, 7, 6, 3, 0, -1 };
+       int p1[] = { 193, 15, 0, -1 };
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b[0] = BN_new()) == NULL)
+               goto err;
+       if ((b[1] = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+       if ((f = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
+       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
+
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
+               CHECK_GOTO(BN_bntest_rand(c, 512, 0, 0));
+               CHECK_GOTO(BN_bntest_rand(d, 512, 0, 0));
+               for (j = 0; j < 2; j++) {
+                       CHECK_GOTO(BN_GF2m_mod_exp(e, a, c, b[j], ctx));
+                       CHECK_GOTO(BN_GF2m_mod_exp(f, a, d, b[j], ctx));
+                       CHECK_GOTO(BN_GF2m_mod_mul(e, e, f, b[j], ctx));
+                       CHECK_GOTO(BN_add(f, c, d));
+                       CHECK_GOTO(BN_GF2m_mod_exp(f, a, f, b[j], ctx));
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+                       if (bp != NULL) {
+                               if (!results) {
+                                       CHECK_GOTO(BN_print(bp, a));
+                                       BIO_puts(bp, " ^ (");
+                                       CHECK_GOTO(BN_print(bp, c));
+                                       BIO_puts(bp, " + ");
+                                       CHECK_GOTO(BN_print(bp, d));
+                                       BIO_puts(bp, ") = ");
+                                       CHECK_GOTO(BN_print(bp, e));
+                                       BIO_puts(bp, "; - ");
+                                       CHECK_GOTO(BN_print(bp, f));
+                                       BIO_puts(bp, " % ");
+                                       CHECK_GOTO(BN_print(bp, b[j]));
+                                       BIO_puts(bp, "\n");
+                               }
+                       }
+#endif
+                       CHECK_GOTO(BN_GF2m_add(f, e, f));
+                       /* Test that a^(c+d)=a^c*a^d. */
+                       if (!BN_is_zero(f)) {
+                               fprintf(stderr, "GF(2^m) modular exponentiation test failed!\n");
+                               goto err;
+                       }
+               }
+       }
+       rc = 1;
+ err:
+       BN_free(a);
+       BN_free(b[0]);
+       BN_free(b[1]);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       BN_free(f);
+       return rc;
+}
+
+int
+test_gf2m_mod_sqrt(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
+       int i, j, rc = 0;
+       int p0[] = { 163, 7, 6, 3, 0, -1 };
+       int p1[] = { 193, 15, 0, -1 };
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b[0] = BN_new()) == NULL)
+               goto err;
+       if ((b[1] = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+       if ((f = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
+       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
+
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
+               for (j = 0; j < 2; j++) {
+                       CHECK_GOTO(BN_GF2m_mod(c, a, b[j]));
+                       CHECK_GOTO(BN_GF2m_mod_sqrt(d, a, b[j], ctx));
+                       CHECK_GOTO(BN_GF2m_mod_sqr(e, d, b[j], ctx));
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+                       if (bp != NULL) {
+                               if (!results) {
+                                       CHECK_GOTO(BN_print(bp, d));
+                                       BIO_puts(bp, " ^ 2 - ");
+                                       CHECK_GOTO(BN_print(bp, a));
+                                       BIO_puts(bp, "\n");
+                               }
+                       }
+#endif
+                       CHECK_GOTO(BN_GF2m_add(f, c, e));
+                       /* Test that d^2 = a, where d = sqrt(a). */
+                       if (!BN_is_zero(f)) {
+                               fprintf(stderr, "GF(2^m) modular square root test failed!\n");
+                               goto err;
+                       }
+               }
+       }
+       rc = 1;
+ err:
+       BN_free(a);
+       BN_free(b[0]);
+       BN_free(b[1]);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       BN_free(f);
+       return rc;
+}
+
+int
+test_gf2m_mod_solve_quad(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL, *e = NULL;
+       int i, j, s = 0, t, rc = 0;
+       int p0[] = { 163, 7, 6, 3, 0, -1 };
+       int p1[] = { 193, 15, 0, -1 };
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b[0] = BN_new()) == NULL)
+               goto err;
+       if ((b[1] = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
+       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
+
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
+               for (j = 0; j < 2; j++) {
+                       t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
+                       if (t) {
+                               s++;
+                               CHECK_GOTO(BN_GF2m_mod_sqr(d, c, b[j], ctx));
+                               CHECK_GOTO(BN_GF2m_add(d, c, d));
+                               CHECK_GOTO(BN_GF2m_mod(e, a, b[j]));
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+                               if (bp != NULL) {
+                                       if (!results) {
+                                               CHECK_GOTO(BN_print(bp, c));
+                                               BIO_puts(bp, " is root of z^2 + z = ");
+                                               CHECK_GOTO(BN_print(bp, a));
+                                               BIO_puts(bp, " % ");
+                                               CHECK_GOTO(BN_print(bp, b[j]));
+                                               BIO_puts(bp, "\n");
+                                       }
+                               }
+#endif
+                               CHECK_GOTO(BN_GF2m_add(e, e, d));
+                               /* Test that solution of quadratic c satisfies c^2 + c = a. */
+                               if (!BN_is_zero(e)) {
+                                       fprintf(stderr, "GF(2^m) modular solve quadratic test failed!\n");
+                                       goto err;
+                               }
+
+                       } else {
+#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
+                               if (bp != NULL) {
+                                       if (!results) {
+                                               BIO_puts(bp, "There are no roots of z^2 + z = ");
+                                               CHECK_GOTO(BN_print(bp, a));
+                                               BIO_puts(bp, " % ");
+                                               CHECK_GOTO(BN_print(bp, b[j]));
+                                               BIO_puts(bp, "\n");
+                                       }
+                               }
+#endif
+                       }
+               }
+       }
+       if (s == 0) {
+               fprintf(stderr, "All %d tests of GF(2^m) modular solve quadratic resulted in no roots;\n", num0);
+               fprintf(stderr, "this is very unlikely and probably indicates an error.\n");
+               goto err;
+       }
+       rc = 1;
+ err:
+       BN_free(a);
+       BN_free(b[0]);
+       BN_free(b[1]);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       return rc;
+}
+#endif
+static int
+genprime_cb(int p, int n, BN_GENCB *arg)
+{
+       char c = '*';
+
+       if (p == 0)
+               c = '.';
+       if (p == 1)
+               c = '+';
+       if (p == 2)
+               c = '*';
+       if (p == 3)
+               c = '\n';
+       putc(c, stderr);
+       return (1);
+}
+
+int
+test_kron(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b = NULL, *r = NULL, *t = NULL;
+       BN_GENCB *cb = NULL;
+       int i;
+       int legendre, kronecker;
+       int rc = 0;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((r = BN_new()) == NULL)
+               goto err;
+       if ((t = BN_new()) == NULL)
+               goto err;
+
+       if ((cb = BN_GENCB_new()) == NULL)
+               goto err;
+
+       BN_GENCB_set(cb, genprime_cb, NULL);
+
+       /*
+        * We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol). In
+        * this case we know that if b is prime, then BN_kronecker(a, b, ctx) is
+        * congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol). So we
+        * generate a random prime b and compare these values for a number of
+        * random a's.  (That is, we run the Solovay-Strassen primality test to
+        * confirm that b is prime, except that we don't want to test whether b
+        * is prime but whether BN_kronecker works.)
+        */
+
+       if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, cb))
+               goto err;
+       BN_set_negative(b, rand_neg());
+       putc('\n', stderr);
+
+       for (i = 0; i < num0; i++) {
+               if (!BN_bntest_rand(a, 512, 0, 0))
+                       goto err;
+               BN_set_negative(a, rand_neg());
+
+               /* t := (|b|-1)/2  (note that b is odd) */
+               if (!BN_copy(t, b))
+                       goto err;
+               BN_set_negative(t, 0);
+               if (!BN_sub_word(t, 1))
+                       goto err;
+               if (!BN_rshift1(t, t))
+                       goto err;
+               /* r := a^t mod b */
+               BN_set_negative(b, 0);
+
+               if (!BN_mod_exp_recp(r, a, t, b, ctx))
+                       goto err;
+               BN_set_negative(b, 1);
+
+               if (BN_is_word(r, 1))
+                       legendre = 1;
+               else if (BN_is_zero(r))
+                       legendre = 0;
+               else {
+                       if (!BN_add_word(r, 1))
+                               goto err;
+                       if (0 != BN_ucmp(r, b)) {
+                               fprintf(stderr, "Legendre symbol computation failed\n");
+                               goto err;
+                       }
+                       legendre = -1;
+               }
+
+               kronecker = BN_kronecker(a, b, ctx);
+               if (kronecker < -1)
+                       goto err;
+               /* we actually need BN_kronecker(a, |b|) */
+               if (BN_is_negative(a) && BN_is_negative(b))
+                       kronecker = -kronecker;
+
+               if (legendre != kronecker) {
+                       fprintf(stderr, "legendre != kronecker; a = ");
+                       CHECK_GOTO(BN_print_fp(stderr, a));
+                       fprintf(stderr, ", b = ");
+                       CHECK_GOTO(BN_print_fp(stderr, b));
+                       fprintf(stderr, "\n");
+                       goto err;
+               }
+
+               putc('.', stderr);
+       }
+
+       putc('\n', stderr);
+       rc = 1;
+
+ err:
+       BN_GENCB_free(cb);
+       BN_free(a);
+       BN_free(b);
+       BN_free(r);
+       BN_free(t);
+       return rc;
+}
+
+int
+test_sqrt(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *p = NULL, *r = NULL;
+       BN_GENCB *cb = NULL;
+       int i, j;
+       int rc = 0;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((p = BN_new()) == NULL)
+               goto err;
+       if ((r = BN_new()) == NULL)
+               goto err;
+
+       if ((cb = BN_GENCB_new()) == NULL)
+               goto err;
+
+       BN_GENCB_set(cb, genprime_cb, NULL);
+
+       for (i = 0; i < 16; i++) {
+               if (i < 8) {
+                       unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
+
+                       if (!BN_set_word(p, primes[i]))
+                               goto err;
+               } else {
+                       if (!BN_set_word(a, 32))
+                               goto err;
+                       if (!BN_set_word(r, 2 * i + 1))
+                               goto err;
+
+                       if (!BN_generate_prime_ex(p, 256, 0, a, r, cb))
+                               goto err;
+                       putc('\n', stderr);
+               }
+               BN_set_negative(p, rand_neg());
+
+               for (j = 0; j < num2; j++) {
+                       /*
+                        * construct 'a' such that it is a square modulo p, but in
+                        * general not a proper square and not reduced modulo p
+                        */
+                       if (!BN_bntest_rand(r, 256, 0, 3))
+                               goto err;
+                       if (!BN_nnmod(r, r, p, ctx))
+                               goto err;
+                       if (!BN_mod_sqr(r, r, p, ctx))
+                               goto err;
+                       if (!BN_bntest_rand(a, 256, 0, 3))
+                               goto err;
+                       if (!BN_nnmod(a, a, p, ctx))
+                               goto err;
+                       if (!BN_mod_sqr(a, a, p, ctx))
+                               goto err;
+                       if (!BN_mul(a, a, r, ctx))
+                               goto err;
+                       if (rand_neg())
+                               if (!BN_sub(a, a, p))
+                                       goto err;
+
+                       if (!BN_mod_sqrt(r, a, p, ctx))
+                               goto err;
+                       if (!BN_mod_sqr(r, r, p, ctx))
+                               goto err;
+
+                       if (!BN_nnmod(a, a, p, ctx))
+                               goto err;
+
+                       if (BN_cmp(a, r) != 0) {
+                               fprintf(stderr, "BN_mod_sqrt failed: a = ");
+                               CHECK_GOTO(BN_print_fp(stderr, a));
+                               fprintf(stderr, ", r = ");
+                               CHECK_GOTO(BN_print_fp(stderr, r));
+                               fprintf(stderr, ", p = ");
+                               CHECK_GOTO(BN_print_fp(stderr, p));
+                               fprintf(stderr, "\n");
+                               goto err;
+                       }
+
+                       putc('.', stderr);
+               }
+
+               putc('\n', stderr);
+       }
+       rc = 1;
+
+ err:
+       BN_GENCB_free(cb);
+       BN_free(a);
+       BN_free(p);
+       BN_free(r);
+       return rc;
+}
+
+int
+test_lshift(BIO *bp, BN_CTX *ctx, BIGNUM *a_)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL;
+       int i;
+       int rc = 1;
+
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       CHECK_GOTO(BN_one(c));
+
+       if (a_)
+               a = a_;
+       else {
+               if ((a = BN_new()) == NULL)
+               goto err;
+               CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0));
+               BN_set_negative(a, rand_neg());
+       }
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_lshift(b, a, i + 1));
+               CHECK_GOTO(BN_add(c, c, c));
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " * ");
+                               CHECK_GOTO(BN_print(bp, c));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, b));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_mul(d, a, c, ctx));
+               CHECK_GOTO(BN_sub(d, d, b));
+               if (!BN_is_zero(d)) {
+                       fprintf(stderr, "Left shift test failed!\n");
+                       fprintf(stderr, "a=");
+                       CHECK_GOTO(BN_print_fp(stderr, a));
+                       fprintf(stderr, "\nb=");
+                       CHECK_GOTO(BN_print_fp(stderr, b));
+                       fprintf(stderr, "\nc=");
+                       CHECK_GOTO(BN_print_fp(stderr, c));
+                       fprintf(stderr, "\nd=");
+                       CHECK_GOTO(BN_print_fp(stderr, d));
+                       fprintf(stderr, "\n");
+                       rc = 0;
+                       break;
+               }
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       BN_free(d);
+       return (rc);
+}
+
+int
+test_lshift1(BIO *bp)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL;
+       int i;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0));
+       BN_set_negative(a, rand_neg());
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_lshift1(b, a));
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " * 2");
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, b));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_add(c, a, a));
+               CHECK_GOTO(BN_sub(a, b, c));
+               if (!BN_is_zero(a)) {
+                       fprintf(stderr, "Left shift one test failed!\n");
+                       rc = 0;
+                       break;
+               }
+
+               CHECK_GOTO(BN_copy(a, b));
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       return (rc);
+}
+
+int
+test_rshift(BIO *bp, BN_CTX *ctx)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
+       int i;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+       if ((d = BN_new()) == NULL)
+               goto err;
+       if ((e = BN_new()) == NULL)
+               goto err;
+       CHECK_GOTO(BN_one(c));
+
+       CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0));
+       BN_set_negative(a, rand_neg());
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_rshift(b, a, i + 1));
+               CHECK_GOTO(BN_add(c, c, c));
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " / ");
+                               CHECK_GOTO(BN_print(bp, c));
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, b));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_div(d, e, a, c, ctx));
+               CHECK_GOTO(BN_sub(d, d, b));
+               if (!BN_is_zero(d)) {
+                       fprintf(stderr, "Right shift test failed!\n");
+                       rc = 0;
+                       break;
+               }
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       return (rc);
+}
+
+int
+test_rshift1(BIO *bp)
+{
+       BIGNUM *a = NULL, *b = NULL, *c = NULL;
+       int i;
+       int rc = 1;
+
+       if ((a = BN_new()) == NULL)
+               goto err;
+       if ((b = BN_new()) == NULL)
+               goto err;
+       if ((c = BN_new()) == NULL)
+               goto err;
+
+       CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0));
+       BN_set_negative(a, rand_neg());
+       for (i = 0; i < num0; i++) {
+               CHECK_GOTO(BN_rshift1(b, a));
+               if (bp != NULL) {
+                       if (!results) {
+                               CHECK_GOTO(BN_print(bp, a));
+                               BIO_puts(bp, " / 2");
+                               BIO_puts(bp, " - ");
+                       }
+                       CHECK_GOTO(BN_print(bp, b));
+                       BIO_puts(bp, "\n");
+               }
+               CHECK_GOTO(BN_sub(c, a, b));
+               CHECK_GOTO(BN_sub(c, c, b));
+               if (!BN_is_zero(c) && !BN_abs_is_word(c, 1)) {
+                       fprintf(stderr, "Right shift one test failed!\n");
+                       rc = 0;
+                       break;
+               }
+               CHECK_GOTO(BN_copy(a, b));
+       }
+ err:
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       return (rc);
+}
+
+int
+rand_neg(void)
+{
+       static unsigned int neg = 0;
+       static int sign[8] = { 0, 0, 0, 1, 1, 0, 1, 1 };
+
+       return (sign[(neg++) % 8]);
+}
+
+int
+test_mod_exp_sizes(BIO *bp, BN_CTX *ctx)
+{
+       BN_MONT_CTX *mont_ctx = NULL;
+       BIGNUM *p = NULL, *x = NULL, *y = NULL, *r = NULL, *r2 = NULL;
+       int size;
+       int rc = 0;
+
+       BN_CTX_start(ctx);
+       CHECK_GOTO(p = BN_CTX_get(ctx));
+       CHECK_GOTO(x = BN_CTX_get(ctx));
+       CHECK_GOTO(y = BN_CTX_get(ctx));
+       CHECK_GOTO(r = BN_CTX_get(ctx));
+       CHECK_GOTO(r2 = BN_CTX_get(ctx));
+       mont_ctx = BN_MONT_CTX_new();
+
+       if (r2 == NULL || mont_ctx == NULL)
+               goto err;
+
+       if (!BN_generate_prime_ex(p, 32, 0, NULL, NULL, NULL) ||
+           !BN_MONT_CTX_set(mont_ctx, p, ctx))
+               goto err;
+
+       for (size = 32; size < 1024; size += 8) {
+               if (!BN_rand(x, size, -1, 0) ||
+                   !BN_rand(y, size, -1, 0) ||
+                   !BN_mod_exp_mont_consttime(r, x, y, p, ctx, mont_ctx) ||
+                   !BN_mod_exp(r2, x, y, p, ctx))
+                       goto err;
+
+               if (BN_cmp(r, r2) != 0) {
+                       char *r_str = NULL;
+                       char *r2_str = NULL;
+                       CHECK_GOTO(r_str = BN_bn2hex(r));
+                       CHECK_GOTO(r2_str = BN_bn2hex(r2));
+
+                       printf("Incorrect answer at size %d: %s vs %s\n",
+                           size, r_str, r2_str);
+                       free(r_str);
+                       free(r2_str);
+                       goto err;
+               }
+       }
+
+       rc = 1;
+
+ err:
+       BN_MONT_CTX_free(mont_ctx);
+       BN_CTX_end(ctx);
+       return rc;
+}
diff --git a/regress/lib/libcrypto/bn/bn_to_string.c b/regress/lib/libcrypto/bn/bn_to_string.c
new file mode 100644 (file)
index 0000000..ca5ca2f
--- /dev/null
@@ -0,0 +1,115 @@
+/*     $OpenBSD: bn_to_string.c,v 1.1 2022/12/01 20:50:10 tb Exp $ */
+/*
+ * Copyright (c) 2019 Theo Buehler <tb@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <err.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+
+char *bn_to_string(const BIGNUM *bn);
+
+struct convert_st {
+       const char      *input;
+       const char      *expected;
+};
+
+struct convert_st testcases[] = {
+       {"0", "0"},
+       {"-0", "-0"},
+       {"7", "7"},
+       {"-7", "-7"},
+       {"8", "8"},
+       {"-8", "-8"},
+       {"F", "15"},
+       {"-F", "-15"},
+       {"10", "16"},
+       {"-10", "-16"},
+       {"7F", "127"},
+       {"-7F", "-127"},
+       {"80", "128"},
+       {"-80", "-128"},
+       {"FF", "255"},
+       {"-FF", "-255"},
+       {"100", "256"},
+       {"7FFF", "32767"},
+       {"-7FFF", "-32767"},
+       {"8000", "32768"},
+       {"-8000", "-32768"},
+       {"FFFF", "65535"},
+       {"-FFFF", "-65535"},
+       {"10000", "65536"},
+       {"-10000", "-65536"},
+       {"7FFFFFFF", "2147483647"},
+       {"-7FFFFFFF", "-2147483647"},
+       {"80000000", "2147483648"},
+       {"-80000000", "-2147483648"},
+       {"FFFFFFFF", "4294967295"},
+       {"-FFFFFFFF", "-4294967295"},
+       {"100000000", "4294967296"},
+       {"-100000000", "-4294967296"},
+       {"7FFFFFFFFFFFFFFF", "9223372036854775807"},
+       {"-7FFFFFFFFFFFFFFF", "-9223372036854775807"},
+       {"8000000000000000", "9223372036854775808"},
+       {"-8000000000000000", "-9223372036854775808"},
+       {"FFFFFFFFFFFFFFFF", "18446744073709551615"},
+       {"-FFFFFFFFFFFFFFFF", "-18446744073709551615"},
+       {"10000000000000000", "18446744073709551616"},
+       {"-10000000000000000", "-18446744073709551616"},
+       {"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+           "170141183460469231731687303715884105727"},
+       {"-7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+           "-170141183460469231731687303715884105727"},
+       {"80000000000000000000000000000000",
+           "0x80000000000000000000000000000000"},
+       {"-80000000000000000000000000000000",
+           "-0x80000000000000000000000000000000"},
+       {"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+           "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"},
+       {"-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+           "-0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"},
+       {"100000000000000000000000000000000",
+           "0x0100000000000000000000000000000000"},
+       {"-100000000000000000000000000000000",
+           "-0x0100000000000000000000000000000000"},
+       { NULL, NULL },
+};
+
+int
+main(int argc, char *argv[])
+{
+       struct convert_st       *test;
+       BIGNUM                  *bn = NULL;
+       char                    *bnstr;
+       int                      failed = 0;
+
+       for (test = testcases; test->input != NULL; test++) {
+               if (!BN_hex2bn(&bn, test->input))
+                       errx(1, "BN_hex2bn(%s)", test->input);
+               if ((bnstr = bn_to_string(bn)) == NULL)
+                       errx(1, "bn_to_string(%s)", test->input);
+               if (strcmp(bnstr, test->expected) != 0) {
+                       warnx("%s != %s", bnstr, test->expected);
+                       failed = 1;
+               }
+               free(bnstr);
+       }
+
+       BN_free(bn);
+
+       return failed;
+}
diff --git a/regress/lib/libcrypto/bn/bn_unit.c b/regress/lib/libcrypto/bn/bn_unit.c
new file mode 100644 (file)
index 0000000..b4e4a77
--- /dev/null
@@ -0,0 +1,79 @@
+/*     $OpenBSD: bn_unit.c,v 1.1 2022/12/01 20:50:10 tb Exp $ */
+
+/*
+ * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <err.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+
+static int
+test_bn_print_wrapper(char *a, size_t size, const char *descr,
+    int (*to_bn)(BIGNUM **, const char *))
+{
+       int ret;
+
+       ret = to_bn(NULL, a);
+       if (ret != 0 && (ret < 0 || (size_t)ret != size - 1)) {
+               fprintf(stderr, "unexpected %s() return"
+                   "want 0 or %zu, got %d\n", descr, size - 1, ret);
+               return 1;
+       }
+
+       return 0;
+}
+
+static int
+test_bn_print_null_derefs(void)
+{
+       size_t size = INT_MAX / 4 + 4;
+       size_t datalimit = (size + 500 * 1024) / 1024;
+       char *a;
+       char digit;
+       int failed = 0;
+
+       if ((a = malloc(size)) == NULL) {
+               warn("malloc(%zu) failed (make sure data limit is >= %zu KiB)",
+                   size, datalimit);
+               return 0;
+       }
+
+       /* Fill with a random digit since coverity doesn't like us using '0'. */
+       digit = '0' + arc4random_uniform(10);
+
+       memset(a, digit, size - 1);
+       a[size - 1] = '\0';
+
+       failed |= test_bn_print_wrapper(a, size, "BN_dec2bn", BN_dec2bn);
+       failed |= test_bn_print_wrapper(a, size, "BN_hex2bn", BN_hex2bn);
+
+       free(a);
+
+       return failed;
+}
+
+int
+main(void)
+{
+       int failed = 0;
+
+       failed |= test_bn_print_null_derefs();
+
+       return failed;
+}
diff --git a/regress/lib/libcrypto/bn/general/Makefile b/regress/lib/libcrypto/bn/general/Makefile
deleted file mode 100644 (file)
index 22f3e3f..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#      $OpenBSD: Makefile,v 1.16 2022/11/22 08:56:33 tb Exp $
-
-.include "../../Makefile.inc"
-
-PROGS +=       bntest
-PROGS +=       bn_isqrt
-PROGS +=       bn_mod_exp2_mont
-PROGS +=       bn_mod_sqrt
-PROGS +=       bn_primes
-PROGS +=       bn_to_string
-PROGS +=       bn_unit
-
-DPADD +=       ${LIBCRYPTO}
-LDFLAGS +=     -lcrypto
-WARNINGS =     Yes
-CFLAGS +=      -Werror
-CFLAGS +=      -I${.CURDIR}/../../../../../lib/libcrypto/bn/
-CLEANFILES =   bntest.out bc.out
-
-LDADD_bntest = ${CRYPTO_INT}
-REGRESS_TARGETS += run-bntest
-run-bntest bntest.out: bntest
-       ./bntest -out bntest.out
-
-REGRESS_TARGETS += run-bc
-run-bc: bntest.out
-       bc < bntest.out | tee bc.out | grep -v '^0$$'
-       ! grep -v '^test ' <bc.out | grep -v '^0$$'
-
-REGRESS_TARGETS += run-bn_mod_exp2_mont
-run-bn_mod_exp2_mont: bn_mod_exp2_mont
-       ./bn_mod_exp2_mont
-
-REGRESS_TARGETS += run-bn_mod_sqrt
-run-bn_mod_sqrt: bn_mod_sqrt
-       ./bn_mod_sqrt
-
-LDADD_bn_primes = ${CRYPTO_INT}
-REGRESS_TARGETS += run-bn_primes
-run-bn_primes: bn_primes
-       ./bn_primes
-
-LDADD_bn_to_string = ${CRYPTO_INT}
-REGRESS_TARGETS += run-bn_to_string
-run-bn_to_string: bn_to_string
-       ./bn_to_string
-
-REGRESS_TARGETS += run-bn_unit
-run-bn_unit: bn_unit
-       ./bn_unit
-
-
-LDADD_bn_isqrt = ${CRYPTO_INT}
-REGRESS_TARGETS += run-bn_isqrt
-run-bn_isqrt: bn_isqrt
-       ./bn_isqrt
-
-print-tables: bn_isqrt
-       @./bn_isqrt -C
-
-.include <bsd.regress.mk>
diff --git a/regress/lib/libcrypto/bn/general/bn_isqrt.c b/regress/lib/libcrypto/bn/general/bn_isqrt.c
deleted file mode 100644 (file)
index b0ec80b..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-/*     $OpenBSD: bn_isqrt.c,v 1.9 2022/12/01 13:49:12 tb Exp $ */
-/*
- * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <err.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <openssl/bn.h>
-
-#include "bn_local.h"
-
-#define N_TESTS                400
-
-/* Sample squares between 2^128 and 2^4096. */
-#define LOWER_BITS     128
-#define UPPER_BITS     4096
-
-extern const uint8_t is_square_mod_11[];
-extern const uint8_t is_square_mod_63[];
-extern const uint8_t is_square_mod_64[];
-extern const uint8_t is_square_mod_65[];
-
-static void
-hexdump(const unsigned char *buf, size_t len)
-{
-       size_t i;
-
-       for (i = 1; i <= len; i++)
-               fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
-
-       if (len % 8)
-               fprintf(stderr, "\n");
-}
-
-static const uint8_t *
-get_table(int modulus)
-{
-       switch (modulus) {
-       case 11:
-               return is_square_mod_11;
-       case 63:
-               return is_square_mod_63;
-       case 64:
-               return is_square_mod_64;
-       case 65:
-               return is_square_mod_65;
-       default:
-               return NULL;
-       }
-}
-
-static int
-check_tables(int print)
-{
-       int fill[] = {11, 63, 64, 65};
-       const uint8_t *table;
-       uint8_t q[65];
-       size_t i;
-       int j;
-       int failed = 0;
-
-       for (i = 0; i < sizeof(fill) / sizeof(fill[0]); i++) {
-               memset(q, 0, sizeof(q));
-
-               for (j = 0; j < fill[i]; j++)
-                       q[(j * j) % fill[i]] = 1;
-
-               if ((table = get_table(fill[i])) == NULL) {
-                       fprintf(stderr, "failed to get table %d\n", fill[i]);
-                       failed |= 1;
-                       continue;
-               }
-
-               if (memcmp(table, q, fill[i]) != 0) {
-                       fprintf(stderr, "table %d does not match:\n", fill[i]);
-                       fprintf(stderr, "want:\n");
-                       hexdump(table, fill[i]);
-                       fprintf(stderr, "got:\n");
-                       hexdump(q, fill[i]);
-                       failed |= 1;
-                       continue;
-               }
-
-               if (!print)
-                       continue;
-
-               printf("const uint8_t is_square_mod_%d[] = {\n\t", fill[i]);
-               for (j = 0; j < fill[i]; j++) {
-                       const char *end = " ";
-
-                       if (j % 16 == 15)
-                               end = "\n\t";
-                       if (j + 1 == fill[i])
-                               end = "";
-
-                       printf("%d,%s", q[j], end);
-               }
-               printf("\n};\nCTASSERT(sizeof(is_square_mod_%d) == %d);\n\n",
-                   fill[i], fill[i]);
-       }
-
-       return failed;
-}
-
-static int
-validate_tables(void)
-{
-       int fill[] = {11, 63, 64, 65};
-       const uint8_t *table;
-       size_t i;
-       int j, k;
-       int failed = 0;
-
-       for (i = 0; i < sizeof(fill) / sizeof(fill[0]); i++) {
-               if ((table = get_table(fill[i])) == NULL) {
-                       fprintf(stderr, "failed to get table %d\n", fill[i]);
-                       failed |= 1;
-                       continue;
-               }
-
-               for (j = 0; j < fill[i]; j++) {
-                       for (k = 0; k < fill[i]; k++) {
-                               if (j == (k * k) % fill[i])
-                                       break;
-                       }
-
-                       if (table[j] == 0 && k < fill[i]) {
-                               fprintf(stderr, "%d == %d^2 (mod %d)", j, k,
-                                   fill[i]);
-                               failed |= 1;
-                       }
-                       if (table[j] == 1 && k == fill[i]) {
-                               fprintf(stderr, "%d not a square (mod %d)", j,
-                                   fill[i]);
-                               failed |= 1;
-                       }
-               }
-       }
-
-       return failed;
-}
-
-/*
- * Choose a random number n of bit length between LOWER_BITS and UPPER_BITS and
- * check that n == isqrt(n^2). Random numbers n^2 <= testcase < (n + 1)^2 are
- * checked to have isqrt(testcase) == n.
- */
-static int
-isqrt_test(void)
-{
-       BN_CTX *ctx;
-       BIGNUM *n, *n_sqr, *lower, *upper, *testcase, *isqrt;
-       int cmp, i, is_perfect_square;
-       int failed = 0;
-
-       if ((ctx = BN_CTX_new()) == NULL)
-               errx(1, "BN_CTX_new");
-
-       BN_CTX_start(ctx);
-
-       if ((lower = BN_CTX_get(ctx)) == NULL)
-               errx(1, "lower = BN_CTX_get(ctx)");
-       if ((upper = BN_CTX_get(ctx)) == NULL)
-               errx(1, "upper = BN_CTX_get(ctx)");
-       if ((n = BN_CTX_get(ctx)) == NULL)
-               errx(1, "n = BN_CTX_get(ctx)");
-       if ((n_sqr = BN_CTX_get(ctx)) == NULL)
-               errx(1, "n = BN_CTX_get(ctx)");
-       if ((isqrt = BN_CTX_get(ctx)) == NULL)
-               errx(1, "result = BN_CTX_get(ctx)");
-       if ((testcase = BN_CTX_get(ctx)) == NULL)
-               errx(1, "testcase = BN_CTX_get(ctx)");
-
-       /* lower = 2^LOWER_BITS, upper = 2^UPPER_BITS. */
-       if (!BN_set_bit(lower, LOWER_BITS))
-               errx(1, "BN_set_bit(lower, %d)", LOWER_BITS);
-       if (!BN_set_bit(upper, UPPER_BITS))
-               errx(1, "BN_set_bit(upper, %d)", UPPER_BITS);
-
-       if (!bn_rand_interval(n, lower, upper))
-               errx(1, "bn_rand_interval n");
-
-       /* n_sqr = n^2 */
-       if (!BN_sqr(n_sqr, n, ctx))
-               errx(1, "BN_sqr");
-
-       if (!bn_isqrt(isqrt, &is_perfect_square, n_sqr, ctx))
-               errx(1, "bn_isqrt n_sqr");
-
-       if ((cmp = BN_cmp(n, isqrt)) != 0 || !is_perfect_square) {
-               fprintf(stderr, "n = ");
-               BN_print_fp(stderr, n);
-               fprintf(stderr, "\nn^2 is_perfect_square: %d, cmp: %d\n",
-                   is_perfect_square, cmp);
-               failed = 1;
-       }
-
-       /* upper = 2 * n + 1 */
-       if (!BN_lshift1(upper, n))
-               errx(1, "BN_lshift1(upper, n)");
-       if (!BN_add_word(upper, 1))
-               errx(1, "BN_sub_word(upper, 1)");
-
-       /* upper = (n + 1)^2 = n^2 + upper */
-       if (!BN_add(upper, n_sqr, upper))
-               errx(1, "BN_add");
-
-       /*
-        * Check that isqrt((n + 1)^2) - 1 == n.
-        */
-
-       if (!bn_isqrt(isqrt, &is_perfect_square, upper, ctx))
-               errx(1, "bn_isqrt(upper)");
-
-       if (!BN_sub_word(isqrt, 1))
-               errx(1, "BN_add_word(isqrt, 1)");
-
-       if ((cmp = BN_cmp(n, isqrt)) != 0 || !is_perfect_square) {
-               fprintf(stderr, "n = ");
-               BN_print_fp(stderr, n);
-               fprintf(stderr, "\n(n + 1)^2 is_perfect_square: %d, cmp: %d\n",
-                   is_perfect_square, cmp);
-               failed = 1;
-       }
-
-       /*
-        * Test N_TESTS random numbers n^2 <= testcase < (n + 1)^2 and check
-        * that their isqrt is n.
-        */
-
-       for (i = 0; i < N_TESTS; i++) {
-               if (!bn_rand_interval(testcase, n_sqr, upper))
-                       errx(1, "bn_rand_interval testcase");
-
-               if (!bn_isqrt(isqrt, &is_perfect_square, testcase, ctx))
-                       errx(1, "bn_isqrt testcase");
-
-               if ((cmp = BN_cmp(n, isqrt)) != 0 ||
-                   (is_perfect_square && BN_cmp(n_sqr, testcase) != 0)) {
-                       fprintf(stderr, "n = ");
-                       BN_print_fp(stderr, n);
-                       fprintf(stderr, "\ntestcase = ");
-                       BN_print_fp(stderr, testcase);
-                       fprintf(stderr,
-                           "\ntestcase is_perfect_square: %d, cmp: %d\n",
-                           is_perfect_square, cmp);
-                       failed = 1;
-               }
-       }
-
-       /*
-        * Finally check that isqrt(n^2 - 1) + 1 == n.
-        */
-
-       if (!BN_sub(testcase, n_sqr, BN_value_one()))
-               errx(1, "BN_sub(testcase, n_sqr, 1)");
-
-       if (!bn_isqrt(isqrt, &is_perfect_square, testcase, ctx))
-               errx(1, "bn_isqrt(n_sqr - 1)");
-
-       if (!BN_add_word(isqrt, 1))
-               errx(1, "BN_add_word(isqrt, 1)");
-
-       if ((cmp = BN_cmp(n, isqrt)) != 0 || is_perfect_square) {
-               fprintf(stderr, "n = ");
-               BN_print_fp(stderr, n);
-               fprintf(stderr, "\nn_sqr - 1 is_perfect_square: %d, cmp: %d\n",
-                   is_perfect_square, cmp);
-               failed = 1;
-       }
-
-       BN_CTX_end(ctx);
-       BN_CTX_free(ctx);
-
-       return failed;
-}
-
-static void
-usage(void)
-{
-       fprintf(stderr, "usage: bn_isqrt [-C]\n");
-       exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
-       size_t i;
-       int ch;
-       int failed = 0, print = 0;
-
-       while ((ch = getopt(argc, argv, "C")) != -1) {
-               switch (ch) {
-               case 'C':
-                       print = 1;
-                       break;
-               default:
-                       usage();
-                       break;
-               }
-       }
-
-       if (print)
-               return check_tables(1);
-
-       for (i = 0; i < N_TESTS; i++)
-               failed |= isqrt_test();
-
-       failed |= check_tables(0);
-       failed |= validate_tables();
-
-       return failed;
-}
diff --git a/regress/lib/libcrypto/bn/general/bn_mod_exp2_mont.c b/regress/lib/libcrypto/bn/general/bn_mod_exp2_mont.c
deleted file mode 100644 (file)
index f0ebfcb..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*     $OpenBSD: bn_mod_exp2_mont.c,v 1.2 2022/12/01 13:49:12 tb Exp $ */
-/*
- * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <err.h>
-
-#include <openssl/bn.h>
-
-/*
- * Small test for a crash reported by Guido Vranken, fixed in bn_exp2.c r1.13.
- * https://github.com/openssl/openssl/issues/17648
- */
-
-int
-main(void)
-{
-       BIGNUM *m;
-
-       if ((m = BN_new()) == NULL)
-               errx(1, "BN_new");
-
-       BN_zero_ex(m);
-
-       if (BN_mod_exp2_mont(NULL, NULL, NULL, NULL, NULL, m, NULL, NULL))
-               errx(1, "BN_mod_exp2_mont succeeded");
-
-       BN_free(m);
-
-       return 0;
-}
diff --git a/regress/lib/libcrypto/bn/general/bn_mod_sqrt.c b/regress/lib/libcrypto/bn/general/bn_mod_sqrt.c
deleted file mode 100644 (file)
index 71e27a3..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*     $OpenBSD: bn_mod_sqrt.c,v 1.2 2022/12/01 13:49:12 tb Exp $ */
-/*
- * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <openssl/bn.h>
-
-/* Test that sqrt * sqrt = A (mod p) where p is a prime */
-struct mod_sqrt_test {
-       const char *sqrt;
-       const char *a;
-       const char *p;
-       int bn_mod_sqrt_fails;
-} mod_sqrt_test_data[] = {
-       {
-               .sqrt = "1",
-               .a = "1",
-               .p = "2",
-               .bn_mod_sqrt_fails = 0,
-       },
-       {
-               .sqrt = "-1",
-               .a = "20a7ee",
-               .p = "460201", /* 460201 == 4D5 * E7D */
-               .bn_mod_sqrt_fails = 1,
-       },
-       {
-               .sqrt = "-1",
-               .a = "65bebdb00a96fc814ec44b81f98b59fba3c30203928fa521"
-                    "4c51e0a97091645280c947b005847f239758482b9bfc45b0"
-                    "66fde340d1fe32fc9c1bf02e1b2d0ed",
-               .p = "9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e2"
-                    "46b41c32f71e951f",
-               .bn_mod_sqrt_fails = 1,
-       },
-};
-
-const size_t N_TESTS = sizeof(mod_sqrt_test_data) / sizeof(*mod_sqrt_test_data);
-
-int mod_sqrt_test(struct mod_sqrt_test *test);
-
-int
-mod_sqrt_test(struct mod_sqrt_test *test)
-{
-       BN_CTX *ctx = NULL;
-       BIGNUM *a = NULL, *p = NULL, *want = NULL, *got = NULL, *diff = NULL;
-       int failed = 1;
-
-       if ((ctx = BN_CTX_new()) == NULL) {
-               fprintf(stderr, "BN_CTX_new failed\n");
-               goto out;
-       }
-
-       if (!BN_hex2bn(&a, test->a)) {
-               fprintf(stderr, "BN_hex2bn(a) failed\n");
-               goto out;
-       }
-       if (!BN_hex2bn(&p, test->p)) {
-               fprintf(stderr, "BN_hex2bn(p) failed\n");
-               goto out;
-       }
-       if (!BN_hex2bn(&want, test->sqrt)) {
-               fprintf(stderr, "BN_hex2bn(want) failed\n");
-               goto out;
-       }
-
-       if (((got = BN_mod_sqrt(NULL, a, p, ctx)) == NULL) !=
-          test->bn_mod_sqrt_fails) {
-               fprintf(stderr, "BN_mod_sqrt %s unexpectedly\n",
-                   test->bn_mod_sqrt_fails ? "succeeded" : "failed");
-               goto out;
-       }
-
-       if (test->bn_mod_sqrt_fails) {
-               failed = 0;
-               goto out;
-       }
-
-       if ((diff = BN_new()) == NULL) {
-               fprintf(stderr, "diff = BN_new() failed\n");
-               goto out;
-       }
-
-       if (!BN_mod_sub(diff, want, got, p, ctx)) {
-               fprintf(stderr, "BN_mod_sub failed\n");
-               goto out;
-       }
-
-       if (!BN_is_zero(diff)) {
-               fprintf(stderr, "want != got\n");
-               goto out;
-       }
-
-       failed = 0;
-
- out:
-       BN_CTX_free(ctx);
-       BN_free(a);
-       BN_free(p);
-       BN_free(want);
-       BN_free(got);
-       BN_free(diff);
-
-       return failed;
-}
-
-int
-main(void)
-{
-       size_t i;
-       int failed = 0;
-
-       for (i = 0; i < N_TESTS; i++)
-               failed |= mod_sqrt_test(&mod_sqrt_test_data[i]);
-
-       return failed;
-}
diff --git a/regress/lib/libcrypto/bn/general/bn_primes.c b/regress/lib/libcrypto/bn/general/bn_primes.c
deleted file mode 100644 (file)
index e637932..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*     $OpenBSD: bn_primes.c,v 1.4 2022/12/01 14:32:06 tb Exp $ */
-/*
- * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <openssl/bn.h>
-
-#include "bn_prime.h"
-
-static int
-test_bn_is_prime_fasttest(int do_trial_division)
-{
-       BIGNUM *n = NULL;
-       char *descr = NULL;
-       uint16_t i, j, max;
-       int is_prime, ret;
-       int failed = 1;
-
-       if (asprintf(&descr, "with%s trial divisions",
-           do_trial_division ? "" : "out") == -1) {
-               descr = NULL;
-               fprintf(stderr, "asprintf failed\n");
-               goto err;
-       }
-
-       if ((n = BN_new()) == NULL) {
-               fprintf(stderr, "BN_new failed\n");
-               goto err;
-       }
-
-       max = primes[NUMPRIMES - 1] + 1;
-
-       failed = 0;
-       for (i = 1, j = 0; i < max && j < NUMPRIMES; i++) {
-               if (!BN_set_word(n, i)) {
-                       fprintf(stderr, "BN_set_word(%d) failed", i);
-                       failed = 1;
-                       goto err;
-               }
-
-               is_prime = i == primes[j];
-               if (is_prime)
-                       j++;
-
-               ret = BN_is_prime_fasttest_ex(n, BN_prime_checks, NULL,
-                   do_trial_division, NULL);
-               if (ret != is_prime) {
-                       fprintf(stderr,
-                           "BN_is_prime_fasttest_ex(%d) %s: want %d, got %d\n",
-                           i, descr, is_prime, ret);
-                       failed = 1;
-               }
-       }
-
-       if (i < max || j < NUMPRIMES) {
-               fprintf(stderr, "%s: %d < %d or %d < %d\n", descr, i, max, j,
-                   NUMPRIMES);
-               failed = 1;
-       }
-
- err:
-       BN_free(n);
-       free(descr);
-       return failed;
-}
-
-#define BN_PRIME_FN_INIT(a) { .fn = a, .name = #a }
-
-static const struct test_dynamic_api {
-       BIGNUM *(*fn)(BIGNUM *);
-       const char *name;
-} dynamic_api_data[] = {
-       BN_PRIME_FN_INIT(BN_get_rfc2409_prime_1024),
-       BN_PRIME_FN_INIT(BN_get_rfc2409_prime_768),
-       BN_PRIME_FN_INIT(BN_get_rfc3526_prime_1536),
-       BN_PRIME_FN_INIT(BN_get_rfc3526_prime_2048),
-       BN_PRIME_FN_INIT(BN_get_rfc3526_prime_3072),
-       BN_PRIME_FN_INIT(BN_get_rfc3526_prime_4096),
-       BN_PRIME_FN_INIT(BN_get_rfc3526_prime_6144),
-       BN_PRIME_FN_INIT(BN_get_rfc3526_prime_8192),
-};
-
-#define N_DYNAMIC_TESTS (sizeof(dynamic_api_data) / sizeof(dynamic_api_data[0]))
-
-static const struct test_const_api {
-       const BIGNUM *(*fn)(void);
-       const char *name;
-} const_api_data[] = {
-       BN_PRIME_FN_INIT(BN_get0_nist_prime_192),
-       BN_PRIME_FN_INIT(BN_get0_nist_prime_224),
-       BN_PRIME_FN_INIT(BN_get0_nist_prime_256),
-       BN_PRIME_FN_INIT(BN_get0_nist_prime_384),
-       BN_PRIME_FN_INIT(BN_get0_nist_prime_521),
-};
-
-#define N_CONST_TESTS (sizeof(const_api_data) / sizeof(const_api_data[0]))
-
-static int
-test_prime_dynamic_api(const struct test_dynamic_api *tc)
-{
-       BIGNUM *prime;
-       int ret;
-       int failed = 1;
-
-       if ((prime = tc->fn(NULL)) == NULL) {
-               fprintf(stderr, "%s failed\n", tc->name);
-               goto err;
-       }
-
-       if ((ret = BN_is_prime_fasttest_ex(prime, 1, NULL, 1, NULL)) != 1) {
-               fprintf(stderr, "%s: %s want 1, got %d\n", tc->name,
-                   "BN_is_prime_fasttest_ex", ret);
-               goto err;
-       }
-
-       failed = 0;
-
- err:
-       BN_free(prime);
-       return failed;
-}
-
-static int
-test_prime_const_api(const struct test_const_api *tc)
-{
-       const BIGNUM *prime;
-       int ret;
-       int failed = 1;
-
-       if ((prime = tc->fn()) == NULL) {
-               fprintf(stderr, "%s failed\n", tc->name);
-               goto err;
-       }
-
-       if ((ret = BN_is_prime_fasttest_ex(prime, 1, NULL, 1, NULL)) != 1) {
-               fprintf(stderr, "%s: %s: want 1, got %d\n", tc->name,
-                   "BN_is_prime_fasttest_ex", ret);
-               goto err;
-       }
-
-       failed = 0;
-
- err:
-       return failed;
-}
-
-static int
-test_prime_constants(void)
-{
-       size_t i;
-       int failed = 0;
-
-       for (i = 0; i < N_DYNAMIC_TESTS; i++)
-               failed |= test_prime_dynamic_api(&dynamic_api_data[i]);
-
-       for (i = 0; i < N_CONST_TESTS; i++)
-               failed |= test_prime_const_api(&const_api_data[i]);
-
-       return failed;
-}
-
-int
-main(void)
-{
-       int failed = 0;
-
-       failed |= test_bn_is_prime_fasttest(0);
-       failed |= test_bn_is_prime_fasttest(1);
-       failed |= test_prime_constants();
-
-       return failed;
-}
diff --git a/regress/lib/libcrypto/bn/general/bn_to_string.c b/regress/lib/libcrypto/bn/general/bn_to_string.c
deleted file mode 100644 (file)
index 901fa98..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*     $OpenBSD: bn_to_string.c,v 1.2 2022/12/01 13:49:12 tb Exp $ */
-/*
- * Copyright (c) 2019 Theo Buehler <tb@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <err.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <openssl/bn.h>
-
-char *bn_to_string(const BIGNUM *bn);
-
-struct convert_st {
-       const char      *input;
-       const char      *expected;
-};
-
-struct convert_st testcases[] = {
-       {"0", "0"},
-       {"-0", "-0"},
-       {"7", "7"},
-       {"-7", "-7"},
-       {"8", "8"},
-       {"-8", "-8"},
-       {"F", "15"},
-       {"-F", "-15"},
-       {"10", "16"},
-       {"-10", "-16"},
-       {"7F", "127"},
-       {"-7F", "-127"},
-       {"80", "128"},
-       {"-80", "-128"},
-       {"FF", "255"},
-       {"-FF", "-255"},
-       {"100", "256"},
-       {"7FFF", "32767"},
-       {"-7FFF", "-32767"},
-       {"8000", "32768"},
-       {"-8000", "-32768"},
-       {"FFFF", "65535"},
-       {"-FFFF", "-65535"},
-       {"10000", "65536"},
-       {"-10000", "-65536"},
-       {"7FFFFFFF", "2147483647"},
-       {"-7FFFFFFF", "-2147483647"},
-       {"80000000", "2147483648"},
-       {"-80000000", "-2147483648"},
-       {"FFFFFFFF", "4294967295"},
-       {"-FFFFFFFF", "-4294967295"},
-       {"100000000", "4294967296"},
-       {"-100000000", "-4294967296"},
-       {"7FFFFFFFFFFFFFFF", "9223372036854775807"},
-       {"-7FFFFFFFFFFFFFFF", "-9223372036854775807"},
-       {"8000000000000000", "9223372036854775808"},
-       {"-8000000000000000", "-9223372036854775808"},
-       {"FFFFFFFFFFFFFFFF", "18446744073709551615"},
-       {"-FFFFFFFFFFFFFFFF", "-18446744073709551615"},
-       {"10000000000000000", "18446744073709551616"},
-       {"-10000000000000000", "-18446744073709551616"},
-       {"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
-           "170141183460469231731687303715884105727"},
-       {"-7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
-           "-170141183460469231731687303715884105727"},
-       {"80000000000000000000000000000000",
-           "0x80000000000000000000000000000000"},
-       {"-80000000000000000000000000000000",
-           "-0x80000000000000000000000000000000"},
-       {"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
-           "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"},
-       {"-FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
-           "-0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"},
-       {"100000000000000000000000000000000",
-           "0x0100000000000000000000000000000000"},
-       {"-100000000000000000000000000000000",
-           "-0x0100000000000000000000000000000000"},
-       { NULL, NULL },
-};
-
-int
-main(int argc, char *argv[])
-{
-       struct convert_st       *test;
-       BIGNUM                  *bn = NULL;
-       char                    *bnstr;
-       int                      failed = 0;
-
-       for (test = testcases; test->input != NULL; test++) {
-               if (!BN_hex2bn(&bn, test->input))
-                       errx(1, "BN_hex2bn(%s)", test->input);
-               if ((bnstr = bn_to_string(bn)) == NULL)
-                       errx(1, "bn_to_string(%s)", test->input);
-               if (strcmp(bnstr, test->expected) != 0) {
-                       warnx("%s != %s", bnstr, test->expected);
-                       failed = 1;
-               }
-               free(bnstr);
-       }
-
-       BN_free(bn);
-
-       return failed;
-}
diff --git a/regress/lib/libcrypto/bn/general/bn_unit.c b/regress/lib/libcrypto/bn/general/bn_unit.c
deleted file mode 100644 (file)
index f2b3652..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*     $OpenBSD: bn_unit.c,v 1.6 2022/12/01 13:49:12 tb Exp $ */
-
-/*
- * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <err.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <openssl/bn.h>
-
-static int
-test_bn_print_wrapper(char *a, size_t size, const char *descr,
-    int (*to_bn)(BIGNUM **, const char *))
-{
-       int ret;
-
-       ret = to_bn(NULL, a);
-       if (ret != 0 && (ret < 0 || (size_t)ret != size - 1)) {
-               fprintf(stderr, "unexpected %s() return"
-                   "want 0 or %zu, got %d\n", descr, size - 1, ret);
-               return 1;
-       }
-
-       return 0;
-}
-
-static int
-test_bn_print_null_derefs(void)
-{
-       size_t size = INT_MAX / 4 + 4;
-       size_t datalimit = (size + 500 * 1024) / 1024;
-       char *a;
-       char digit;
-       int failed = 0;
-
-       if ((a = malloc(size)) == NULL) {
-               warn("malloc(%zu) failed (make sure data limit is >= %zu KiB)",
-                   size, datalimit);
-               return 0;
-       }
-
-       /* Fill with a random digit since coverity doesn't like us using '0'. */
-       digit = '0' + arc4random_uniform(10);
-
-       memset(a, digit, size - 1);
-       a[size - 1] = '\0';
-
-       failed |= test_bn_print_wrapper(a, size, "BN_dec2bn", BN_dec2bn);
-       failed |= test_bn_print_wrapper(a, size, "BN_hex2bn", BN_hex2bn);
-
-       free(a);
-
-       return failed;
-}
-
-int
-main(void)
-{
-       int failed = 0;
-
-       failed |= test_bn_print_null_derefs();
-
-       return failed;
-}
diff --git a/regress/lib/libcrypto/bn/general/bntest.c b/regress/lib/libcrypto/bn/general/bntest.c
deleted file mode 100644 (file)
index b9581a0..0000000
+++ /dev/null
@@ -1,2624 +0,0 @@
-/*     $OpenBSD: bntest.c,v 1.25 2022/09/05 21:06:31 tb Exp $  */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- *
- * Portions of the attached software ("Contribution") are developed by
- * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
- *
- * The Contribution is licensed pursuant to the Eric Young open source
- * license provided above.
- *
- * The binary polynomial arithmetic software is originally written by
- * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
- *
- */
-
-/* Until the key-gen callbacks are modified to use newer prototypes, we allow
- * deprecated functions for openssl-internal code */
-#ifdef OPENSSL_NO_DEPRECATED
-#undef OPENSSL_NO_DEPRECATED
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <openssl/bio.h>
-#include <openssl/bn.h>
-#include <openssl/x509.h>
-#include <openssl/err.h>
-
-int BN_mod_exp_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-    const BIGNUM *m, BN_CTX *ctx);
-int BN_mod_exp_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-    const BIGNUM *m, BN_CTX *ctx);
-int BN_mod_exp_mont_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
-int BN_mod_exp_mont_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
-
-int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom);
-
-const int num0 = 100; /* number of tests */
-const int num1 = 50;  /* additional tests for some functions */
-const int num2 = 5;   /* number of tests for slow functions */
-
-int test_add(BIO *bp);
-int test_sub(BIO *bp);
-int test_lshift1(BIO *bp);
-int test_lshift(BIO *bp, BN_CTX *ctx, BIGNUM *a_);
-int test_rshift1(BIO *bp);
-int test_rshift(BIO *bp, BN_CTX *ctx);
-int test_div(BIO *bp, BN_CTX *ctx);
-int test_div_word(BIO *bp);
-int test_div_recp(BIO *bp, BN_CTX *ctx);
-int test_mul(BIO *bp);
-int test_sqr(BIO *bp, BN_CTX *ctx);
-int test_mont(BIO *bp, BN_CTX *ctx);
-int test_mod(BIO *bp, BN_CTX *ctx);
-int test_mod_mul(BIO *bp, BN_CTX *ctx);
-int test_mod_exp(BIO *bp, BN_CTX *ctx);
-int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx);
-int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx);
-int test_mod_exp_sizes(BIO *bp, BN_CTX *ctx);
-int test_exp(BIO *bp, BN_CTX *ctx);
-int test_gf2m_add(BIO *bp);
-int test_gf2m_mod(BIO *bp);
-int test_gf2m_mod_mul(BIO *bp, BN_CTX *ctx);
-int test_gf2m_mod_sqr(BIO *bp, BN_CTX *ctx);
-int test_gf2m_mod_inv(BIO *bp, BN_CTX *ctx);
-int test_gf2m_mod_div(BIO *bp, BN_CTX *ctx);
-int test_gf2m_mod_exp(BIO *bp, BN_CTX *ctx);
-int test_gf2m_mod_sqrt(BIO *bp, BN_CTX *ctx);
-int test_gf2m_mod_solve_quad(BIO *bp, BN_CTX *ctx);
-int test_kron(BIO *bp, BN_CTX *ctx);
-int test_sqrt(BIO *bp, BN_CTX *ctx);
-int rand_neg(void);
-static int results = 0;
-
-static unsigned char lst[] =
-       "\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
-       "\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
-
-#define PRINT_ERROR printf("Error in %s [%s:%d]\n", __func__, __FILE__,        \
-               __LINE__)
-
-#define CHECK_GOTO(a) do {                                             \
-       if (!(a)) {                                                     \
-               PRINT_ERROR;                                            \
-               rc = 0;                                                 \
-               goto err;                                               \
-       }                                                               \
-} while (0)
-
-static void
-message(BIO *out, char *m)
-{
-       fprintf(stderr, "test %s\n", m);
-       BIO_puts(out, "print \"test ");
-       BIO_puts(out, m);
-       BIO_puts(out, "\\n\"\n");
-}
-
-int
-main(int argc, char *argv[])
-{
-       BN_CTX *ctx;
-       BIO *out;
-       char *outfile = NULL;
-
-       results = 0;
-
-       argc--;
-       argv++;
-       while (argc >= 1) {
-               if (strcmp(*argv, "-results") == 0)
-                       results = 1;
-               else if (strcmp(*argv, "-out") == 0) {
-                       if (--argc < 1)
-                               break;
-                       outfile= *(++argv);
-               }
-               argc--;
-               argv++;
-       }
-
-
-       ctx = BN_CTX_new();
-       if (ctx == NULL)
-               exit(1);
-
-       out = BIO_new(BIO_s_file());
-       if (out == NULL)
-               exit(1);
-       if (outfile == NULL) {
-               BIO_set_fp(out, stdout, BIO_NOCLOSE);
-       } else {
-               if (!BIO_write_filename(out, outfile)) {
-                       perror(outfile);
-                       exit(1);
-               }
-       }
-
-       if (!results)
-               BIO_puts(out, "obase=16\nibase=16\n");
-
-       message(out, "BN_add");
-       if (!test_add(out))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_sub");
-       if (!test_sub(out))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_lshift1");
-       if (!test_lshift1(out))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_lshift (fixed)");
-       if (!test_lshift(out, ctx, BN_bin2bn(lst, sizeof(lst) - 1, NULL)))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_lshift");
-       if (!test_lshift(out, ctx, NULL))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_rshift1");
-       if (!test_rshift1(out))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_rshift");
-       if (!test_rshift(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_sqr");
-       if (!test_sqr(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_mul");
-       if (!test_mul(out))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_div");
-       if (!test_div(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_div_word");
-       if (!test_div_word(out))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_div_recp");
-       if (!test_div_recp(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_mod");
-       if (!test_mod(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_mod_mul");
-       if (!test_mod_mul(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_mont");
-       if (!test_mont(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_mod_exp");
-       if (!test_mod_exp(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_mod_exp_mont_consttime");
-       if (!test_mod_exp_mont_consttime(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_mod_exp_mont5");
-       if (!test_mod_exp_mont5(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_exp");
-       if (!test_exp(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_kronecker");
-       if (!test_kron(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_mod_sqrt");
-       if (!test_sqrt(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "Modexp with different sizes");
-       if (!test_mod_exp_sizes(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-#ifndef OPENSSL_NO_EC2M
-       message(out, "BN_GF2m_add");
-       if (!test_gf2m_add(out))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_GF2m_mod");
-       if (!test_gf2m_mod(out))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_GF2m_mod_mul");
-       if (!test_gf2m_mod_mul(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_GF2m_mod_sqr");
-       if (!test_gf2m_mod_sqr(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_GF2m_mod_inv");
-       if (!test_gf2m_mod_inv(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_GF2m_mod_div");
-       if (!test_gf2m_mod_div(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_GF2m_mod_exp");
-       if (!test_gf2m_mod_exp(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_GF2m_mod_sqrt");
-       if (!test_gf2m_mod_sqrt(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-
-       message(out, "BN_GF2m_mod_solve_quad");
-       if (!test_gf2m_mod_solve_quad(out, ctx))
-               goto err;
-       (void)BIO_flush(out);
-#endif
-       BN_CTX_free(ctx);
-       BIO_free(out);
-
-       exit(0);
- err:
-       BIO_puts(out, "1\n"); /* make sure the Perl script fed by bc notices
-                              * the failure, see test_bn in test/Makefile.ssl*/
-
-       (void)BIO_flush(out);
-       ERR_load_crypto_strings();
-       ERR_print_errors_fp(stderr);
-       exit(1);
-}
-
-int
-test_add(BIO *bp)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL;
-       int i;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_bntest_rand(b, 450 + i, 0, 0));
-               BN_set_negative(a, rand_neg());
-               BN_set_negative(b, rand_neg());
-               CHECK_GOTO(BN_add(c, a, b));
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " + ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, c));
-                       BIO_puts(bp, "\n");
-               }
-               BN_set_negative(a, !BN_is_negative(a));
-               BN_set_negative(b, !BN_is_negative(b));
-               CHECK_GOTO(BN_add(c, c, b));
-               CHECK_GOTO(BN_add(c, c, a));
-               if (!BN_is_zero(c)) {
-                       fprintf(stderr, "Add test failed!\n");
-                       rc = 0;
-                       break;
-               }
-       }
-
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-
-       return rc;
-}
-
-int
-test_sub(BIO *bp)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL;
-       int i;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-
-       for (i = 0; i < num0 + num1; i++) {
-               if (i < num1) {
-                       CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
-                       CHECK_GOTO(BN_copy(b, a));
-                       if (BN_set_bit(a, i) == 0) {
-                               rc = 0;
-                               break;
-                       }
-                       CHECK_GOTO(BN_add_word(b, i));
-               } else {
-                       CHECK_GOTO(BN_bntest_rand(b, 400 + i - num1, 0, 0));
-                       BN_set_negative(a, rand_neg());
-                       BN_set_negative(b, rand_neg());
-               }
-               CHECK_GOTO(BN_sub(c, a, b));
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " - ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, c));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_add(c, c, b));
-               CHECK_GOTO(BN_sub(c, c, a));
-               if (!BN_is_zero(c)) {
-                       fprintf(stderr, "Subtract test failed!\n");
-                       rc = 0;
-                       break;
-               }
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       return (rc);
-}
-
-int
-test_div(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
-       int i;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_one(a));
-       CHECK_GOTO(BN_zero(b));
-
-       if (BN_div(d, c, a, b, ctx)) {
-               fprintf(stderr, "Division by zero succeeded!\n");
-               return (0);
-       }
-
-       for (i = 0; i < num0 + num1; i++) {
-               if (i < num1) {
-                       CHECK_GOTO(BN_bntest_rand(a, 400, 0, 0));
-                       CHECK_GOTO(BN_copy(b, a));
-                       CHECK_GOTO(BN_lshift(a, a, i));
-                       CHECK_GOTO(BN_add_word(a, i));
-               } else
-                       CHECK_GOTO(BN_bntest_rand(b, 50 + 3 * (i - num1), 0, 0));
-               BN_set_negative(a, rand_neg());
-               BN_set_negative(b, rand_neg());
-               CHECK_GOTO(BN_div(d, c, a, b, ctx));
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " / ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, d));
-                       BIO_puts(bp, "\n");
-
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " % ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, c));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_mul(e, d, b, ctx));
-               CHECK_GOTO(BN_add(d, e, c));
-               CHECK_GOTO(BN_sub(d, d, a));
-               if (!BN_is_zero(d)) {
-                       fprintf(stderr, "Division test failed!\n");
-                       rc = 0;
-                       break;
-               }
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       return (rc);
-}
-
-static void
-print_word(BIO *bp, BN_ULONG w)
-{
-#ifdef SIXTY_FOUR_BIT
-       if (sizeof(w) > sizeof(unsigned long)) {
-               unsigned long h = (unsigned long)(w >> 32), l = (unsigned long)(w);
-
-               if (h)
-                       BIO_printf(bp, "%lX%08lX", h, l);
-               else
-                       BIO_printf(bp, "%lX", l);
-               return;
-       }
-#endif
-       BIO_printf(bp, BN_HEX_FMT1, w);
-}
-
-int
-test_div_word(BIO *bp)
-{
-       BIGNUM *a = NULL, *b = NULL;
-       BN_ULONG r, rmod, s = 0;
-       int i;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-
-       for (i = 0; i < num0; i++) {
-               do {
-                       if (!BN_bntest_rand(a, 512, -1, 0) ||
-                           !BN_bntest_rand(b, BN_BITS2, -1, 0)) {
-                               rc = 0;
-                               break;
-                       }
-                       s = BN_get_word(b);
-               } while (!s);
-
-               if (!BN_copy(b, a)) {
-                       rc = 0;
-                       break;
-               }
-
-               rmod = BN_mod_word(b, s);
-               r = BN_div_word(b, s);
-
-               if (r == (BN_ULONG)-1 || rmod == (BN_ULONG)-1) {
-                       rc = 0;
-                       break;
-               }
-
-               if (rmod != r) {
-                       fprintf(stderr, "Mod (word) test failed!\n");
-                       rc = 0;
-                       break;
-               }
-
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " / ");
-                               print_word(bp, s);
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, b));
-                       BIO_puts(bp, "\n");
-
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " % ");
-                               print_word(bp, s);
-                               BIO_puts(bp, " - ");
-                       }
-                       print_word(bp, r);
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_mul_word(b, s));
-               CHECK_GOTO(BN_add_word(b, r));
-               CHECK_GOTO(BN_sub(b, a, b));
-               if (!BN_is_zero(b)) {
-                       fprintf(stderr, "Division (word) test failed!\n");
-                       rc = 0;
-                       break;
-               }
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-
-       return rc;
-}
-
-int
-test_div_recp(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
-       BN_RECP_CTX *recp = NULL;
-       int i;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-
-       if ((recp = BN_RECP_CTX_new()) == NULL)
-               goto err;
-
-       for (i = 0; i < num0 + num1; i++) {
-               if (i < num1) {
-                       CHECK_GOTO(BN_bntest_rand(a, 400, 0, 0));
-                       CHECK_GOTO(BN_copy(b, a));
-                       CHECK_GOTO(BN_lshift(a, a, i));
-                       CHECK_GOTO(BN_add_word(a, i));
-               } else
-                       CHECK_GOTO(BN_bntest_rand(b, 50 + 3 * (i - num1), 0, 0));
-               BN_set_negative(a, rand_neg());
-               BN_set_negative(b, rand_neg());
-               CHECK_GOTO(BN_RECP_CTX_set(recp, b, ctx));
-               CHECK_GOTO(BN_div_recp(d, c, a, recp, ctx));
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " / ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, d));
-                       BIO_puts(bp, "\n");
-
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " % ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, c));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_mul(e, d, b, ctx));
-               CHECK_GOTO(BN_add(d, e, c));
-               CHECK_GOTO(BN_sub(d, d, a));
-               if (!BN_is_zero(d)) {
-                       fprintf(stderr, "Reciprocal division test failed!\n");
-                       fprintf(stderr, "a=");
-                       CHECK_GOTO(BN_print_fp(stderr, a));
-                       fprintf(stderr, "\nb=");
-                       CHECK_GOTO(BN_print_fp(stderr, b));
-                       fprintf(stderr, "\n");
-                       rc = 0;
-                       break;
-               }
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       BN_RECP_CTX_free(recp);
-       return (rc);
-}
-
-int
-test_mul(BIO *bp)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
-       int i;
-       int rc = 1;
-       BN_CTX *ctx;
-
-       ctx = BN_CTX_new();
-       if (ctx == NULL)
-               exit(1);
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-
-       for (i = 0; i < num0 + num1; i++) {
-               if (i <= num1) {
-                       CHECK_GOTO(BN_bntest_rand(a, 100, 0, 0));
-                       CHECK_GOTO(BN_bntest_rand(b, 100, 0, 0));
-               } else
-                       CHECK_GOTO(BN_bntest_rand(b, i - num1, 0, 0));
-               BN_set_negative(a, rand_neg());
-               BN_set_negative(b, rand_neg());
-               CHECK_GOTO(BN_mul(c, a, b, ctx));
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " * ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, c));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_div(d, e, c, a, ctx));
-               CHECK_GOTO(BN_sub(d, d, b));
-               if (!BN_is_zero(d) || !BN_is_zero(e)) {
-                       fprintf(stderr, "Multiplication test failed!\n");
-                       rc = 0;
-                       break;
-               }
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       BN_CTX_free(ctx);
-       return (rc);
-}
-
-int
-test_sqr(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *c = NULL, *d = NULL, *e = NULL;
-       int i, rc = 0;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 40 + i * 10, 0, 0));
-               BN_set_negative(a, rand_neg());
-               CHECK_GOTO(BN_sqr(c, a, ctx));
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " * ");
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, c));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_div(d, e, c, a, ctx));
-               CHECK_GOTO(BN_sub(d, d, a));
-               if (!BN_is_zero(d) || !BN_is_zero(e)) {
-                       fprintf(stderr, "Square test failed!\n");
-                       goto err;
-               }
-       }
-
-       /* Regression test for a BN_sqr overflow bug. */
-       if (!BN_hex2bn(&a, "80000000000000008000000000000001"
-           "FFFFFFFFFFFFFFFE0000000000000000")) {
-               fprintf(stderr, "BN_hex2bn failed\n");
-               goto err;
-       }
-       CHECK_GOTO(BN_sqr(c, a, ctx));
-       if (bp != NULL) {
-               if (!results) {
-                       CHECK_GOTO(BN_print(bp, a));
-                       BIO_puts(bp, " * ");
-                       CHECK_GOTO(BN_print(bp, a));
-                       BIO_puts(bp, " - ");
-               }
-               CHECK_GOTO(BN_print(bp, c));
-               BIO_puts(bp, "\n");
-       }
-       CHECK_GOTO(BN_mul(d, a, a, ctx));
-       if (BN_cmp(c, d)) {
-               fprintf(stderr,
-                   "Square test failed: BN_sqr and BN_mul produce "
-                   "different results!\n");
-               goto err;
-       }
-
-       /* Regression test for a BN_sqr overflow bug. */
-       if (!BN_hex2bn(&a, "80000000000000000000000080000001"
-           "FFFFFFFE000000000000000000000000")) {
-               fprintf(stderr, "BN_hex2bn failed\n");
-               goto err;
-       }
-       CHECK_GOTO(BN_sqr(c, a, ctx));
-       if (bp != NULL) {
-               if (!results) {
-                       CHECK_GOTO(BN_print(bp, a));
-                       BIO_puts(bp, " * ");
-                       CHECK_GOTO(BN_print(bp, a));
-                       BIO_puts(bp, " - ");
-               }
-               CHECK_GOTO(BN_print(bp, c));
-               BIO_puts(bp, "\n");
-       }
-       CHECK_GOTO(BN_mul(d, a, a, ctx));
-       if (BN_cmp(c, d)) {
-               fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
-                               "different results!\n");
-               goto err;
-       }
-       rc = 1;
- err:
-       BN_free(a);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       return rc;
-}
-
-int
-test_mont(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *A = NULL, *B = NULL;
-       BIGNUM *n = NULL;
-       int i;
-       int rc = 1;
-       BN_MONT_CTX *mont;
-
-       mont = BN_MONT_CTX_new();
-       if (mont == NULL)
-               return 0;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((A = BN_new()) == NULL)
-               goto err;
-       if ((B = BN_new()) == NULL)
-               goto err;
-       if ((n = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_zero(n));
-       if (BN_MONT_CTX_set(mont, n, ctx)) {
-               fprintf(stderr, "BN_MONT_CTX_set succeeded for zero modulus!\n");
-               return (0);
-       }
-
-       CHECK_GOTO(BN_set_word(n, 16));
-       if (BN_MONT_CTX_set(mont, n, ctx)) {
-               fprintf(stderr, "BN_MONT_CTX_set succeeded for even modulus!\n");
-               return (0);
-       }
-
-       CHECK_GOTO(BN_bntest_rand(a, 100, 0, 0));
-       CHECK_GOTO(BN_bntest_rand(b, 100, 0, 0));
-       for (i = 0; i < num2; i++) {
-               int bits = (200 * (i + 1)) / num2;
-
-               if (bits == 0)
-                       continue;
-               CHECK_GOTO(BN_bntest_rand(n, bits, 0, 1));
-               CHECK_GOTO(BN_MONT_CTX_set(mont, n, ctx));
-
-               CHECK_GOTO(BN_nnmod(a, a, n, ctx));
-               CHECK_GOTO(BN_nnmod(b, b, n, ctx));
-
-               CHECK_GOTO(BN_to_montgomery(A, a, mont, ctx));
-               CHECK_GOTO(BN_to_montgomery(B, b, mont, ctx));
-
-               CHECK_GOTO(BN_mod_mul_montgomery(c, A, B, mont, ctx));
-               CHECK_GOTO(BN_from_montgomery(A, c, mont, ctx));
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " * ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " % ");
-                               /* n == &mont->N */
-                               CHECK_GOTO(BN_print(bp, n));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, A));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_mod_mul(d, a, b, n, ctx));
-               CHECK_GOTO(BN_sub(d, d, A));
-               if (!BN_is_zero(d)) {
-                       fprintf(stderr, "Montgomery multiplication test failed!\n");
-                       rc = 0;
-                       break;
-               }
-       }
- err:
-       BN_MONT_CTX_free(mont);
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       BN_free(d);
-       BN_free(A);
-       BN_free(B);
-       BN_free(n);
-       return (rc);
-}
-
-int
-test_mod(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
-       int i;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0));
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_bntest_rand(b, 450 + i * 10, 0, 0));
-               BN_set_negative(a, rand_neg());
-               BN_set_negative(b, rand_neg());
-               CHECK_GOTO(BN_mod(c, a, b, ctx));
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " % ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, c));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_div(d, e, a, b, ctx));
-               CHECK_GOTO(BN_sub(e, e, c));
-               if (!BN_is_zero(e)) {
-                       fprintf(stderr, "Modulo test failed!\n");
-                       rc = 0;
-                       break;
-               }
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       return (rc);
-}
-
-int
-test_mod_mul(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
-       int i, j;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_one(a));
-       CHECK_GOTO(BN_one(b));
-       CHECK_GOTO(BN_zero(c));
-       if (BN_mod_mul(e, a, b, c, ctx)) {
-               fprintf(stderr, "BN_mod_mul with zero modulus succeeded!\n");
-               return (0);
-       }
-
-       for (j = 0; j < 3; j++) {
-               CHECK_GOTO(BN_bntest_rand(c, 1024, 0, 0));
-               for (i = 0; i < num0; i++) {
-                       CHECK_GOTO(BN_bntest_rand(a, 475 + i * 10, 0, 0));
-                       CHECK_GOTO(BN_bntest_rand(b, 425 + i * 11, 0, 0));
-                       BN_set_negative(a, rand_neg());
-                       BN_set_negative(b, rand_neg());
-                       if (!BN_mod_mul(e, a, b, c, ctx)) {
-                               unsigned long l;
-
-                               while ((l = ERR_get_error()))
-                                       fprintf(stderr, "ERROR:%s\n",
-                                           ERR_error_string(l, NULL));
-                               exit(1);
-                       }
-                       if (bp != NULL) {
-                               if (!results) {
-                                       CHECK_GOTO(BN_print(bp, a));
-                                       BIO_puts(bp, " * ");
-                                       CHECK_GOTO(BN_print(bp, b));
-                                       BIO_puts(bp, " % ");
-                                       CHECK_GOTO(BN_print(bp, c));
-                                       if ((BN_is_negative(a) ^ BN_is_negative(b)) &&
-                                           !BN_is_zero(e)) {
-                                               /* If  (a*b) % c  is negative,  c  must be added
-                                                * in order to obtain the normalized remainder
-                                                * (new with OpenSSL 0.9.7, previous versions of
-                                                * BN_mod_mul could generate negative results)
-                                                */
-                                               BIO_puts(bp, " + ");
-                                               CHECK_GOTO(BN_print(bp, c));
-                                       }
-                                       BIO_puts(bp, " - ");
-                               }
-                               CHECK_GOTO(BN_print(bp, e));
-                               BIO_puts(bp, "\n");
-                       }
-                       CHECK_GOTO(BN_mul(d, a, b, ctx));
-                       CHECK_GOTO(BN_sub(d, d, e));
-                       CHECK_GOTO(BN_div(a, b, d, c, ctx));
-                       if (!BN_is_zero(b)) {
-                               fprintf(stderr, "Modulo multiply test failed!\n");
-                               ERR_print_errors_fp(stderr);
-                               rc = 0;
-                               goto err;
-                       }
-               }
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       return (rc);
-}
-
-int
-test_mod_exp(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
-       int i;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_one(a));
-       CHECK_GOTO(BN_one(b));
-       CHECK_GOTO(BN_zero(c));
-       if (BN_mod_exp(d, a, b, c, ctx)) {
-               fprintf(stderr, "BN_mod_exp with zero modulus succeeded!\n");
-               rc = 0;
-               goto err;
-       }
-       if (BN_mod_exp_ct(d, a, b, c, ctx)) {
-               fprintf(stderr, "BN_mod_exp_ct with zero modulus succeeded!\n");
-               rc = 0;
-               goto err;
-       }
-       if (BN_mod_exp_nonct(d, a, b, c, ctx)) {
-               fprintf(stderr, "BN_mod_exp_nonct with zero modulus succeeded!\n");
-               rc = 0;
-               goto err;
-       }
-
-       CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */
-       for (i = 0; i < num2; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
-               CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
-
-               if (!BN_mod_exp(d, a, b, c, ctx)) {
-                       rc = 0;
-                       break;
-               }
-
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " ^ ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " % ");
-                               CHECK_GOTO(BN_print(bp, c));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, d));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_exp(e, a, b, ctx));
-               CHECK_GOTO(BN_sub(e, e, d));
-               CHECK_GOTO(BN_div(a, b, e, c, ctx));
-               if (!BN_is_zero(b)) {
-                       fprintf(stderr, "Modulo exponentiation test failed!\n");
-                       rc = 0;
-                       break;
-               }
-       }
-
-       CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */
-       for (i = 0; i < num2; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
-               CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
-
-               if (!BN_mod_exp_ct(d, a, b, c, ctx)) {
-                       rc = 0;
-                       break;
-               }
-
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " ^ ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " % ");
-                               CHECK_GOTO(BN_print(bp, c));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, d));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_exp(e, a, b, ctx));
-               CHECK_GOTO(BN_sub(e, e, d));
-               CHECK_GOTO(BN_div(a, b, e, c, ctx));
-               if (!BN_is_zero(b)) {
-                       fprintf(stderr, "Modulo exponentiation test failed!\n");
-                       rc = 0;
-                       break;
-               }
-       }
-
-       CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */
-       for (i = 0; i < num2; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
-               CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
-
-               if (!BN_mod_exp_nonct(d, a, b, c, ctx)) {
-                       rc = 0;
-                       break;
-               }
-
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " ^ ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " % ");
-                               CHECK_GOTO(BN_print(bp, c));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, d));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_exp(e, a, b, ctx));
-               CHECK_GOTO(BN_sub(e, e, d));
-               CHECK_GOTO(BN_div(a, b, e, c, ctx));
-               if (!BN_is_zero(b)) {
-                       fprintf(stderr, "Modulo exponentiation test failed!\n");
-                       rc = 0;
-                       break;
-               }
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       return (rc);
-}
-
-int
-test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
-       int i;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_one(a));
-       CHECK_GOTO(BN_one(b));
-       CHECK_GOTO(BN_zero(c));
-       if (BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) {
-               fprintf(stderr, "BN_mod_exp_mont_consttime with zero modulus "
-                               "succeeded\n");
-               rc = 0;
-               goto err;
-       }
-
-       CHECK_GOTO(BN_set_word(c, 16));
-       if (BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) {
-               fprintf(stderr, "BN_mod_exp_mont_consttime with even modulus "
-                               "succeeded\n");
-               rc = 0;
-               goto err;
-       }
-
-       CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */
-       for (i = 0; i < num2; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
-               CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
-
-               if (!BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) {
-                       rc = 0;
-                       break;
-               }
-
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " ^ ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " % ");
-                               CHECK_GOTO(BN_print(bp, c));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, d));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_exp(e, a, b, ctx));
-               CHECK_GOTO(BN_sub(e, e, d));
-               CHECK_GOTO(BN_div(a, b, e, c, ctx));
-               if (!BN_is_zero(b)) {
-                       fprintf(stderr, "Modulo exponentiation test failed!\n");
-                       rc = 0;
-                       break;
-               }
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       return (rc);
-}
-
-/*
- * Test constant-time modular exponentiation with 1024-bit inputs, which on
- * x86_64 cause a different code branch to be taken.
- */
-int
-test_mod_exp_mont5(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *p = NULL, *m = NULL, *d = NULL, *e = NULL;
-       BIGNUM *b = NULL, *n = NULL, *c = NULL;
-       BN_MONT_CTX *mont = NULL;
-       int len;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((p = BN_new()) == NULL)
-               goto err;
-       if ((m = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((n = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(mont = BN_MONT_CTX_new());
-
-       CHECK_GOTO(BN_bntest_rand(m, 1024, 0, 1)); /* must be odd for montgomery */
-       /* Zero exponent */
-       CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0));
-       CHECK_GOTO(BN_zero(p));
-       if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)) {
-               rc = 0;
-               goto err;
-       }
-       if (!BN_is_one(d)) {
-               fprintf(stderr, "Modular exponentiation test failed!\n");
-               rc = 0;
-               goto err;
-       }
-       /* Regression test for carry bug in mulx4x_mont */
-       len = BN_hex2bn(&a,
-           "7878787878787878787878787878787878787878787878787878787878787878"
-           "7878787878787878787878787878787878787878787878787878787878787878"
-           "7878787878787878787878787878787878787878787878787878787878787878"
-           "7878787878787878787878787878787878787878787878787878787878787878");
-       CHECK_GOTO(len);
-       len = BN_hex2bn(&b,
-           "095D72C08C097BA488C5E439C655A192EAFB6380073D8C2664668EDDB4060744"
-           "E16E57FB4EDB9AE10A0CEFCDC28A894F689A128379DB279D48A2E20849D68593"
-           "9B7803BCF46CEBF5C533FB0DD35B080593DE5472E3FE5DB951B8BFF9B4CB8F03"
-           "9CC638A5EE8CDD703719F8000E6A9F63BEED5F2FCD52FF293EA05A251BB4AB81");
-       CHECK_GOTO(len);
-       len = BN_hex2bn(&n,
-           "D78AF684E71DB0C39CFF4E64FB9DB567132CB9C50CC98009FEB820B26F2DED9B"
-           "91B9B5E2B83AE0AE4EB4E0523CA726BFBE969B89FD754F674CE99118C3F2D1C5"
-           "D81FDC7C54E02B60262B241D53C040E99E45826ECA37A804668E690E1AFC1CA4"
-           "2C9A15D84D4954425F0B7642FC0BD9D7B24E2618D2DCC9B729D944BADACFDDAF");
-       CHECK_GOTO(len);
-       CHECK_GOTO(BN_MONT_CTX_set(mont, n, ctx));
-       CHECK_GOTO(BN_mod_mul_montgomery(c, a, b, mont, ctx));
-       CHECK_GOTO(BN_mod_mul_montgomery(d, b, a, mont, ctx));
-       if (BN_cmp(c, d)) {
-               fprintf(stderr, "Montgomery multiplication test failed:"
-                   " a*b != b*a.\n");
-               rc = 0;
-               goto err;
-       }
-       /* Regression test for carry bug in sqr[x]8x_mont */
-       len = BN_hex2bn(&n,
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFF00"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "00000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF");
-       CHECK_GOTO(len);
-       len = BN_hex2bn(&a,
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
-           "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFF0000000000"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "0000000000000000000000000000000000000000000000000000000000000000"
-           "000000000000000000000000000000000000000000FFFFFFFFFFFFFF00000000");
-       CHECK_GOTO(len);
-       BN_free(b);
-       CHECK_GOTO(b = BN_dup(a));
-       CHECK_GOTO(BN_MONT_CTX_set(mont, n, ctx));
-       CHECK_GOTO(BN_mod_mul_montgomery(c, a, a, mont, ctx));
-       CHECK_GOTO(BN_mod_mul_montgomery(d, a, b, mont, ctx));
-       if (BN_cmp(c, d)) {
-               fprintf(stderr, "Montgomery multiplication test failed:"
-                   " a**2 != a*a.\n");
-               rc = 0;
-               goto err;
-       }
-       /* Zero input */
-       CHECK_GOTO(BN_bntest_rand(p, 1024, 0, 0));
-       CHECK_GOTO(BN_zero(a));
-       if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)) {
-               rc = 0;
-               goto err;
-       }
-       if (!BN_is_zero(d)) {
-               fprintf(stderr, "Modular exponentiation test failed!\n");
-               rc = 0;
-               goto err;
-       }
-       /*
-        * Craft an input whose Montgomery representation is 1, i.e., shorter
-        * than the modulus m, in order to test the const time precomputation
-        * scattering/gathering.
-        */
-       CHECK_GOTO(BN_one(a));
-       CHECK_GOTO(BN_MONT_CTX_set(mont, m, ctx));
-       if (!BN_from_montgomery(e, a, mont, ctx)) {
-               rc = 0;
-               goto err;
-       }
-       if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL)) {
-               rc = 0;
-               goto err;
-       }
-       if (!BN_mod_exp_simple(a, e, p, m, ctx)) {
-               rc = 0;
-               goto err;
-       }
-       if (BN_cmp(a, d) != 0) {
-               fprintf(stderr, "Modular exponentiation test failed!\n");
-               rc = 0;
-               goto err;
-       }
-       /* Finally, some regular test vectors. */
-       CHECK_GOTO(BN_bntest_rand(e, 1024, 0, 0));
-       if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL)) {
-               rc = 0;
-               goto err;
-       }
-       if (!BN_mod_exp_simple(a, e, p, m, ctx)) {
-               rc = 0;
-               goto err;
-       }
-       if (BN_cmp(a, d) != 0) {
-               fprintf(stderr, "Modular exponentiation test failed!\n");
-               rc = 0;
-               goto err;
-       }
- err:
-       BN_free(a);
-       BN_free(p);
-       BN_free(m);
-       BN_free(d);
-       BN_free(e);
-       BN_free(b);
-       BN_free(n);
-       BN_free(c);
-       BN_MONT_CTX_free(mont);
-       return (rc);
-}
-
-int
-test_exp(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b = NULL, *d = NULL, *e = NULL, *one = NULL;
-       int i;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-       if ((one = BN_new()) == NULL)
-               goto err;
-       CHECK_GOTO(BN_one(one));
-
-       for (i = 0; i < num2; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
-               CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
-
-               if (BN_exp(d, a, b, ctx) <= 0) {
-                       rc = 0;
-                       break;
-               }
-
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " ^ ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, d));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_one(e));
-               for (; !BN_is_zero(b); BN_sub(b, b, one))
-                       CHECK_GOTO(BN_mul(e, e, a, ctx));
-               CHECK_GOTO(BN_sub(e, e, d));
-               if (!BN_is_zero(e)) {
-                       fprintf(stderr, "Exponentiation test failed!\n");
-                       rc = 0;
-                       break;
-               }
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(d);
-       BN_free(e);
-       BN_free(one);
-       return (rc);
-}
-
-#ifndef OPENSSL_NO_EC2M
-int
-test_gf2m_add(BIO *bp)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL;
-       int i, rc = 0;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_rand(a, 512, 0, 0));
-               CHECK_GOTO(BN_copy(b, BN_value_one()));
-               BN_set_negative(a, rand_neg());
-               BN_set_negative(b, rand_neg());
-               CHECK_GOTO(BN_GF2m_add(c, a, b));
-#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " ^ ");
-                               CHECK_GOTO(BN_print(bp, b));
-                               BIO_puts(bp, " = ");
-                       }
-                       CHECK_GOTO(BN_print(bp, c));
-                       BIO_puts(bp, "\n");
-               }
-#endif
-               /* Test that two added values have the correct parity. */
-               if ((BN_is_odd(a) && BN_is_odd(c))
-                   || (!BN_is_odd(a) && !BN_is_odd(c))) {
-                       fprintf(stderr, "GF(2^m) addition test (a) failed!\n");
-                       goto err;
-               }
-               CHECK_GOTO(BN_GF2m_add(c, c, c));
-               /* Test that c + c = 0. */
-               if (!BN_is_zero(c)) {
-                       fprintf(stderr, "GF(2^m) addition test (b) failed!\n");
-                       goto err;
-               }
-       }
-       rc = 1;
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       return rc;
-}
-
-int
-test_gf2m_mod(BIO *bp)
-{
-       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL, *e = NULL;
-       int i, j;
-       int p0[] = { 163, 7, 6, 3, 0, -1 };
-       int p1[] = { 193, 15, 0, -1 };
-       int rc = 0;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b[0] = BN_new()) == NULL)
-               goto err;
-       if ((b[1] = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
-       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
-
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0));
-               for (j = 0; j < 2; j++) {
-                       CHECK_GOTO(BN_GF2m_mod(c, a, b[j]));
-#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
-                       if (bp != NULL) {
-                               if (!results) {
-                                       CHECK_GOTO(BN_print(bp, a));
-                                       BIO_puts(bp, " % ");
-                                       CHECK_GOTO(BN_print(bp, b[j]));
-                                       BIO_puts(bp, " - ");
-                                       CHECK_GOTO(BN_print(bp, c));
-                                       BIO_puts(bp, "\n");
-                               }
-                       }
-#endif
-                       CHECK_GOTO(BN_GF2m_add(d, a, c));
-                       CHECK_GOTO(BN_GF2m_mod(e, d, b[j]));
-                       /* Test that a + (a mod p) mod p == 0. */
-                       if (!BN_is_zero(e)) {
-                               fprintf(stderr, "GF(2^m) modulo test failed!\n");
-                               goto err;
-                       }
-               }
-       }
-       rc = 1;
- err:
-       BN_free(a);
-       BN_free(b[0]);
-       BN_free(b[1]);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       return rc;
-}
-
-int
-test_gf2m_mod_mul(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
-       BIGNUM *g = NULL, *h = NULL;
-       int i, j;
-       int p0[] = { 163, 7, 6, 3, 0, -1 };
-       int p1[] = { 193, 15, 0, -1 };
-       int rc = 0;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b[0] = BN_new()) == NULL)
-               goto err;
-       if ((b[1] = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-       if ((f = BN_new()) == NULL)
-               goto err;
-       if ((g = BN_new()) == NULL)
-               goto err;
-       if ((h = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
-       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
-
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0));
-               CHECK_GOTO(BN_bntest_rand(c, 1024, 0, 0));
-               CHECK_GOTO(BN_bntest_rand(d, 1024, 0, 0));
-               for (j = 0; j < 2; j++) {
-                       CHECK_GOTO(BN_GF2m_mod_mul(e, a, c, b[j], ctx));
-#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
-                       if (bp != NULL) {
-                               if (!results) {
-                                       CHECK_GOTO(BN_print(bp, a));
-                                       BIO_puts(bp, " * ");
-                                       CHECK_GOTO(BN_print(bp, c));
-                                       BIO_puts(bp, " % ");
-                                       CHECK_GOTO(BN_print(bp, b[j]));
-                                       BIO_puts(bp, " - ");
-                                       CHECK_GOTO(BN_print(bp, e));
-                                       BIO_puts(bp, "\n");
-                               }
-                       }
-#endif
-                       CHECK_GOTO(BN_GF2m_add(f, a, d));
-                       CHECK_GOTO(BN_GF2m_mod_mul(g, f, c, b[j], ctx));
-                       CHECK_GOTO(BN_GF2m_mod_mul(h, d, c, b[j], ctx));
-                       CHECK_GOTO(BN_GF2m_add(f, e, g));
-                       CHECK_GOTO(BN_GF2m_add(f, f, h));
-                       /* Test that (a+d)*c = a*c + d*c. */
-                       if (!BN_is_zero(f)) {
-                               fprintf(stderr, "GF(2^m) modular multiplication test failed!\n");
-                               goto err;
-                       }
-               }
-       }
-       rc = 1;
- err:
-       BN_free(a);
-       BN_free(b[0]);
-       BN_free(b[1]);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       BN_free(f);
-       BN_free(g);
-       BN_free(h);
-       return rc;
-}
-
-int
-test_gf2m_mod_sqr(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL;
-       int i, j, rc = 0;
-       int p0[] = { 163, 7, 6, 3, 0, -1 };
-       int p1[] = { 193, 15, 0, -1 };
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b[0] = BN_new()) == NULL)
-               goto err;
-       if ((b[1] = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
-       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
-
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0));
-               for (j = 0; j < 2; j++) {
-                       CHECK_GOTO(BN_GF2m_mod_sqr(c, a, b[j], ctx));
-                       CHECK_GOTO(BN_copy(d, a));
-                       CHECK_GOTO(BN_GF2m_mod_mul(d, a, d, b[j], ctx));
-#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
-                       if (bp != NULL) {
-                               if (!results) {
-                                       CHECK_GOTO(BN_print(bp, a));
-                                       BIO_puts(bp, " ^ 2 % ");
-                                       CHECK_GOTO(BN_print(bp, b[j]));
-                                       BIO_puts(bp, " = ");
-                                       CHECK_GOTO(BN_print(bp, c));
-                                       BIO_puts(bp, "; a * a = ");
-                                       CHECK_GOTO(BN_print(bp, d));
-                                       BIO_puts(bp, "\n");
-                               }
-                       }
-#endif
-                       CHECK_GOTO(BN_GF2m_add(d, c, d));
-                       /* Test that a*a = a^2. */
-                       if (!BN_is_zero(d)) {
-                               fprintf(stderr, "GF(2^m) modular squaring test failed!\n");
-                               goto err;
-                       }
-               }
-       }
-       rc = 1;
- err:
-       BN_free(a);
-       BN_free(b[0]);
-       BN_free(b[1]);
-       BN_free(c);
-       BN_free(d);
-       return rc;
-}
-
-int
-test_gf2m_mod_inv(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL;
-       int i, j, rc = 0;
-       int p0[] = { 163, 7, 6, 3, 0, -1 };
-       int p1[] = { 193, 15, 0, -1 };
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b[0] = BN_new()) == NULL)
-               goto err;
-       if ((b[1] = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
-       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
-
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
-               for (j = 0; j < 2; j++) {
-                       CHECK_GOTO(BN_GF2m_mod_inv(c, a, b[j], ctx));
-                       CHECK_GOTO(BN_GF2m_mod_mul(d, a, c, b[j], ctx));
-#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
-                       if (bp != NULL) {
-                               if (!results) {
-                                       CHECK_GOTO(BN_print(bp, a));
-                                       BIO_puts(bp, " * ");
-                                       CHECK_GOTO(BN_print(bp, c));
-                                       BIO_puts(bp, " - 1 % ");
-                                       CHECK_GOTO(BN_print(bp, b[j]));
-                                       BIO_puts(bp, "\n");
-                               }
-                       }
-#endif
-                       /* Test that ((1/a)*a) = 1. */
-                       if (!BN_is_one(d)) {
-                               fprintf(stderr, "GF(2^m) modular inversion test failed!\n");
-                               goto err;
-                       }
-               }
-       }
-       rc = 1;
- err:
-       BN_free(a);
-       BN_free(b[0]);
-       BN_free(b[1]);
-       BN_free(c);
-       BN_free(d);
-       return rc;
-}
-
-int
-test_gf2m_mod_div(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
-       int i, j, rc = 0;
-       int p0[] = { 163, 7, 6, 3, 0, -1 };
-       int p1[] = { 193, 15, 0, -1 };
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b[0] = BN_new()) == NULL)
-               goto err;
-       if ((b[1] = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-       if ((f = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
-       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
-
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
-               CHECK_GOTO(BN_bntest_rand(c, 512, 0, 0));
-               for (j = 0; j < 2; j++) {
-                       CHECK_GOTO(BN_GF2m_mod_div(d, a, c, b[j], ctx));
-                       CHECK_GOTO(BN_GF2m_mod_mul(e, d, c, b[j], ctx));
-                       CHECK_GOTO(BN_GF2m_mod_div(f, a, e, b[j], ctx));
-#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
-                       if (bp != NULL) {
-                               if (!results) {
-                                       CHECK_GOTO(BN_print(bp, a));
-                                       BIO_puts(bp, " = ");
-                                       CHECK_GOTO(BN_print(bp, c));
-                                       BIO_puts(bp, " * ");
-                                       CHECK_GOTO(BN_print(bp, d));
-                                       BIO_puts(bp, " % ");
-                                       CHECK_GOTO(BN_print(bp, b[j]));
-                                       BIO_puts(bp, "\n");
-                               }
-                       }
-#endif
-                       /* Test that ((a/c)*c)/a = 1. */
-                       if (!BN_is_one(f)) {
-                               fprintf(stderr, "GF(2^m) modular division test failed!\n");
-                               goto err;
-                       }
-               }
-       }
-       rc = 1;
- err:
-       BN_free(a);
-       BN_free(b[0]);
-       BN_free(b[1]);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       BN_free(f);
-       return rc;
-}
-
-int
-test_gf2m_mod_exp(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
-       int i, j, rc = 0;
-       int p0[] = { 163, 7, 6, 3, 0, -1 };
-       int p1[] = { 193, 15, 0, -1 };
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b[0] = BN_new()) == NULL)
-               goto err;
-       if ((b[1] = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-       if ((f = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
-       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
-
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
-               CHECK_GOTO(BN_bntest_rand(c, 512, 0, 0));
-               CHECK_GOTO(BN_bntest_rand(d, 512, 0, 0));
-               for (j = 0; j < 2; j++) {
-                       CHECK_GOTO(BN_GF2m_mod_exp(e, a, c, b[j], ctx));
-                       CHECK_GOTO(BN_GF2m_mod_exp(f, a, d, b[j], ctx));
-                       CHECK_GOTO(BN_GF2m_mod_mul(e, e, f, b[j], ctx));
-                       CHECK_GOTO(BN_add(f, c, d));
-                       CHECK_GOTO(BN_GF2m_mod_exp(f, a, f, b[j], ctx));
-#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
-                       if (bp != NULL) {
-                               if (!results) {
-                                       CHECK_GOTO(BN_print(bp, a));
-                                       BIO_puts(bp, " ^ (");
-                                       CHECK_GOTO(BN_print(bp, c));
-                                       BIO_puts(bp, " + ");
-                                       CHECK_GOTO(BN_print(bp, d));
-                                       BIO_puts(bp, ") = ");
-                                       CHECK_GOTO(BN_print(bp, e));
-                                       BIO_puts(bp, "; - ");
-                                       CHECK_GOTO(BN_print(bp, f));
-                                       BIO_puts(bp, " % ");
-                                       CHECK_GOTO(BN_print(bp, b[j]));
-                                       BIO_puts(bp, "\n");
-                               }
-                       }
-#endif
-                       CHECK_GOTO(BN_GF2m_add(f, e, f));
-                       /* Test that a^(c+d)=a^c*a^d. */
-                       if (!BN_is_zero(f)) {
-                               fprintf(stderr, "GF(2^m) modular exponentiation test failed!\n");
-                               goto err;
-                       }
-               }
-       }
-       rc = 1;
- err:
-       BN_free(a);
-       BN_free(b[0]);
-       BN_free(b[1]);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       BN_free(f);
-       return rc;
-}
-
-int
-test_gf2m_mod_sqrt(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
-       int i, j, rc = 0;
-       int p0[] = { 163, 7, 6, 3, 0, -1 };
-       int p1[] = { 193, 15, 0, -1 };
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b[0] = BN_new()) == NULL)
-               goto err;
-       if ((b[1] = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-       if ((f = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
-       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
-
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
-               for (j = 0; j < 2; j++) {
-                       CHECK_GOTO(BN_GF2m_mod(c, a, b[j]));
-                       CHECK_GOTO(BN_GF2m_mod_sqrt(d, a, b[j], ctx));
-                       CHECK_GOTO(BN_GF2m_mod_sqr(e, d, b[j], ctx));
-#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
-                       if (bp != NULL) {
-                               if (!results) {
-                                       CHECK_GOTO(BN_print(bp, d));
-                                       BIO_puts(bp, " ^ 2 - ");
-                                       CHECK_GOTO(BN_print(bp, a));
-                                       BIO_puts(bp, "\n");
-                               }
-                       }
-#endif
-                       CHECK_GOTO(BN_GF2m_add(f, c, e));
-                       /* Test that d^2 = a, where d = sqrt(a). */
-                       if (!BN_is_zero(f)) {
-                               fprintf(stderr, "GF(2^m) modular square root test failed!\n");
-                               goto err;
-                       }
-               }
-       }
-       rc = 1;
- err:
-       BN_free(a);
-       BN_free(b[0]);
-       BN_free(b[1]);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       BN_free(f);
-       return rc;
-}
-
-int
-test_gf2m_mod_solve_quad(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b[2] = { 0 }, *c = NULL, *d = NULL, *e = NULL;
-       int i, j, s = 0, t, rc = 0;
-       int p0[] = { 163, 7, 6, 3, 0, -1 };
-       int p1[] = { 193, 15, 0, -1 };
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b[0] = BN_new()) == NULL)
-               goto err;
-       if ((b[1] = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_GF2m_arr2poly(p0, b[0]));
-       CHECK_GOTO(BN_GF2m_arr2poly(p1, b[1]));
-
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
-               for (j = 0; j < 2; j++) {
-                       t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
-                       if (t) {
-                               s++;
-                               CHECK_GOTO(BN_GF2m_mod_sqr(d, c, b[j], ctx));
-                               CHECK_GOTO(BN_GF2m_add(d, c, d));
-                               CHECK_GOTO(BN_GF2m_mod(e, a, b[j]));
-#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
-                               if (bp != NULL) {
-                                       if (!results) {
-                                               CHECK_GOTO(BN_print(bp, c));
-                                               BIO_puts(bp, " is root of z^2 + z = ");
-                                               CHECK_GOTO(BN_print(bp, a));
-                                               BIO_puts(bp, " % ");
-                                               CHECK_GOTO(BN_print(bp, b[j]));
-                                               BIO_puts(bp, "\n");
-                                       }
-                               }
-#endif
-                               CHECK_GOTO(BN_GF2m_add(e, e, d));
-                               /* Test that solution of quadratic c satisfies c^2 + c = a. */
-                               if (!BN_is_zero(e)) {
-                                       fprintf(stderr, "GF(2^m) modular solve quadratic test failed!\n");
-                                       goto err;
-                               }
-
-                       } else {
-#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
-                               if (bp != NULL) {
-                                       if (!results) {
-                                               BIO_puts(bp, "There are no roots of z^2 + z = ");
-                                               CHECK_GOTO(BN_print(bp, a));
-                                               BIO_puts(bp, " % ");
-                                               CHECK_GOTO(BN_print(bp, b[j]));
-                                               BIO_puts(bp, "\n");
-                                       }
-                               }
-#endif
-                       }
-               }
-       }
-       if (s == 0) {
-               fprintf(stderr, "All %d tests of GF(2^m) modular solve quadratic resulted in no roots;\n", num0);
-               fprintf(stderr, "this is very unlikely and probably indicates an error.\n");
-               goto err;
-       }
-       rc = 1;
- err:
-       BN_free(a);
-       BN_free(b[0]);
-       BN_free(b[1]);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       return rc;
-}
-#endif
-static int
-genprime_cb(int p, int n, BN_GENCB *arg)
-{
-       char c = '*';
-
-       if (p == 0)
-               c = '.';
-       if (p == 1)
-               c = '+';
-       if (p == 2)
-               c = '*';
-       if (p == 3)
-               c = '\n';
-       putc(c, stderr);
-       return (1);
-}
-
-int
-test_kron(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b = NULL, *r = NULL, *t = NULL;
-       BN_GENCB *cb = NULL;
-       int i;
-       int legendre, kronecker;
-       int rc = 0;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((r = BN_new()) == NULL)
-               goto err;
-       if ((t = BN_new()) == NULL)
-               goto err;
-
-       if ((cb = BN_GENCB_new()) == NULL)
-               goto err;
-
-       BN_GENCB_set(cb, genprime_cb, NULL);
-
-       /*
-        * We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol). In
-        * this case we know that if b is prime, then BN_kronecker(a, b, ctx) is
-        * congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol). So we
-        * generate a random prime b and compare these values for a number of
-        * random a's.  (That is, we run the Solovay-Strassen primality test to
-        * confirm that b is prime, except that we don't want to test whether b
-        * is prime but whether BN_kronecker works.)
-        */
-
-       if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, cb))
-               goto err;
-       BN_set_negative(b, rand_neg());
-       putc('\n', stderr);
-
-       for (i = 0; i < num0; i++) {
-               if (!BN_bntest_rand(a, 512, 0, 0))
-                       goto err;
-               BN_set_negative(a, rand_neg());
-
-               /* t := (|b|-1)/2  (note that b is odd) */
-               if (!BN_copy(t, b))
-                       goto err;
-               BN_set_negative(t, 0);
-               if (!BN_sub_word(t, 1))
-                       goto err;
-               if (!BN_rshift1(t, t))
-                       goto err;
-               /* r := a^t mod b */
-               BN_set_negative(b, 0);
-
-               if (!BN_mod_exp_recp(r, a, t, b, ctx))
-                       goto err;
-               BN_set_negative(b, 1);
-
-               if (BN_is_word(r, 1))
-                       legendre = 1;
-               else if (BN_is_zero(r))
-                       legendre = 0;
-               else {
-                       if (!BN_add_word(r, 1))
-                               goto err;
-                       if (0 != BN_ucmp(r, b)) {
-                               fprintf(stderr, "Legendre symbol computation failed\n");
-                               goto err;
-                       }
-                       legendre = -1;
-               }
-
-               kronecker = BN_kronecker(a, b, ctx);
-               if (kronecker < -1)
-                       goto err;
-               /* we actually need BN_kronecker(a, |b|) */
-               if (BN_is_negative(a) && BN_is_negative(b))
-                       kronecker = -kronecker;
-
-               if (legendre != kronecker) {
-                       fprintf(stderr, "legendre != kronecker; a = ");
-                       CHECK_GOTO(BN_print_fp(stderr, a));
-                       fprintf(stderr, ", b = ");
-                       CHECK_GOTO(BN_print_fp(stderr, b));
-                       fprintf(stderr, "\n");
-                       goto err;
-               }
-
-               putc('.', stderr);
-       }
-
-       putc('\n', stderr);
-       rc = 1;
-
- err:
-       BN_GENCB_free(cb);
-       BN_free(a);
-       BN_free(b);
-       BN_free(r);
-       BN_free(t);
-       return rc;
-}
-
-int
-test_sqrt(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *p = NULL, *r = NULL;
-       BN_GENCB *cb = NULL;
-       int i, j;
-       int rc = 0;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((p = BN_new()) == NULL)
-               goto err;
-       if ((r = BN_new()) == NULL)
-               goto err;
-
-       if ((cb = BN_GENCB_new()) == NULL)
-               goto err;
-
-       BN_GENCB_set(cb, genprime_cb, NULL);
-
-       for (i = 0; i < 16; i++) {
-               if (i < 8) {
-                       unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
-
-                       if (!BN_set_word(p, primes[i]))
-                               goto err;
-               } else {
-                       if (!BN_set_word(a, 32))
-                               goto err;
-                       if (!BN_set_word(r, 2 * i + 1))
-                               goto err;
-
-                       if (!BN_generate_prime_ex(p, 256, 0, a, r, cb))
-                               goto err;
-                       putc('\n', stderr);
-               }
-               BN_set_negative(p, rand_neg());
-
-               for (j = 0; j < num2; j++) {
-                       /*
-                        * construct 'a' such that it is a square modulo p, but in
-                        * general not a proper square and not reduced modulo p
-                        */
-                       if (!BN_bntest_rand(r, 256, 0, 3))
-                               goto err;
-                       if (!BN_nnmod(r, r, p, ctx))
-                               goto err;
-                       if (!BN_mod_sqr(r, r, p, ctx))
-                               goto err;
-                       if (!BN_bntest_rand(a, 256, 0, 3))
-                               goto err;
-                       if (!BN_nnmod(a, a, p, ctx))
-                               goto err;
-                       if (!BN_mod_sqr(a, a, p, ctx))
-                               goto err;
-                       if (!BN_mul(a, a, r, ctx))
-                               goto err;
-                       if (rand_neg())
-                               if (!BN_sub(a, a, p))
-                                       goto err;
-
-                       if (!BN_mod_sqrt(r, a, p, ctx))
-                               goto err;
-                       if (!BN_mod_sqr(r, r, p, ctx))
-                               goto err;
-
-                       if (!BN_nnmod(a, a, p, ctx))
-                               goto err;
-
-                       if (BN_cmp(a, r) != 0) {
-                               fprintf(stderr, "BN_mod_sqrt failed: a = ");
-                               CHECK_GOTO(BN_print_fp(stderr, a));
-                               fprintf(stderr, ", r = ");
-                               CHECK_GOTO(BN_print_fp(stderr, r));
-                               fprintf(stderr, ", p = ");
-                               CHECK_GOTO(BN_print_fp(stderr, p));
-                               fprintf(stderr, "\n");
-                               goto err;
-                       }
-
-                       putc('.', stderr);
-               }
-
-               putc('\n', stderr);
-       }
-       rc = 1;
-
- err:
-       BN_GENCB_free(cb);
-       BN_free(a);
-       BN_free(p);
-       BN_free(r);
-       return rc;
-}
-
-int
-test_lshift(BIO *bp, BN_CTX *ctx, BIGNUM *a_)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL;
-       int i;
-       int rc = 1;
-
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       CHECK_GOTO(BN_one(c));
-
-       if (a_)
-               a = a_;
-       else {
-               if ((a = BN_new()) == NULL)
-               goto err;
-               CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0));
-               BN_set_negative(a, rand_neg());
-       }
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_lshift(b, a, i + 1));
-               CHECK_GOTO(BN_add(c, c, c));
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " * ");
-                               CHECK_GOTO(BN_print(bp, c));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, b));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_mul(d, a, c, ctx));
-               CHECK_GOTO(BN_sub(d, d, b));
-               if (!BN_is_zero(d)) {
-                       fprintf(stderr, "Left shift test failed!\n");
-                       fprintf(stderr, "a=");
-                       CHECK_GOTO(BN_print_fp(stderr, a));
-                       fprintf(stderr, "\nb=");
-                       CHECK_GOTO(BN_print_fp(stderr, b));
-                       fprintf(stderr, "\nc=");
-                       CHECK_GOTO(BN_print_fp(stderr, c));
-                       fprintf(stderr, "\nd=");
-                       CHECK_GOTO(BN_print_fp(stderr, d));
-                       fprintf(stderr, "\n");
-                       rc = 0;
-                       break;
-               }
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       BN_free(d);
-       return (rc);
-}
-
-int
-test_lshift1(BIO *bp)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL;
-       int i;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0));
-       BN_set_negative(a, rand_neg());
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_lshift1(b, a));
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " * 2");
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, b));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_add(c, a, a));
-               CHECK_GOTO(BN_sub(a, b, c));
-               if (!BN_is_zero(a)) {
-                       fprintf(stderr, "Left shift one test failed!\n");
-                       rc = 0;
-                       break;
-               }
-
-               CHECK_GOTO(BN_copy(a, b));
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       return (rc);
-}
-
-int
-test_rshift(BIO *bp, BN_CTX *ctx)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
-       int i;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-       if ((d = BN_new()) == NULL)
-               goto err;
-       if ((e = BN_new()) == NULL)
-               goto err;
-       CHECK_GOTO(BN_one(c));
-
-       CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0));
-       BN_set_negative(a, rand_neg());
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_rshift(b, a, i + 1));
-               CHECK_GOTO(BN_add(c, c, c));
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " / ");
-                               CHECK_GOTO(BN_print(bp, c));
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, b));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_div(d, e, a, c, ctx));
-               CHECK_GOTO(BN_sub(d, d, b));
-               if (!BN_is_zero(d)) {
-                       fprintf(stderr, "Right shift test failed!\n");
-                       rc = 0;
-                       break;
-               }
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       BN_free(d);
-       BN_free(e);
-       return (rc);
-}
-
-int
-test_rshift1(BIO *bp)
-{
-       BIGNUM *a = NULL, *b = NULL, *c = NULL;
-       int i;
-       int rc = 1;
-
-       if ((a = BN_new()) == NULL)
-               goto err;
-       if ((b = BN_new()) == NULL)
-               goto err;
-       if ((c = BN_new()) == NULL)
-               goto err;
-
-       CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0));
-       BN_set_negative(a, rand_neg());
-       for (i = 0; i < num0; i++) {
-               CHECK_GOTO(BN_rshift1(b, a));
-               if (bp != NULL) {
-                       if (!results) {
-                               CHECK_GOTO(BN_print(bp, a));
-                               BIO_puts(bp, " / 2");
-                               BIO_puts(bp, " - ");
-                       }
-                       CHECK_GOTO(BN_print(bp, b));
-                       BIO_puts(bp, "\n");
-               }
-               CHECK_GOTO(BN_sub(c, a, b));
-               CHECK_GOTO(BN_sub(c, c, b));
-               if (!BN_is_zero(c) && !BN_abs_is_word(c, 1)) {
-                       fprintf(stderr, "Right shift one test failed!\n");
-                       rc = 0;
-                       break;
-               }
-               CHECK_GOTO(BN_copy(a, b));
-       }
- err:
-       BN_free(a);
-       BN_free(b);
-       BN_free(c);
-       return (rc);
-}
-
-int
-rand_neg(void)
-{
-       static unsigned int neg = 0;
-       static int sign[8] = { 0, 0, 0, 1, 1, 0, 1, 1 };
-
-       return (sign[(neg++) % 8]);
-}
-
-int
-test_mod_exp_sizes(BIO *bp, BN_CTX *ctx)
-{
-       BN_MONT_CTX *mont_ctx = NULL;
-       BIGNUM *p = NULL, *x = NULL, *y = NULL, *r = NULL, *r2 = NULL;
-       int size;
-       int rc = 0;
-
-       BN_CTX_start(ctx);
-       CHECK_GOTO(p = BN_CTX_get(ctx));
-       CHECK_GOTO(x = BN_CTX_get(ctx));
-       CHECK_GOTO(y = BN_CTX_get(ctx));
-       CHECK_GOTO(r = BN_CTX_get(ctx));
-       CHECK_GOTO(r2 = BN_CTX_get(ctx));
-       mont_ctx = BN_MONT_CTX_new();
-
-       if (r2 == NULL || mont_ctx == NULL)
-               goto err;
-
-       if (!BN_generate_prime_ex(p, 32, 0, NULL, NULL, NULL) ||
-           !BN_MONT_CTX_set(mont_ctx, p, ctx))
-               goto err;
-
-       for (size = 32; size < 1024; size += 8) {
-               if (!BN_rand(x, size, -1, 0) ||
-                   !BN_rand(y, size, -1, 0) ||
-                   !BN_mod_exp_mont_consttime(r, x, y, p, ctx, mont_ctx) ||
-                   !BN_mod_exp(r2, x, y, p, ctx))
-                       goto err;
-
-               if (BN_cmp(r, r2) != 0) {
-                       char *r_str = NULL;
-                       char *r2_str = NULL;
-                       CHECK_GOTO(r_str = BN_bn2hex(r));
-                       CHECK_GOTO(r2_str = BN_bn2hex(r2));
-
-                       printf("Incorrect answer at size %d: %s vs %s\n",
-                           size, r_str, r2_str);
-                       free(r_str);
-                       free(r2_str);
-                       goto err;
-               }
-       }
-
-       rc = 1;
-
- err:
-       BN_MONT_CTX_free(mont_ctx);
-       BN_CTX_end(ctx);
-       return rc;
-}
diff --git a/regress/lib/libcrypto/bn/mont/Makefile b/regress/lib/libcrypto/bn/mont/Makefile
deleted file mode 100644 (file)
index 55c4822..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#      $OpenBSD: Makefile,v 1.3 2017/01/21 09:38:58 beck Exp $
-
-PROG=  mont
-LDADD= -lcrypto
-DPADD= ${LIBCRYPTO}
-WARNINGS=      Yes
-CFLAGS+=       -Werror
-
-.include <bsd.regress.mk>
diff --git a/regress/lib/libcrypto/bn/mont/mont.c b/regress/lib/libcrypto/bn/mont/mont.c
deleted file mode 100644 (file)
index 8b9b14a..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*     $OpenBSD: mont.c,v 1.6 2022/01/14 09:32:27 tb Exp $     */
-
-/*
- * Copyright (c) 2014 Miodrag Vallat.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <err.h>
-
-#include <openssl/bn.h>
-#include <openssl/crypto.h>
-#include <openssl/dh.h>
-#include <openssl/err.h>
-
-/*
- * Test for proper bn_mul_mont behaviour when operands are of vastly different
- * sizes.
- */
-
-int
-main(int argc, char *argv[])
-{
-       DH *dh = NULL;
-       BIGNUM *priv_key = NULL;
-       unsigned char *key = NULL;
-       unsigned char r[32 + 16 * 8];
-       size_t privsz;
-
-       arc4random_buf(r, sizeof(r));
-
-       for (privsz = 32; privsz <= sizeof(r); privsz += 8) {
-               dh = DH_new();
-               if (dh == NULL)
-                       goto err;
-               if (DH_generate_parameters_ex(dh, 32, DH_GENERATOR_2,
-                   NULL) == 0)
-                       goto err;
-
-               /* force private key to be much larger than public one */
-               priv_key = BN_bin2bn(r, privsz, NULL);
-               if (priv_key == NULL)
-                       goto err;
-
-               if (!DH_set0_key(dh, NULL, priv_key))
-                       goto err;
-               priv_key = NULL;
-
-               if (DH_generate_key(dh) == 0)
-                       goto err;
-               key = malloc(DH_size(dh));
-               if (key == NULL)
-                       err(1, "malloc");
-               if (DH_compute_key(key, DH_get0_pub_key(dh), dh) == -1)
-                       goto err;
-
-               free(key);
-               key = NULL;
-               DH_free(dh);
-               dh = NULL;
-       }
-
-       return 0;
-
- err:
-       ERR_print_errors_fp(stderr);
-       free(key);
-       BN_free(priv_key);
-       DH_free(dh);
-       return 1;
-}
diff --git a/regress/lib/libcrypto/bn/rand/Makefile b/regress/lib/libcrypto/bn/rand/Makefile
deleted file mode 100644 (file)
index 52d0835..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#      $OpenBSD: Makefile,v 1.1 2018/11/06 06:55:27 tb Exp $
-
-.include "../../Makefile.inc"
-
-PROG=  bn_rand_interval
-LDADD= ${CRYPTO_INT}
-DPADD= ${LIBCRYPTO}
-WARNINGS=      Yes
-CFLAGS+=       -Werror
-
-.include <bsd.regress.mk>
diff --git a/regress/lib/libcrypto/bn/rand/bn_rand_interval.c b/regress/lib/libcrypto/bn/rand/bn_rand_interval.c
deleted file mode 100644 (file)
index 8cd5527..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*     $OpenBSD: bn_rand_interval.c,v 1.6 2022/12/01 13:49:12 tb Exp $ */
-/*
- * Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <err.h>
-#include <stdio.h>
-
-#include <openssl/bn.h>
-
-#define NUM_TESTS 1000000
-
-int bn_rand_interval(BIGNUM *rnd, const BIGNUM *lower_incl,
-    const BIGNUM *upper_excl);
-void print_triple(BIGNUM *a, BIGNUM *b, BIGNUM *x);
-
-void
-print_triple(BIGNUM *a, BIGNUM *b, BIGNUM *x) {
-       if (a != NULL) {
-               printf("a = ");
-               BN_print_fp(stdout, a);
-               printf("\n");
-       }
-
-       if (b != NULL) {
-               printf("b = ");
-               BN_print_fp(stdout, b);
-               printf("\n");
-       }
-
-       if (x != NULL) {
-               printf("x = ");
-               BN_print_fp(stdout, x);
-               printf("\n");
-       }
-}
-
-int
-main(int argc, char *argv[])
-{
-       BIGNUM *a, *b, *x;
-       int i, success = 1;
-
-       if ((a = BN_new()) == NULL)
-               errx(1, "BN_new(a)");
-       if ((b = BN_new()) == NULL)
-               errx(1, "BN_new(b)");
-       if ((x = BN_new()) == NULL)
-               errx(1, "BN_new(c)");
-
-       for (i = 0; i < NUM_TESTS; i++) {
-               if (!BN_rand(a, 256, 0, 0))
-                       errx(1, "BN_rand(a)");
-
-               if (bn_rand_interval(x, a, a) != 0) {
-                       success = 0;
-
-                       printf("bn_rand_interval(a == a) succeeded\n");
-                       print_triple(a, NULL, x);
-               }
-
-               if (!BN_rand(b, 256, 0, 0))
-                       errx(1, "BN_rand(b)");
-
-               switch(BN_cmp(a, b)) {
-               case 0:         /* a == b */
-                       continue;
-
-               case 1:         /* a > b */
-                       BN_swap(a, b);
-                       break;
-
-               default:        /* a < b */
-                       break;
-               }
-
-               if (!bn_rand_interval(x, a, b))
-                       errx(1, "bn_rand_interval() failed");
-
-               if (BN_cmp(x, a) < 0 || BN_cmp(x, b) >= 0) {
-                       success = 0;
-
-                       printf("generated number x not inside [a,b)\n");
-                       print_triple(a, b, x);
-               }
-
-               if (bn_rand_interval(x, b, a) != 0) {
-                       success = 0;
-
-                       printf("bn_rand_interval(x, b, a) succeeded\n");
-                       print_triple(a, b, x);
-               }
-       }
-
-       BN_free(a);
-       BN_free(b);
-       BN_free(x);
-
-       return 1 - success;
-}