xref: /openbsd/regress/lib/libcrypto/bn/bn_test.c (revision 8f4cde5d)
1*8f4cde5dStb /*	$OpenBSD: bn_test.c,v 1.19 2023/04/25 17:17:21 tb Exp $	*/
2b8d22d11Stb /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3b8d22d11Stb  * All rights reserved.
4b8d22d11Stb  *
5b8d22d11Stb  * This package is an SSL implementation written
6b8d22d11Stb  * by Eric Young (eay@cryptsoft.com).
7b8d22d11Stb  * The implementation was written so as to conform with Netscapes SSL.
8b8d22d11Stb  *
9b8d22d11Stb  * This library is free for commercial and non-commercial use as long as
10b8d22d11Stb  * the following conditions are aheared to.  The following conditions
11b8d22d11Stb  * apply to all code found in this distribution, be it the RC4, RSA,
12b8d22d11Stb  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13b8d22d11Stb  * included with this distribution is covered by the same copyright terms
14b8d22d11Stb  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15b8d22d11Stb  *
16b8d22d11Stb  * Copyright remains Eric Young's, and as such any Copyright notices in
17b8d22d11Stb  * the code are not to be removed.
18b8d22d11Stb  * If this package is used in a product, Eric Young should be given attribution
19b8d22d11Stb  * as the author of the parts of the library used.
20b8d22d11Stb  * This can be in the form of a textual message at program startup or
21b8d22d11Stb  * in documentation (online or textual) provided with the package.
22b8d22d11Stb  *
23b8d22d11Stb  * Redistribution and use in source and binary forms, with or without
24b8d22d11Stb  * modification, are permitted provided that the following conditions
25b8d22d11Stb  * are met:
26b8d22d11Stb  * 1. Redistributions of source code must retain the copyright
27b8d22d11Stb  *    notice, this list of conditions and the following disclaimer.
28b8d22d11Stb  * 2. Redistributions in binary form must reproduce the above copyright
29b8d22d11Stb  *    notice, this list of conditions and the following disclaimer in the
30b8d22d11Stb  *    documentation and/or other materials provided with the distribution.
31b8d22d11Stb  * 3. All advertising materials mentioning features or use of this software
32b8d22d11Stb  *    must display the following acknowledgement:
33b8d22d11Stb  *    "This product includes cryptographic software written by
34b8d22d11Stb  *     Eric Young (eay@cryptsoft.com)"
35b8d22d11Stb  *    The word 'cryptographic' can be left out if the rouines from the library
36b8d22d11Stb  *    being used are not cryptographic related :-).
37b8d22d11Stb  * 4. If you include any Windows specific code (or a derivative thereof) from
38b8d22d11Stb  *    the apps directory (application code) you must include an acknowledgement:
39b8d22d11Stb  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40b8d22d11Stb  *
41b8d22d11Stb  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42b8d22d11Stb  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43b8d22d11Stb  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44b8d22d11Stb  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45b8d22d11Stb  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46b8d22d11Stb  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47b8d22d11Stb  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48b8d22d11Stb  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49b8d22d11Stb  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50b8d22d11Stb  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51b8d22d11Stb  * SUCH DAMAGE.
52b8d22d11Stb  *
53b8d22d11Stb  * The licence and distribution terms for any publically available version or
54b8d22d11Stb  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55b8d22d11Stb  * copied and put under another distribution licence
56b8d22d11Stb  * [including the GNU Public Licence.]
57b8d22d11Stb  */
58b8d22d11Stb /* ====================================================================
59b8d22d11Stb  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60b8d22d11Stb  *
61b8d22d11Stb  * Portions of the attached software ("Contribution") are developed by
62b8d22d11Stb  * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63b8d22d11Stb  *
64b8d22d11Stb  * The Contribution is licensed pursuant to the Eric Young open source
65b8d22d11Stb  * license provided above.
66b8d22d11Stb  *
67b8d22d11Stb  * The binary polynomial arithmetic software is originally written by
68b8d22d11Stb  * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69b8d22d11Stb  *
70b8d22d11Stb  */
71b8d22d11Stb 
72b8d22d11Stb #include <stdio.h>
73b8d22d11Stb #include <stdlib.h>
74b8d22d11Stb #include <string.h>
75b8d22d11Stb 
76b8d22d11Stb #include <openssl/bio.h>
77b8d22d11Stb #include <openssl/bn.h>
78b8d22d11Stb #include <openssl/err.h>
79b8d22d11Stb 
8020c8b67dStb #include "bn_local.h"
81b8d22d11Stb 
82b8d22d11Stb const int num0 = 100; /* number of tests */
83b8d22d11Stb const int num1 = 50;  /* additional tests for some functions */
84b8d22d11Stb const int num2 = 5;   /* number of tests for slow functions */
85b8d22d11Stb 
860edabd22Stb int test_add(BIO *bp, BN_CTX *ctx);
870edabd22Stb int test_sub(BIO *bp, BN_CTX *ctx);
880edabd22Stb int test_lshift1(BIO *bp, BN_CTX *ctx);
894bbad1a5Stb int test_lshift(BIO *bp, BN_CTX *ctx, int use_lst);
900edabd22Stb int test_rshift1(BIO *bp, BN_CTX *ctx);
91b8d22d11Stb int test_rshift(BIO *bp, BN_CTX *ctx);
92b8d22d11Stb int test_div(BIO *bp, BN_CTX *ctx);
930edabd22Stb int test_div_word(BIO *bp, BN_CTX *ctx);
94b8d22d11Stb int test_div_recp(BIO *bp, BN_CTX *ctx);
950edabd22Stb int test_mul(BIO *bp, BN_CTX *ctx);
96b8d22d11Stb int test_sqr(BIO *bp, BN_CTX *ctx);
97b8d22d11Stb int test_mont(BIO *bp, BN_CTX *ctx);
98b8d22d11Stb int test_mod(BIO *bp, BN_CTX *ctx);
99b8d22d11Stb int test_mod_mul(BIO *bp, BN_CTX *ctx);
100b8d22d11Stb int test_mod_exp(BIO *bp, BN_CTX *ctx);
101b8d22d11Stb int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx);
102b8d22d11Stb int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx);
103b8d22d11Stb int test_mod_exp_sizes(BIO *bp, BN_CTX *ctx);
104b8d22d11Stb int test_exp(BIO *bp, BN_CTX *ctx);
105b8d22d11Stb int test_kron(BIO *bp, BN_CTX *ctx);
106b8d22d11Stb int test_sqrt(BIO *bp, BN_CTX *ctx);
107b8d22d11Stb int rand_neg(void);
108b8d22d11Stb static int results = 0;
109b8d22d11Stb 
110b8d22d11Stb #define PRINT_ERROR printf("Error in %s [%s:%d]\n", __func__, __FILE__,	\
111b8d22d11Stb 		__LINE__)
112b8d22d11Stb 
113b8d22d11Stb #define CHECK_GOTO(a) do {						\
114b8d22d11Stb 	if (!(a)) {							\
115b8d22d11Stb 		PRINT_ERROR;						\
116b8d22d11Stb 		goto err;						\
117b8d22d11Stb 	}								\
118b8d22d11Stb } while (0)
119b8d22d11Stb 
120b8d22d11Stb static void
message(BIO * out,char * m)121b8d22d11Stb message(BIO *out, char *m)
122b8d22d11Stb {
1235550240dStb 	ERR_print_errors_fp(stderr);
1245550240dStb 	ERR_clear_error();
1255550240dStb 
126b8d22d11Stb 	fprintf(stderr, "test %s\n", m);
127b8d22d11Stb 	BIO_puts(out, "print \"test ");
128b8d22d11Stb 	BIO_puts(out, m);
129b8d22d11Stb 	BIO_puts(out, "\\n\"\n");
130b8d22d11Stb }
131b8d22d11Stb 
132b8d22d11Stb int
main(int argc,char * argv[])133b8d22d11Stb main(int argc, char *argv[])
134b8d22d11Stb {
135b8d22d11Stb 	BN_CTX *ctx;
136b8d22d11Stb 	BIO *out;
137b8d22d11Stb 	char *outfile = NULL;
138b8d22d11Stb 
139b8d22d11Stb 	results = 0;
140b8d22d11Stb 
141b8d22d11Stb 	argc--;
142b8d22d11Stb 	argv++;
143b8d22d11Stb 	while (argc >= 1) {
144b8d22d11Stb 		if (strcmp(*argv, "-results") == 0)
145b8d22d11Stb 			results = 1;
146b8d22d11Stb 		else if (strcmp(*argv, "-out") == 0) {
147b8d22d11Stb 			if (--argc < 1)
148b8d22d11Stb 				break;
149b8d22d11Stb 			outfile= *(++argv);
150b8d22d11Stb 		}
151b8d22d11Stb 		argc--;
152b8d22d11Stb 		argv++;
153b8d22d11Stb 	}
154b8d22d11Stb 
1551604cb40Stb 	if ((ctx = BN_CTX_new()) == NULL)
156b8d22d11Stb 		exit(1);
157b8d22d11Stb 
1581604cb40Stb 	if ((out = BIO_new(BIO_s_file())) == NULL)
159b8d22d11Stb 		exit(1);
160b8d22d11Stb 	if (outfile == NULL) {
161b8d22d11Stb 		BIO_set_fp(out, stdout, BIO_NOCLOSE);
162b8d22d11Stb 	} else {
163b8d22d11Stb 		if (!BIO_write_filename(out, outfile)) {
164b8d22d11Stb 			perror(outfile);
165b8d22d11Stb 			exit(1);
166b8d22d11Stb 		}
167b8d22d11Stb 	}
168b8d22d11Stb 
169b8d22d11Stb 	if (!results)
170b8d22d11Stb 		BIO_puts(out, "obase=16\nibase=16\n");
171b8d22d11Stb 
172b8d22d11Stb 	message(out, "BN_add");
1730edabd22Stb 	if (!test_add(out, ctx))
174b8d22d11Stb 		goto err;
175b8d22d11Stb 	(void)BIO_flush(out);
176b8d22d11Stb 
177b8d22d11Stb 	message(out, "BN_sub");
1780edabd22Stb 	if (!test_sub(out, ctx))
179b8d22d11Stb 		goto err;
180b8d22d11Stb 	(void)BIO_flush(out);
181b8d22d11Stb 
182b8d22d11Stb 	message(out, "BN_lshift1");
1830edabd22Stb 	if (!test_lshift1(out, ctx))
184b8d22d11Stb 		goto err;
185b8d22d11Stb 	(void)BIO_flush(out);
186b8d22d11Stb 
187b8d22d11Stb 	message(out, "BN_lshift (fixed)");
1884bbad1a5Stb 	if (!test_lshift(out, ctx, 0))
189b8d22d11Stb 		goto err;
190b8d22d11Stb 	(void)BIO_flush(out);
191b8d22d11Stb 
1920edabd22Stb 	message(out, "BN_lshift");
1930edabd22Stb 	if (!test_lshift(out, ctx, 1))
1940edabd22Stb 		goto err;
1950edabd22Stb 	(void)BIO_flush(out);
1960edabd22Stb 
197b8d22d11Stb 	message(out, "BN_rshift1");
1980edabd22Stb 	if (!test_rshift1(out, ctx))
199b8d22d11Stb 		goto err;
200b8d22d11Stb 	(void)BIO_flush(out);
201b8d22d11Stb 
202b8d22d11Stb 	message(out, "BN_rshift");
203b8d22d11Stb 	if (!test_rshift(out, ctx))
204b8d22d11Stb 		goto err;
205b8d22d11Stb 	(void)BIO_flush(out);
206b8d22d11Stb 
207b8d22d11Stb 	message(out, "BN_sqr");
208b8d22d11Stb 	if (!test_sqr(out, ctx))
209b8d22d11Stb 		goto err;
210b8d22d11Stb 	(void)BIO_flush(out);
211b8d22d11Stb 
212b8d22d11Stb 	message(out, "BN_mul");
2130edabd22Stb 	if (!test_mul(out, ctx))
214b8d22d11Stb 		goto err;
215b8d22d11Stb 	(void)BIO_flush(out);
216b8d22d11Stb 
217b8d22d11Stb 	message(out, "BN_div");
218b8d22d11Stb 	if (!test_div(out, ctx))
219b8d22d11Stb 		goto err;
220b8d22d11Stb 	(void)BIO_flush(out);
221b8d22d11Stb 
222b8d22d11Stb 	message(out, "BN_div_word");
2230edabd22Stb 	if (!test_div_word(out, ctx))
224b8d22d11Stb 		goto err;
225b8d22d11Stb 	(void)BIO_flush(out);
226b8d22d11Stb 
227b8d22d11Stb 	message(out, "BN_div_recp");
228b8d22d11Stb 	if (!test_div_recp(out, ctx))
229b8d22d11Stb 		goto err;
230b8d22d11Stb 	(void)BIO_flush(out);
231b8d22d11Stb 
232b8d22d11Stb 	message(out, "BN_mod");
233b8d22d11Stb 	if (!test_mod(out, ctx))
234b8d22d11Stb 		goto err;
235b8d22d11Stb 	(void)BIO_flush(out);
236b8d22d11Stb 
237b8d22d11Stb 	message(out, "BN_mod_mul");
238b8d22d11Stb 	if (!test_mod_mul(out, ctx))
239b8d22d11Stb 		goto err;
240b8d22d11Stb 	(void)BIO_flush(out);
241b8d22d11Stb 
242b8d22d11Stb 	message(out, "BN_mont");
243b8d22d11Stb 	if (!test_mont(out, ctx))
244b8d22d11Stb 		goto err;
245b8d22d11Stb 	(void)BIO_flush(out);
246b8d22d11Stb 
247b8d22d11Stb 	message(out, "BN_mod_exp");
248b8d22d11Stb 	if (!test_mod_exp(out, ctx))
249b8d22d11Stb 		goto err;
250b8d22d11Stb 	(void)BIO_flush(out);
251b8d22d11Stb 
252b8d22d11Stb 	message(out, "BN_mod_exp_mont_consttime");
253b8d22d11Stb 	if (!test_mod_exp_mont_consttime(out, ctx))
254b8d22d11Stb 		goto err;
255b8d22d11Stb 	(void)BIO_flush(out);
256b8d22d11Stb 
257b8d22d11Stb 	message(out, "BN_mod_exp_mont5");
258b8d22d11Stb 	if (!test_mod_exp_mont5(out, ctx))
259b8d22d11Stb 		goto err;
260b8d22d11Stb 	(void)BIO_flush(out);
261b8d22d11Stb 
262b8d22d11Stb 	message(out, "BN_exp");
263b8d22d11Stb 	if (!test_exp(out, ctx))
264b8d22d11Stb 		goto err;
265b8d22d11Stb 	(void)BIO_flush(out);
266b8d22d11Stb 
267b8d22d11Stb 	message(out, "BN_kronecker");
268b8d22d11Stb 	if (!test_kron(out, ctx))
269b8d22d11Stb 		goto err;
270b8d22d11Stb 	(void)BIO_flush(out);
271b8d22d11Stb 
272b8d22d11Stb 	message(out, "BN_mod_sqrt");
273b8d22d11Stb 	if (!test_sqrt(out, ctx))
274b8d22d11Stb 		goto err;
275b8d22d11Stb 	(void)BIO_flush(out);
276b8d22d11Stb 
277b8d22d11Stb 	message(out, "Modexp with different sizes");
278b8d22d11Stb 	if (!test_mod_exp_sizes(out, ctx))
279b8d22d11Stb 		goto err;
280b8d22d11Stb 	(void)BIO_flush(out);
281b8d22d11Stb 
282b8d22d11Stb 	BN_CTX_free(ctx);
283b8d22d11Stb 	BIO_free(out);
284b8d22d11Stb 
285b8d22d11Stb 	exit(0);
286b8d22d11Stb  err:
287b8d22d11Stb 	BIO_puts(out, "1\n"); /* make sure the Perl script fed by bc notices
288b8d22d11Stb 	                       * the failure, see test_bn in test/Makefile.ssl*/
289b8d22d11Stb 
290b8d22d11Stb 	(void)BIO_flush(out);
291b8d22d11Stb 	ERR_load_crypto_strings();
292b8d22d11Stb 	ERR_print_errors_fp(stderr);
293b8d22d11Stb 	exit(1);
294b8d22d11Stb }
295b8d22d11Stb 
296b8d22d11Stb int
test_add(BIO * bp,BN_CTX * ctx)2970edabd22Stb test_add(BIO *bp, BN_CTX *ctx)
298b8d22d11Stb {
2990edabd22Stb 	BIGNUM *a, *b, *c;
300b8d22d11Stb 	int i;
301f7264475Stb 	int ret = 0;
302b8d22d11Stb 
3030edabd22Stb 	BN_CTX_start(ctx);
3040edabd22Stb 
3050edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
306b8d22d11Stb 		goto err;
3070edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
308b8d22d11Stb 		goto err;
3090edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
310b8d22d11Stb 		goto err;
311b8d22d11Stb 
312b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
313b8d22d11Stb 	for (i = 0; i < num0; i++) {
314b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(b, 450 + i, 0, 0));
315b8d22d11Stb 		BN_set_negative(a, rand_neg());
316b8d22d11Stb 		BN_set_negative(b, rand_neg());
317b8d22d11Stb 		CHECK_GOTO(BN_add(c, a, b));
318b8d22d11Stb 		if (bp != NULL) {
319b8d22d11Stb 			if (!results) {
320b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
321b8d22d11Stb 				BIO_puts(bp, " + ");
322b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
323b8d22d11Stb 				BIO_puts(bp, " - ");
324b8d22d11Stb 			}
325b8d22d11Stb 			CHECK_GOTO(BN_print(bp, c));
326b8d22d11Stb 			BIO_puts(bp, "\n");
327b8d22d11Stb 		}
328b8d22d11Stb 		BN_set_negative(a, !BN_is_negative(a));
329b8d22d11Stb 		BN_set_negative(b, !BN_is_negative(b));
330b8d22d11Stb 		CHECK_GOTO(BN_add(c, c, b));
331b8d22d11Stb 		CHECK_GOTO(BN_add(c, c, a));
332b8d22d11Stb 		if (!BN_is_zero(c)) {
333b8d22d11Stb 			fprintf(stderr, "Add test failed!\n");
3342e7cce5eStb 			goto err;
335b8d22d11Stb 		}
336b8d22d11Stb 	}
337b8d22d11Stb 
338f7264475Stb 	ret = 1;
339b8d22d11Stb  err:
3400edabd22Stb 	BN_CTX_end(ctx);
341b8d22d11Stb 
342f7264475Stb 	return ret;
343b8d22d11Stb }
344b8d22d11Stb 
345b8d22d11Stb int
test_sub(BIO * bp,BN_CTX * ctx)3460edabd22Stb test_sub(BIO *bp, BN_CTX *ctx)
347b8d22d11Stb {
3480edabd22Stb 	BIGNUM *a, *b, *c;
349b8d22d11Stb 	int i;
350f7264475Stb 	int ret = 0;
351b8d22d11Stb 
3520edabd22Stb 	BN_CTX_start(ctx);
3530edabd22Stb 
3540edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
355b8d22d11Stb 		goto err;
3560edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
357b8d22d11Stb 		goto err;
3580edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
359b8d22d11Stb 		goto err;
360b8d22d11Stb 
361b8d22d11Stb 	for (i = 0; i < num0 + num1; i++) {
362b8d22d11Stb 		if (i < num1) {
363b8d22d11Stb 			CHECK_GOTO(BN_bntest_rand(a, 512, 0, 0));
3648e84e241Stb 			CHECK_GOTO(bn_copy(b, a));
365457e5092Stb 			if (BN_set_bit(a, i) == 0)
3662e7cce5eStb 				goto err;
367b8d22d11Stb 			CHECK_GOTO(BN_add_word(b, i));
368b8d22d11Stb 		} else {
369b8d22d11Stb 			CHECK_GOTO(BN_bntest_rand(b, 400 + i - num1, 0, 0));
370b8d22d11Stb 			BN_set_negative(a, rand_neg());
371b8d22d11Stb 			BN_set_negative(b, rand_neg());
372b8d22d11Stb 		}
373b8d22d11Stb 		CHECK_GOTO(BN_sub(c, a, b));
374b8d22d11Stb 		if (bp != NULL) {
375b8d22d11Stb 			if (!results) {
376b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
377b8d22d11Stb 				BIO_puts(bp, " - ");
378b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
379b8d22d11Stb 				BIO_puts(bp, " - ");
380b8d22d11Stb 			}
381b8d22d11Stb 			CHECK_GOTO(BN_print(bp, c));
382b8d22d11Stb 			BIO_puts(bp, "\n");
383b8d22d11Stb 		}
384b8d22d11Stb 		CHECK_GOTO(BN_add(c, c, b));
385b8d22d11Stb 		CHECK_GOTO(BN_sub(c, c, a));
386b8d22d11Stb 		if (!BN_is_zero(c)) {
387b8d22d11Stb 			fprintf(stderr, "Subtract test failed!\n");
3882e7cce5eStb 			goto err;
389b8d22d11Stb 		}
390b8d22d11Stb 	}
3912e7cce5eStb 
392f7264475Stb 	ret = 1;
393b8d22d11Stb  err:
3940edabd22Stb 	BN_CTX_end(ctx);
3952e7cce5eStb 
396f7264475Stb 	return ret;
397b8d22d11Stb }
398b8d22d11Stb 
399b8d22d11Stb int
test_div(BIO * bp,BN_CTX * ctx)400b8d22d11Stb test_div(BIO *bp, BN_CTX *ctx)
401b8d22d11Stb {
4020edabd22Stb 	BIGNUM *a, *b, *c, *d, *e;
403b8d22d11Stb 	int i;
404f7264475Stb 	int ret = 0;
405b8d22d11Stb 
4060edabd22Stb 	BN_CTX_start(ctx);
4070edabd22Stb 
4080edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
409b8d22d11Stb 		goto err;
4100edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
411b8d22d11Stb 		goto err;
4120edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
413b8d22d11Stb 		goto err;
4140edabd22Stb 	if ((d = BN_CTX_get(ctx)) == NULL)
415b8d22d11Stb 		goto err;
4160edabd22Stb 	if ((e = BN_CTX_get(ctx)) == NULL)
417b8d22d11Stb 		goto err;
418b8d22d11Stb 
419b8d22d11Stb 	CHECK_GOTO(BN_one(a));
42030ad135cStb 	BN_zero(b);
421b8d22d11Stb 
422b8d22d11Stb 	if (BN_div(d, c, a, b, ctx)) {
423b8d22d11Stb 		fprintf(stderr, "Division by zero succeeded!\n");
424bb44b87cStb 		goto err;
425b8d22d11Stb 	}
4265550240dStb 	ERR_clear_error();
427b8d22d11Stb 
428b8d22d11Stb 	for (i = 0; i < num0 + num1; i++) {
429b8d22d11Stb 		if (i < num1) {
430b8d22d11Stb 			CHECK_GOTO(BN_bntest_rand(a, 400, 0, 0));
4318e84e241Stb 			CHECK_GOTO(bn_copy(b, a));
432b8d22d11Stb 			CHECK_GOTO(BN_lshift(a, a, i));
433b8d22d11Stb 			CHECK_GOTO(BN_add_word(a, i));
434b8d22d11Stb 		} else
435b8d22d11Stb 			CHECK_GOTO(BN_bntest_rand(b, 50 + 3 * (i - num1), 0, 0));
436b8d22d11Stb 		BN_set_negative(a, rand_neg());
437b8d22d11Stb 		BN_set_negative(b, rand_neg());
438b8d22d11Stb 		CHECK_GOTO(BN_div(d, c, a, b, ctx));
439b8d22d11Stb 		if (bp != NULL) {
440b8d22d11Stb 			if (!results) {
441b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
442b8d22d11Stb 				BIO_puts(bp, " / ");
443b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
444b8d22d11Stb 				BIO_puts(bp, " - ");
445b8d22d11Stb 			}
446b8d22d11Stb 			CHECK_GOTO(BN_print(bp, d));
447b8d22d11Stb 			BIO_puts(bp, "\n");
448b8d22d11Stb 
449b8d22d11Stb 			if (!results) {
450b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
451b8d22d11Stb 				BIO_puts(bp, " % ");
452b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
453b8d22d11Stb 				BIO_puts(bp, " - ");
454b8d22d11Stb 			}
455b8d22d11Stb 			CHECK_GOTO(BN_print(bp, c));
456b8d22d11Stb 			BIO_puts(bp, "\n");
457b8d22d11Stb 		}
458b8d22d11Stb 		CHECK_GOTO(BN_mul(e, d, b, ctx));
459b8d22d11Stb 		CHECK_GOTO(BN_add(d, e, c));
460b8d22d11Stb 		CHECK_GOTO(BN_sub(d, d, a));
461b8d22d11Stb 		if (!BN_is_zero(d)) {
462b8d22d11Stb 			fprintf(stderr, "Division test failed!\n");
4632e7cce5eStb 			goto err;
464b8d22d11Stb 		}
465b8d22d11Stb 	}
4662e7cce5eStb 
467f7264475Stb 	ret = 1;
468b8d22d11Stb  err:
4690edabd22Stb 	BN_CTX_end(ctx);
4702e7cce5eStb 
471f7264475Stb 	return ret;
472b8d22d11Stb }
473b8d22d11Stb 
474b8d22d11Stb static void
print_word(BIO * bp,BN_ULONG w)475b8d22d11Stb print_word(BIO *bp, BN_ULONG w)
476b8d22d11Stb {
477b8d22d11Stb #ifdef SIXTY_FOUR_BIT
478b8d22d11Stb 	if (sizeof(w) > sizeof(unsigned long)) {
479b8d22d11Stb 		unsigned long h = (unsigned long)(w >> 32), l = (unsigned long)(w);
480b8d22d11Stb 
481b8d22d11Stb 		if (h)
482b8d22d11Stb 			BIO_printf(bp, "%lX%08lX", h, l);
483b8d22d11Stb 		else
484b8d22d11Stb 			BIO_printf(bp, "%lX", l);
485b8d22d11Stb 		return;
486b8d22d11Stb 	}
487b8d22d11Stb #endif
488b8d22d11Stb 	BIO_printf(bp, BN_HEX_FMT1, w);
489b8d22d11Stb }
490b8d22d11Stb 
491b8d22d11Stb int
test_div_word(BIO * bp,BN_CTX * ctx)4920edabd22Stb test_div_word(BIO *bp, BN_CTX *ctx)
493b8d22d11Stb {
4940edabd22Stb 	BIGNUM *a, *b;
495b8d22d11Stb 	BN_ULONG r, rmod, s = 0;
496b8d22d11Stb 	int i;
497f7264475Stb 	int ret = 0;
498b8d22d11Stb 
4990edabd22Stb 	BN_CTX_start(ctx);
5000edabd22Stb 
5010edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
502b8d22d11Stb 		goto err;
5030edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
504b8d22d11Stb 		goto err;
505b8d22d11Stb 
506b8d22d11Stb 	for (i = 0; i < num0; i++) {
507b8d22d11Stb 		do {
508b8d22d11Stb 			if (!BN_bntest_rand(a, 512, -1, 0) ||
509457e5092Stb 			    !BN_bntest_rand(b, BN_BITS2, -1, 0))
5102e7cce5eStb 				goto err;
511b8d22d11Stb 			s = BN_get_word(b);
512b8d22d11Stb 		} while (!s);
513b8d22d11Stb 
514457e5092Stb 		if (!bn_copy(b, a))
5152e7cce5eStb 			goto err;
516b8d22d11Stb 
517b8d22d11Stb 		rmod = BN_mod_word(b, s);
518b8d22d11Stb 		r = BN_div_word(b, s);
519b8d22d11Stb 
520457e5092Stb 		if (r == (BN_ULONG)-1 || rmod == (BN_ULONG)-1)
5212e7cce5eStb 			goto err;
522b8d22d11Stb 
523b8d22d11Stb 		if (rmod != r) {
524b8d22d11Stb 			fprintf(stderr, "Mod (word) test failed!\n");
5252e7cce5eStb 			goto err;
526b8d22d11Stb 		}
527b8d22d11Stb 
528b8d22d11Stb 		if (bp != NULL) {
529b8d22d11Stb 			if (!results) {
530b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
531b8d22d11Stb 				BIO_puts(bp, " / ");
532b8d22d11Stb 				print_word(bp, s);
533b8d22d11Stb 				BIO_puts(bp, " - ");
534b8d22d11Stb 			}
535b8d22d11Stb 			CHECK_GOTO(BN_print(bp, b));
536b8d22d11Stb 			BIO_puts(bp, "\n");
537b8d22d11Stb 
538b8d22d11Stb 			if (!results) {
539b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
540b8d22d11Stb 				BIO_puts(bp, " % ");
541b8d22d11Stb 				print_word(bp, s);
542b8d22d11Stb 				BIO_puts(bp, " - ");
543b8d22d11Stb 			}
544b8d22d11Stb 			print_word(bp, r);
545b8d22d11Stb 			BIO_puts(bp, "\n");
546b8d22d11Stb 		}
547b8d22d11Stb 		CHECK_GOTO(BN_mul_word(b, s));
548b8d22d11Stb 		CHECK_GOTO(BN_add_word(b, r));
549b8d22d11Stb 		CHECK_GOTO(BN_sub(b, a, b));
550b8d22d11Stb 		if (!BN_is_zero(b)) {
551b8d22d11Stb 			fprintf(stderr, "Division (word) test failed!\n");
5522e7cce5eStb 			goto err;
553b8d22d11Stb 		}
554b8d22d11Stb 	}
5552e7cce5eStb 
556f7264475Stb 	ret = 1;
557b8d22d11Stb  err:
5580edabd22Stb 	BN_CTX_end(ctx);
559b8d22d11Stb 
560f7264475Stb 	return ret;
561b8d22d11Stb }
562b8d22d11Stb 
563b8d22d11Stb int
test_div_recp(BIO * bp,BN_CTX * ctx)564b8d22d11Stb test_div_recp(BIO *bp, BN_CTX *ctx)
565b8d22d11Stb {
566b8d22d11Stb 	BN_RECP_CTX *recp = NULL;
5670edabd22Stb 	BIGNUM *a, *b, *c, *d, *e;
568b8d22d11Stb 	int i;
569f7264475Stb 	int ret = 0;
570b8d22d11Stb 
5710edabd22Stb 	BN_CTX_start(ctx);
5720edabd22Stb 
5730edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
574b8d22d11Stb 		goto err;
5750edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
576b8d22d11Stb 		goto err;
5770edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
578b8d22d11Stb 		goto err;
5790edabd22Stb 	if ((d = BN_CTX_get(ctx)) == NULL)
580b8d22d11Stb 		goto err;
5810edabd22Stb 	if ((e = BN_CTX_get(ctx)) == NULL)
582b8d22d11Stb 		goto err;
583b8d22d11Stb 
584b8d22d11Stb 	if ((recp = BN_RECP_CTX_new()) == NULL)
585b8d22d11Stb 		goto err;
586b8d22d11Stb 
587b8d22d11Stb 	for (i = 0; i < num0 + num1; i++) {
588b8d22d11Stb 		if (i < num1) {
589b8d22d11Stb 			CHECK_GOTO(BN_bntest_rand(a, 400, 0, 0));
5908e84e241Stb 			CHECK_GOTO(bn_copy(b, a));
591b8d22d11Stb 			CHECK_GOTO(BN_lshift(a, a, i));
592b8d22d11Stb 			CHECK_GOTO(BN_add_word(a, i));
593b8d22d11Stb 		} else
594b8d22d11Stb 			CHECK_GOTO(BN_bntest_rand(b, 50 + 3 * (i - num1), 0, 0));
595b8d22d11Stb 		BN_set_negative(a, rand_neg());
596b8d22d11Stb 		BN_set_negative(b, rand_neg());
597b8d22d11Stb 		CHECK_GOTO(BN_RECP_CTX_set(recp, b, ctx));
598b8d22d11Stb 		CHECK_GOTO(BN_div_recp(d, c, a, recp, ctx));
599b8d22d11Stb 		if (bp != NULL) {
600b8d22d11Stb 			if (!results) {
601b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
602b8d22d11Stb 				BIO_puts(bp, " / ");
603b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
604b8d22d11Stb 				BIO_puts(bp, " - ");
605b8d22d11Stb 			}
606b8d22d11Stb 			CHECK_GOTO(BN_print(bp, d));
607b8d22d11Stb 			BIO_puts(bp, "\n");
608b8d22d11Stb 
609b8d22d11Stb 			if (!results) {
610b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
611b8d22d11Stb 				BIO_puts(bp, " % ");
612b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
613b8d22d11Stb 				BIO_puts(bp, " - ");
614b8d22d11Stb 			}
615b8d22d11Stb 			CHECK_GOTO(BN_print(bp, c));
616b8d22d11Stb 			BIO_puts(bp, "\n");
617b8d22d11Stb 		}
618b8d22d11Stb 		CHECK_GOTO(BN_mul(e, d, b, ctx));
619b8d22d11Stb 		CHECK_GOTO(BN_add(d, e, c));
620b8d22d11Stb 		CHECK_GOTO(BN_sub(d, d, a));
621b8d22d11Stb 		if (!BN_is_zero(d)) {
622b8d22d11Stb 			fprintf(stderr, "Reciprocal division test failed!\n");
623b8d22d11Stb 			fprintf(stderr, "a=");
624b8d22d11Stb 			CHECK_GOTO(BN_print_fp(stderr, a));
625b8d22d11Stb 			fprintf(stderr, "\nb=");
626b8d22d11Stb 			CHECK_GOTO(BN_print_fp(stderr, b));
627b8d22d11Stb 			fprintf(stderr, "\n");
6282e7cce5eStb 			goto err;
629b8d22d11Stb 		}
630b8d22d11Stb 	}
6312e7cce5eStb 
632f7264475Stb 	ret = 1;
633b8d22d11Stb  err:
6340edabd22Stb 	BN_CTX_end(ctx);
635b8d22d11Stb 	BN_RECP_CTX_free(recp);
6362e7cce5eStb 
637f7264475Stb 	return ret;
638b8d22d11Stb }
639b8d22d11Stb 
640b8d22d11Stb int
test_mul(BIO * bp,BN_CTX * ctx)6410edabd22Stb test_mul(BIO *bp, BN_CTX *ctx)
642b8d22d11Stb {
6430edabd22Stb 	BIGNUM *a, *b, *c, *d, *e;
644b8d22d11Stb 	int i;
645f7264475Stb 	int ret = 0;
646b8d22d11Stb 
6470edabd22Stb 	BN_CTX_start(ctx);
648b8d22d11Stb 
6490edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
650b8d22d11Stb 		goto err;
6510edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
652b8d22d11Stb 		goto err;
6530edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
654b8d22d11Stb 		goto err;
6550edabd22Stb 	if ((d = BN_CTX_get(ctx)) == NULL)
656b8d22d11Stb 		goto err;
6570edabd22Stb 	if ((e = BN_CTX_get(ctx)) == NULL)
658b8d22d11Stb 		goto err;
659b8d22d11Stb 
660b8d22d11Stb 	for (i = 0; i < num0 + num1; i++) {
661b8d22d11Stb 		if (i <= num1) {
662b8d22d11Stb 			CHECK_GOTO(BN_bntest_rand(a, 100, 0, 0));
663b8d22d11Stb 			CHECK_GOTO(BN_bntest_rand(b, 100, 0, 0));
664b8d22d11Stb 		} else
665b8d22d11Stb 			CHECK_GOTO(BN_bntest_rand(b, i - num1, 0, 0));
666b8d22d11Stb 		BN_set_negative(a, rand_neg());
667b8d22d11Stb 		BN_set_negative(b, rand_neg());
668b8d22d11Stb 		CHECK_GOTO(BN_mul(c, a, b, ctx));
669b8d22d11Stb 		if (bp != NULL) {
670b8d22d11Stb 			if (!results) {
671b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
672b8d22d11Stb 				BIO_puts(bp, " * ");
673b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
674b8d22d11Stb 				BIO_puts(bp, " - ");
675b8d22d11Stb 			}
676b8d22d11Stb 			CHECK_GOTO(BN_print(bp, c));
677b8d22d11Stb 			BIO_puts(bp, "\n");
678b8d22d11Stb 		}
679b8d22d11Stb 		CHECK_GOTO(BN_div(d, e, c, a, ctx));
680b8d22d11Stb 		CHECK_GOTO(BN_sub(d, d, b));
681b8d22d11Stb 		if (!BN_is_zero(d) || !BN_is_zero(e)) {
682b8d22d11Stb 			fprintf(stderr, "Multiplication test failed!\n");
6832e7cce5eStb 			goto err;
684b8d22d11Stb 		}
685b8d22d11Stb 	}
6862e7cce5eStb 
687f7264475Stb 	ret = 1;
688b8d22d11Stb  err:
6890edabd22Stb 	BN_CTX_end(ctx);
6902e7cce5eStb 
691f7264475Stb 	return ret;
692b8d22d11Stb }
693b8d22d11Stb 
694b8d22d11Stb int
test_sqr(BIO * bp,BN_CTX * ctx)695b8d22d11Stb test_sqr(BIO *bp, BN_CTX *ctx)
696b8d22d11Stb {
6970edabd22Stb 	BIGNUM *a, *c, *d, *e;
698568ce9ecStb 	int i;
699f7264475Stb 	int ret = 0;
700b8d22d11Stb 
7010edabd22Stb 	BN_CTX_start(ctx);
7020edabd22Stb 
7030edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
704b8d22d11Stb 		goto err;
7050edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
706b8d22d11Stb 		goto err;
7070edabd22Stb 	if ((d = BN_CTX_get(ctx)) == NULL)
708b8d22d11Stb 		goto err;
7090edabd22Stb 	if ((e = BN_CTX_get(ctx)) == NULL)
710b8d22d11Stb 		goto err;
711b8d22d11Stb 
712b8d22d11Stb 	for (i = 0; i < num0; i++) {
713b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(a, 40 + i * 10, 0, 0));
714b8d22d11Stb 		BN_set_negative(a, rand_neg());
715b8d22d11Stb 		CHECK_GOTO(BN_sqr(c, a, ctx));
716b8d22d11Stb 		if (bp != NULL) {
717b8d22d11Stb 			if (!results) {
718b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
719b8d22d11Stb 				BIO_puts(bp, " * ");
720b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
721b8d22d11Stb 				BIO_puts(bp, " - ");
722b8d22d11Stb 			}
723b8d22d11Stb 			CHECK_GOTO(BN_print(bp, c));
724b8d22d11Stb 			BIO_puts(bp, "\n");
725b8d22d11Stb 		}
726b8d22d11Stb 		CHECK_GOTO(BN_div(d, e, c, a, ctx));
727b8d22d11Stb 		CHECK_GOTO(BN_sub(d, d, a));
728b8d22d11Stb 		if (!BN_is_zero(d) || !BN_is_zero(e)) {
729b8d22d11Stb 			fprintf(stderr, "Square test failed!\n");
730b8d22d11Stb 			goto err;
731b8d22d11Stb 		}
732b8d22d11Stb 	}
733b8d22d11Stb 
734b8d22d11Stb 	/* Regression test for a BN_sqr overflow bug. */
735b8d22d11Stb 	if (!BN_hex2bn(&a, "80000000000000008000000000000001"
736b8d22d11Stb 	    "FFFFFFFFFFFFFFFE0000000000000000")) {
737b8d22d11Stb 		fprintf(stderr, "BN_hex2bn failed\n");
738b8d22d11Stb 		goto err;
739b8d22d11Stb 	}
740b8d22d11Stb 	CHECK_GOTO(BN_sqr(c, a, ctx));
741b8d22d11Stb 	if (bp != NULL) {
742b8d22d11Stb 		if (!results) {
743b8d22d11Stb 			CHECK_GOTO(BN_print(bp, a));
744b8d22d11Stb 			BIO_puts(bp, " * ");
745b8d22d11Stb 			CHECK_GOTO(BN_print(bp, a));
746b8d22d11Stb 			BIO_puts(bp, " - ");
747b8d22d11Stb 		}
748b8d22d11Stb 		CHECK_GOTO(BN_print(bp, c));
749b8d22d11Stb 		BIO_puts(bp, "\n");
750b8d22d11Stb 	}
751b8d22d11Stb 	CHECK_GOTO(BN_mul(d, a, a, ctx));
752b8d22d11Stb 	if (BN_cmp(c, d)) {
753b8d22d11Stb 		fprintf(stderr,
754b8d22d11Stb 		    "Square test failed: BN_sqr and BN_mul produce "
755b8d22d11Stb 		    "different results!\n");
756b8d22d11Stb 		goto err;
757b8d22d11Stb 	}
758b8d22d11Stb 
759b8d22d11Stb 	/* Regression test for a BN_sqr overflow bug. */
760b8d22d11Stb 	if (!BN_hex2bn(&a, "80000000000000000000000080000001"
761b8d22d11Stb 	    "FFFFFFFE000000000000000000000000")) {
762b8d22d11Stb 		fprintf(stderr, "BN_hex2bn failed\n");
763b8d22d11Stb 		goto err;
764b8d22d11Stb 	}
765b8d22d11Stb 	CHECK_GOTO(BN_sqr(c, a, ctx));
766b8d22d11Stb 	if (bp != NULL) {
767b8d22d11Stb 		if (!results) {
768b8d22d11Stb 			CHECK_GOTO(BN_print(bp, a));
769b8d22d11Stb 			BIO_puts(bp, " * ");
770b8d22d11Stb 			CHECK_GOTO(BN_print(bp, a));
771b8d22d11Stb 			BIO_puts(bp, " - ");
772b8d22d11Stb 		}
773b8d22d11Stb 		CHECK_GOTO(BN_print(bp, c));
774b8d22d11Stb 		BIO_puts(bp, "\n");
775b8d22d11Stb 	}
776b8d22d11Stb 	CHECK_GOTO(BN_mul(d, a, a, ctx));
777b8d22d11Stb 	if (BN_cmp(c, d)) {
778b8d22d11Stb 		fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
779b8d22d11Stb 				"different results!\n");
780b8d22d11Stb 		goto err;
781b8d22d11Stb 	}
7822e7cce5eStb 
783f7264475Stb 	ret = 1;
784b8d22d11Stb  err:
7850edabd22Stb 	BN_CTX_end(ctx);
7862e7cce5eStb 
787f7264475Stb 	return ret;
788b8d22d11Stb }
789b8d22d11Stb 
790b8d22d11Stb int
test_mont(BIO * bp,BN_CTX * ctx)791b8d22d11Stb test_mont(BIO *bp, BN_CTX *ctx)
792b8d22d11Stb {
7930edabd22Stb 	BN_MONT_CTX *mont = NULL;
7940edabd22Stb 	BIGNUM *a, *b, *c, *d, *A, *B, *n;
795b8d22d11Stb 	int i;
796f7264475Stb 	int ret = 0;
797b8d22d11Stb 
7980edabd22Stb 	BN_CTX_start(ctx);
799b8d22d11Stb 
8000edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
801b8d22d11Stb 		goto err;
8020edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
803b8d22d11Stb 		goto err;
8040edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
805b8d22d11Stb 		goto err;
8060edabd22Stb 	if ((d = BN_CTX_get(ctx)) == NULL)
807b8d22d11Stb 		goto err;
8080edabd22Stb 	if ((A = BN_CTX_get(ctx)) == NULL)
809b8d22d11Stb 		goto err;
8100edabd22Stb 	if ((B = BN_CTX_get(ctx)) == NULL)
811b8d22d11Stb 		goto err;
8120edabd22Stb 	if ((n = BN_CTX_get(ctx)) == NULL)
8130edabd22Stb 		goto err;
8140edabd22Stb 
8150edabd22Stb 	if ((mont = BN_MONT_CTX_new()) == NULL)
816b8d22d11Stb 		goto err;
817b8d22d11Stb 
81830ad135cStb 	BN_zero(n);
819b8d22d11Stb 	if (BN_MONT_CTX_set(mont, n, ctx)) {
820b8d22d11Stb 		fprintf(stderr, "BN_MONT_CTX_set succeeded for zero modulus!\n");
821bb44b87cStb 		goto err;
822b8d22d11Stb 	}
8235550240dStb 	ERR_clear_error();
824b8d22d11Stb 
825b8d22d11Stb 	CHECK_GOTO(BN_set_word(n, 16));
826b8d22d11Stb 	if (BN_MONT_CTX_set(mont, n, ctx)) {
827b8d22d11Stb 		fprintf(stderr, "BN_MONT_CTX_set succeeded for even modulus!\n");
828bb44b87cStb 		goto err;
829b8d22d11Stb 	}
8305550240dStb 	ERR_clear_error();
831b8d22d11Stb 
832b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(a, 100, 0, 0));
833b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(b, 100, 0, 0));
834b8d22d11Stb 	for (i = 0; i < num2; i++) {
835b8d22d11Stb 		int bits = (200 * (i + 1)) / num2;
836b8d22d11Stb 
837b8d22d11Stb 		if (bits == 0)
838b8d22d11Stb 			continue;
839b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(n, bits, 0, 1));
840b8d22d11Stb 		CHECK_GOTO(BN_MONT_CTX_set(mont, n, ctx));
841b8d22d11Stb 
842b8d22d11Stb 		CHECK_GOTO(BN_nnmod(a, a, n, ctx));
843b8d22d11Stb 		CHECK_GOTO(BN_nnmod(b, b, n, ctx));
844b8d22d11Stb 
845b8d22d11Stb 		CHECK_GOTO(BN_to_montgomery(A, a, mont, ctx));
846b8d22d11Stb 		CHECK_GOTO(BN_to_montgomery(B, b, mont, ctx));
847b8d22d11Stb 
848b8d22d11Stb 		CHECK_GOTO(BN_mod_mul_montgomery(c, A, B, mont, ctx));
849b8d22d11Stb 		CHECK_GOTO(BN_from_montgomery(A, c, mont, ctx));
850b8d22d11Stb 		if (bp != NULL) {
851b8d22d11Stb 			if (!results) {
852b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
853b8d22d11Stb 				BIO_puts(bp, " * ");
854b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
855b8d22d11Stb 				BIO_puts(bp, " % ");
856b8d22d11Stb 				/* n == &mont->N */
857b8d22d11Stb 				CHECK_GOTO(BN_print(bp, n));
858b8d22d11Stb 				BIO_puts(bp, " - ");
859b8d22d11Stb 			}
860b8d22d11Stb 			CHECK_GOTO(BN_print(bp, A));
861b8d22d11Stb 			BIO_puts(bp, "\n");
862b8d22d11Stb 		}
863b8d22d11Stb 		CHECK_GOTO(BN_mod_mul(d, a, b, n, ctx));
864b8d22d11Stb 		CHECK_GOTO(BN_sub(d, d, A));
865b8d22d11Stb 		if (!BN_is_zero(d)) {
866b8d22d11Stb 			fprintf(stderr, "Montgomery multiplication test failed!\n");
8672e7cce5eStb 			goto err;
868b8d22d11Stb 		}
869b8d22d11Stb 	}
8702e7cce5eStb 
871f7264475Stb 	ret = 1;
872b8d22d11Stb  err:
8730edabd22Stb 	BN_CTX_end(ctx);
874b8d22d11Stb 	BN_MONT_CTX_free(mont);
8752e7cce5eStb 
876f7264475Stb 	return ret;
877b8d22d11Stb }
878b8d22d11Stb 
879b8d22d11Stb int
test_mod(BIO * bp,BN_CTX * ctx)880b8d22d11Stb test_mod(BIO *bp, BN_CTX *ctx)
881b8d22d11Stb {
8820edabd22Stb 	BIGNUM *a, *b, *c, *d, *e;
883b8d22d11Stb 	int i;
884f7264475Stb 	int ret = 0;
885b8d22d11Stb 
8860edabd22Stb 	BN_CTX_start(ctx);
8870edabd22Stb 
8880edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
889b8d22d11Stb 		goto err;
8900edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
891b8d22d11Stb 		goto err;
8920edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
893b8d22d11Stb 		goto err;
8940edabd22Stb 	if ((d = BN_CTX_get(ctx)) == NULL)
895b8d22d11Stb 		goto err;
8960edabd22Stb 	if ((e = BN_CTX_get(ctx)) == NULL)
897b8d22d11Stb 		goto err;
898b8d22d11Stb 
899b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0));
900b8d22d11Stb 	for (i = 0; i < num0; i++) {
901b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(b, 450 + i * 10, 0, 0));
902b8d22d11Stb 		BN_set_negative(a, rand_neg());
903b8d22d11Stb 		BN_set_negative(b, rand_neg());
904b8d22d11Stb 		CHECK_GOTO(BN_mod(c, a, b, ctx));
905b8d22d11Stb 		if (bp != NULL) {
906b8d22d11Stb 			if (!results) {
907b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
908b8d22d11Stb 				BIO_puts(bp, " % ");
909b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
910b8d22d11Stb 				BIO_puts(bp, " - ");
911b8d22d11Stb 			}
912b8d22d11Stb 			CHECK_GOTO(BN_print(bp, c));
913b8d22d11Stb 			BIO_puts(bp, "\n");
914b8d22d11Stb 		}
915b8d22d11Stb 		CHECK_GOTO(BN_div(d, e, a, b, ctx));
916b8d22d11Stb 		CHECK_GOTO(BN_sub(e, e, c));
917b8d22d11Stb 		if (!BN_is_zero(e)) {
918b8d22d11Stb 			fprintf(stderr, "Modulo test failed!\n");
9192e7cce5eStb 			goto err;
920b8d22d11Stb 		}
921b8d22d11Stb 	}
9222e7cce5eStb 
923f7264475Stb 	ret = 1;
924b8d22d11Stb  err:
9250edabd22Stb 	BN_CTX_end(ctx);
9262e7cce5eStb 
927f7264475Stb 	return ret;
928b8d22d11Stb }
929b8d22d11Stb 
930b8d22d11Stb int
test_mod_mul(BIO * bp,BN_CTX * ctx)931b8d22d11Stb test_mod_mul(BIO *bp, BN_CTX *ctx)
932b8d22d11Stb {
9330edabd22Stb 	BIGNUM *a, *b, *c, *d, *e;
934b8d22d11Stb 	int i, j;
935f7264475Stb 	int ret = 0;
936b8d22d11Stb 
9370edabd22Stb 	BN_CTX_start(ctx);
9380edabd22Stb 
9390edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
940b8d22d11Stb 		goto err;
9410edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
942b8d22d11Stb 		goto err;
9430edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
944b8d22d11Stb 		goto err;
9450edabd22Stb 	if ((d = BN_CTX_get(ctx)) == NULL)
946b8d22d11Stb 		goto err;
9470edabd22Stb 	if ((e = BN_CTX_get(ctx)) == NULL)
948b8d22d11Stb 		goto err;
949b8d22d11Stb 
950b8d22d11Stb 	CHECK_GOTO(BN_one(a));
951b8d22d11Stb 	CHECK_GOTO(BN_one(b));
95230ad135cStb 	BN_zero(c);
953b8d22d11Stb 	if (BN_mod_mul(e, a, b, c, ctx)) {
954b8d22d11Stb 		fprintf(stderr, "BN_mod_mul with zero modulus succeeded!\n");
955bb44b87cStb 		goto err;
956b8d22d11Stb 	}
9575550240dStb 	ERR_clear_error();
958b8d22d11Stb 
959b8d22d11Stb 	for (j = 0; j < 3; j++) {
960b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(c, 1024, 0, 0));
961b8d22d11Stb 		for (i = 0; i < num0; i++) {
962b8d22d11Stb 			CHECK_GOTO(BN_bntest_rand(a, 475 + i * 10, 0, 0));
963b8d22d11Stb 			CHECK_GOTO(BN_bntest_rand(b, 425 + i * 11, 0, 0));
964b8d22d11Stb 			BN_set_negative(a, rand_neg());
965b8d22d11Stb 			BN_set_negative(b, rand_neg());
966b8d22d11Stb 			if (!BN_mod_mul(e, a, b, c, ctx)) {
967b8d22d11Stb 				unsigned long l;
968b8d22d11Stb 
969b8d22d11Stb 				while ((l = ERR_get_error()))
970b8d22d11Stb 					fprintf(stderr, "ERROR:%s\n",
971b8d22d11Stb 					    ERR_error_string(l, NULL));
972b8d22d11Stb 				exit(1);
973b8d22d11Stb 			}
974b8d22d11Stb 			if (bp != NULL) {
975b8d22d11Stb 				if (!results) {
976b8d22d11Stb 					CHECK_GOTO(BN_print(bp, a));
977b8d22d11Stb 					BIO_puts(bp, " * ");
978b8d22d11Stb 					CHECK_GOTO(BN_print(bp, b));
979b8d22d11Stb 					BIO_puts(bp, " % ");
980b8d22d11Stb 					CHECK_GOTO(BN_print(bp, c));
981b8d22d11Stb 					if ((BN_is_negative(a) ^ BN_is_negative(b)) &&
982b8d22d11Stb 					    !BN_is_zero(e)) {
983b8d22d11Stb 						/* If  (a*b) % c  is negative,  c  must be added
984b8d22d11Stb 						 * in order to obtain the normalized remainder
985b8d22d11Stb 						 * (new with OpenSSL 0.9.7, previous versions of
986b8d22d11Stb 						 * BN_mod_mul could generate negative results)
987b8d22d11Stb 						 */
988b8d22d11Stb 						BIO_puts(bp, " + ");
989b8d22d11Stb 						CHECK_GOTO(BN_print(bp, c));
990b8d22d11Stb 					}
991b8d22d11Stb 					BIO_puts(bp, " - ");
992b8d22d11Stb 				}
993b8d22d11Stb 				CHECK_GOTO(BN_print(bp, e));
994b8d22d11Stb 				BIO_puts(bp, "\n");
995b8d22d11Stb 			}
996b8d22d11Stb 			CHECK_GOTO(BN_mul(d, a, b, ctx));
997b8d22d11Stb 			CHECK_GOTO(BN_sub(d, d, e));
998b8d22d11Stb 			CHECK_GOTO(BN_div(a, b, d, c, ctx));
999b8d22d11Stb 			if (!BN_is_zero(b)) {
1000b8d22d11Stb 				fprintf(stderr, "Modulo multiply test failed!\n");
1001b8d22d11Stb 				ERR_print_errors_fp(stderr);
1002b8d22d11Stb 				goto err;
1003b8d22d11Stb 			}
1004b8d22d11Stb 		}
1005b8d22d11Stb 	}
10062e7cce5eStb 
1007f7264475Stb 	ret = 1;
1008b8d22d11Stb  err:
10090edabd22Stb 	BN_CTX_end(ctx);
10102e7cce5eStb 
1011f7264475Stb 	return ret;
1012b8d22d11Stb }
1013b8d22d11Stb 
1014b8d22d11Stb int
test_mod_exp(BIO * bp,BN_CTX * ctx)1015b8d22d11Stb test_mod_exp(BIO *bp, BN_CTX *ctx)
1016b8d22d11Stb {
10170edabd22Stb 	BIGNUM *a, *b, *c, *d, *e;
1018b8d22d11Stb 	int i;
1019f7264475Stb 	int ret = 0;
1020b8d22d11Stb 
10210edabd22Stb 	BN_CTX_start(ctx);
10220edabd22Stb 
10230edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
1024b8d22d11Stb 		goto err;
10250edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
1026b8d22d11Stb 		goto err;
10270edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
1028b8d22d11Stb 		goto err;
10290edabd22Stb 	if ((d = BN_CTX_get(ctx)) == NULL)
1030b8d22d11Stb 		goto err;
10310edabd22Stb 	if ((e = BN_CTX_get(ctx)) == NULL)
1032b8d22d11Stb 		goto err;
1033b8d22d11Stb 
1034b8d22d11Stb 	CHECK_GOTO(BN_one(a));
1035b8d22d11Stb 	CHECK_GOTO(BN_one(b));
103630ad135cStb 	BN_zero(c);
1037b8d22d11Stb 	if (BN_mod_exp(d, a, b, c, ctx)) {
1038b8d22d11Stb 		fprintf(stderr, "BN_mod_exp with zero modulus succeeded!\n");
1039b8d22d11Stb 		goto err;
1040b8d22d11Stb 	}
10415550240dStb 	ERR_clear_error();
1042b8d22d11Stb 	if (BN_mod_exp_ct(d, a, b, c, ctx)) {
1043b8d22d11Stb 		fprintf(stderr, "BN_mod_exp_ct with zero modulus succeeded!\n");
1044b8d22d11Stb 		goto err;
1045b8d22d11Stb 	}
10465550240dStb 	ERR_clear_error();
1047b8d22d11Stb 	if (BN_mod_exp_nonct(d, a, b, c, ctx)) {
1048b8d22d11Stb 		fprintf(stderr, "BN_mod_exp_nonct with zero modulus succeeded!\n");
1049b8d22d11Stb 		goto err;
1050b8d22d11Stb 	}
10515550240dStb 	ERR_clear_error();
1052b8d22d11Stb 
1053b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */
1054b8d22d11Stb 	for (i = 0; i < num2; i++) {
1055b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
1056b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
1057b8d22d11Stb 
1058457e5092Stb 		if (!BN_mod_exp(d, a, b, c, ctx))
10592e7cce5eStb 			goto err;
1060b8d22d11Stb 
1061b8d22d11Stb 		if (bp != NULL) {
1062b8d22d11Stb 			if (!results) {
1063b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
1064b8d22d11Stb 				BIO_puts(bp, " ^ ");
1065b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
1066b8d22d11Stb 				BIO_puts(bp, " % ");
1067b8d22d11Stb 				CHECK_GOTO(BN_print(bp, c));
1068b8d22d11Stb 				BIO_puts(bp, " - ");
1069b8d22d11Stb 			}
1070b8d22d11Stb 			CHECK_GOTO(BN_print(bp, d));
1071b8d22d11Stb 			BIO_puts(bp, "\n");
1072b8d22d11Stb 		}
1073b8d22d11Stb 		CHECK_GOTO(BN_exp(e, a, b, ctx));
1074b8d22d11Stb 		CHECK_GOTO(BN_sub(e, e, d));
1075b8d22d11Stb 		CHECK_GOTO(BN_div(a, b, e, c, ctx));
1076b8d22d11Stb 		if (!BN_is_zero(b)) {
1077b8d22d11Stb 			fprintf(stderr, "Modulo exponentiation test failed!\n");
10782e7cce5eStb 			goto err;
1079b8d22d11Stb 		}
1080b8d22d11Stb 	}
1081b8d22d11Stb 
1082b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */
1083b8d22d11Stb 	for (i = 0; i < num2; i++) {
1084b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
1085b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
1086b8d22d11Stb 
1087457e5092Stb 		if (!BN_mod_exp_ct(d, a, b, c, ctx))
10882e7cce5eStb 			goto err;
1089b8d22d11Stb 
1090b8d22d11Stb 		if (bp != NULL) {
1091b8d22d11Stb 			if (!results) {
1092b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
1093b8d22d11Stb 				BIO_puts(bp, " ^ ");
1094b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
1095b8d22d11Stb 				BIO_puts(bp, " % ");
1096b8d22d11Stb 				CHECK_GOTO(BN_print(bp, c));
1097b8d22d11Stb 				BIO_puts(bp, " - ");
1098b8d22d11Stb 			}
1099b8d22d11Stb 			CHECK_GOTO(BN_print(bp, d));
1100b8d22d11Stb 			BIO_puts(bp, "\n");
1101b8d22d11Stb 		}
1102b8d22d11Stb 		CHECK_GOTO(BN_exp(e, a, b, ctx));
1103b8d22d11Stb 		CHECK_GOTO(BN_sub(e, e, d));
1104b8d22d11Stb 		CHECK_GOTO(BN_div(a, b, e, c, ctx));
1105b8d22d11Stb 		if (!BN_is_zero(b)) {
1106b8d22d11Stb 			fprintf(stderr, "Modulo exponentiation test failed!\n");
11072e7cce5eStb 			goto err;
1108b8d22d11Stb 		}
1109b8d22d11Stb 	}
1110b8d22d11Stb 
1111b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */
1112b8d22d11Stb 	for (i = 0; i < num2; i++) {
1113b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
1114b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
1115b8d22d11Stb 
1116457e5092Stb 		if (!BN_mod_exp_nonct(d, a, b, c, ctx))
11172e7cce5eStb 			goto err;
1118b8d22d11Stb 
1119b8d22d11Stb 		if (bp != NULL) {
1120b8d22d11Stb 			if (!results) {
1121b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
1122b8d22d11Stb 				BIO_puts(bp, " ^ ");
1123b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
1124b8d22d11Stb 				BIO_puts(bp, " % ");
1125b8d22d11Stb 				CHECK_GOTO(BN_print(bp, c));
1126b8d22d11Stb 				BIO_puts(bp, " - ");
1127b8d22d11Stb 			}
1128b8d22d11Stb 			CHECK_GOTO(BN_print(bp, d));
1129b8d22d11Stb 			BIO_puts(bp, "\n");
1130b8d22d11Stb 		}
1131b8d22d11Stb 		CHECK_GOTO(BN_exp(e, a, b, ctx));
1132b8d22d11Stb 		CHECK_GOTO(BN_sub(e, e, d));
1133b8d22d11Stb 		CHECK_GOTO(BN_div(a, b, e, c, ctx));
1134b8d22d11Stb 		if (!BN_is_zero(b)) {
1135b8d22d11Stb 			fprintf(stderr, "Modulo exponentiation test failed!\n");
11362e7cce5eStb 			goto err;
1137b8d22d11Stb 		}
1138b8d22d11Stb 	}
11392e7cce5eStb 
1140f7264475Stb 	ret = 1;
1141b8d22d11Stb  err:
11420edabd22Stb 	BN_CTX_end(ctx);
11432e7cce5eStb 
1144f7264475Stb 	return ret;
1145b8d22d11Stb }
1146b8d22d11Stb 
1147b8d22d11Stb int
test_mod_exp_mont_consttime(BIO * bp,BN_CTX * ctx)1148b8d22d11Stb test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
1149b8d22d11Stb {
11500edabd22Stb 	BIGNUM *a, *b, *c, *d, *e;
1151b8d22d11Stb 	int i;
1152f7264475Stb 	int ret = 0;
1153b8d22d11Stb 
11540edabd22Stb 	BN_CTX_start(ctx);
11550edabd22Stb 
11560edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
1157b8d22d11Stb 		goto err;
11580edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
1159b8d22d11Stb 		goto err;
11600edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
1161b8d22d11Stb 		goto err;
11620edabd22Stb 	if ((d = BN_CTX_get(ctx)) == NULL)
1163b8d22d11Stb 		goto err;
11640edabd22Stb 	if ((e = BN_CTX_get(ctx)) == NULL)
1165b8d22d11Stb 		goto err;
1166b8d22d11Stb 
1167b8d22d11Stb 	CHECK_GOTO(BN_one(a));
1168b8d22d11Stb 	CHECK_GOTO(BN_one(b));
116930ad135cStb 	BN_zero(c);
1170b8d22d11Stb 	if (BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) {
1171b8d22d11Stb 		fprintf(stderr, "BN_mod_exp_mont_consttime with zero modulus "
1172b8d22d11Stb 				"succeeded\n");
1173b8d22d11Stb 		goto err;
1174b8d22d11Stb 	}
11755550240dStb 	ERR_clear_error();
1176b8d22d11Stb 
1177b8d22d11Stb 	CHECK_GOTO(BN_set_word(c, 16));
1178b8d22d11Stb 	if (BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) {
1179b8d22d11Stb 		fprintf(stderr, "BN_mod_exp_mont_consttime with even modulus "
1180b8d22d11Stb 				"succeeded\n");
1181b8d22d11Stb 		goto err;
1182b8d22d11Stb 	}
11835550240dStb 	ERR_clear_error();
1184b8d22d11Stb 
1185b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(c, 30, 0, 1)); /* must be odd for montgomery */
1186b8d22d11Stb 	for (i = 0; i < num2; i++) {
1187b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
1188b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
1189b8d22d11Stb 
1190457e5092Stb 		if (!BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL))
11912e7cce5eStb 			goto err;
1192b8d22d11Stb 
1193b8d22d11Stb 		if (bp != NULL) {
1194b8d22d11Stb 			if (!results) {
1195b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
1196b8d22d11Stb 				BIO_puts(bp, " ^ ");
1197b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
1198b8d22d11Stb 				BIO_puts(bp, " % ");
1199b8d22d11Stb 				CHECK_GOTO(BN_print(bp, c));
1200b8d22d11Stb 				BIO_puts(bp, " - ");
1201b8d22d11Stb 			}
1202b8d22d11Stb 			CHECK_GOTO(BN_print(bp, d));
1203b8d22d11Stb 			BIO_puts(bp, "\n");
1204b8d22d11Stb 		}
1205b8d22d11Stb 		CHECK_GOTO(BN_exp(e, a, b, ctx));
1206b8d22d11Stb 		CHECK_GOTO(BN_sub(e, e, d));
1207b8d22d11Stb 		CHECK_GOTO(BN_div(a, b, e, c, ctx));
1208b8d22d11Stb 		if (!BN_is_zero(b)) {
1209b8d22d11Stb 			fprintf(stderr, "Modulo exponentiation test failed!\n");
12102e7cce5eStb 			goto err;
1211b8d22d11Stb 		}
1212b8d22d11Stb 	}
12132e7cce5eStb 
1214f7264475Stb 	ret = 1;
1215b8d22d11Stb  err:
12160edabd22Stb 	BN_CTX_end(ctx);
12172e7cce5eStb 
1218f7264475Stb 	return ret;
1219b8d22d11Stb }
1220b8d22d11Stb 
1221b8d22d11Stb /*
1222b8d22d11Stb  * Test constant-time modular exponentiation with 1024-bit inputs, which on
1223b8d22d11Stb  * x86_64 cause a different code branch to be taken.
1224b8d22d11Stb  */
1225b8d22d11Stb int
test_mod_exp_mont5(BIO * bp,BN_CTX * ctx)1226b8d22d11Stb test_mod_exp_mont5(BIO *bp, BN_CTX *ctx)
1227b8d22d11Stb {
12280edabd22Stb 	BIGNUM *a, *p, *m, *d, *e;
12290edabd22Stb 	BIGNUM *b, *n, *c;
1230b8d22d11Stb 	BN_MONT_CTX *mont = NULL;
1231b8d22d11Stb 	int len;
1232f7264475Stb 	int ret = 0;
1233b8d22d11Stb 
12340edabd22Stb 	BN_CTX_start(ctx);
12350edabd22Stb 
12360edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
1237b8d22d11Stb 		goto err;
12380edabd22Stb 	if ((p = BN_CTX_get(ctx)) == NULL)
1239b8d22d11Stb 		goto err;
12400edabd22Stb 	if ((m = BN_CTX_get(ctx)) == NULL)
1241b8d22d11Stb 		goto err;
12420edabd22Stb 	if ((d = BN_CTX_get(ctx)) == NULL)
1243b8d22d11Stb 		goto err;
12440edabd22Stb 	if ((e = BN_CTX_get(ctx)) == NULL)
1245b8d22d11Stb 		goto err;
12460edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
1247b8d22d11Stb 		goto err;
12480edabd22Stb 	if ((n = BN_CTX_get(ctx)) == NULL)
1249b8d22d11Stb 		goto err;
12500edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
1251b8d22d11Stb 		goto err;
1252b8d22d11Stb 
1253b8d22d11Stb 	CHECK_GOTO(mont = BN_MONT_CTX_new());
1254b8d22d11Stb 
1255b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(m, 1024, 0, 1)); /* must be odd for montgomery */
1256b8d22d11Stb 	/* Zero exponent */
1257b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(a, 1024, 0, 0));
125830ad135cStb 	BN_zero(p);
1259457e5092Stb 	if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL))
1260b8d22d11Stb 		goto err;
1261b8d22d11Stb 	if (!BN_is_one(d)) {
1262b8d22d11Stb 		fprintf(stderr, "Modular exponentiation test failed!\n");
1263b8d22d11Stb 		goto err;
1264b8d22d11Stb 	}
1265b8d22d11Stb 	/* Regression test for carry bug in mulx4x_mont */
1266b8d22d11Stb 	len = BN_hex2bn(&a,
1267b8d22d11Stb 	    "7878787878787878787878787878787878787878787878787878787878787878"
1268b8d22d11Stb 	    "7878787878787878787878787878787878787878787878787878787878787878"
1269b8d22d11Stb 	    "7878787878787878787878787878787878787878787878787878787878787878"
1270b8d22d11Stb 	    "7878787878787878787878787878787878787878787878787878787878787878");
1271b8d22d11Stb 	CHECK_GOTO(len);
1272b8d22d11Stb 	len = BN_hex2bn(&b,
1273b8d22d11Stb 	    "095D72C08C097BA488C5E439C655A192EAFB6380073D8C2664668EDDB4060744"
1274b8d22d11Stb 	    "E16E57FB4EDB9AE10A0CEFCDC28A894F689A128379DB279D48A2E20849D68593"
1275b8d22d11Stb 	    "9B7803BCF46CEBF5C533FB0DD35B080593DE5472E3FE5DB951B8BFF9B4CB8F03"
1276b8d22d11Stb 	    "9CC638A5EE8CDD703719F8000E6A9F63BEED5F2FCD52FF293EA05A251BB4AB81");
1277b8d22d11Stb 	CHECK_GOTO(len);
1278b8d22d11Stb 	len = BN_hex2bn(&n,
1279b8d22d11Stb 	    "D78AF684E71DB0C39CFF4E64FB9DB567132CB9C50CC98009FEB820B26F2DED9B"
1280b8d22d11Stb 	    "91B9B5E2B83AE0AE4EB4E0523CA726BFBE969B89FD754F674CE99118C3F2D1C5"
1281b8d22d11Stb 	    "D81FDC7C54E02B60262B241D53C040E99E45826ECA37A804668E690E1AFC1CA4"
1282b8d22d11Stb 	    "2C9A15D84D4954425F0B7642FC0BD9D7B24E2618D2DCC9B729D944BADACFDDAF");
1283b8d22d11Stb 	CHECK_GOTO(len);
1284b8d22d11Stb 	CHECK_GOTO(BN_MONT_CTX_set(mont, n, ctx));
1285b8d22d11Stb 	CHECK_GOTO(BN_mod_mul_montgomery(c, a, b, mont, ctx));
1286b8d22d11Stb 	CHECK_GOTO(BN_mod_mul_montgomery(d, b, a, mont, ctx));
1287b8d22d11Stb 	if (BN_cmp(c, d)) {
1288b8d22d11Stb 		fprintf(stderr, "Montgomery multiplication test failed:"
1289b8d22d11Stb 		    " a*b != b*a.\n");
1290b8d22d11Stb 		goto err;
1291b8d22d11Stb 	}
1292b8d22d11Stb 	/* Regression test for carry bug in sqr[x]8x_mont */
1293b8d22d11Stb 	len = BN_hex2bn(&n,
1294b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1295b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1296b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1297b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1298b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1299b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1300b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1301b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFF00"
1302b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1303b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1304b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1305b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1306b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1307b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1308b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1309b8d22d11Stb 	    "00000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF");
1310b8d22d11Stb 	CHECK_GOTO(len);
1311b8d22d11Stb 	len = BN_hex2bn(&a,
1312b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1313b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1314b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1315b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1316b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1317b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1318b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1319b8d22d11Stb 	    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFF0000000000"
1320b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1321b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1322b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1323b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1324b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1325b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1326b8d22d11Stb 	    "0000000000000000000000000000000000000000000000000000000000000000"
1327b8d22d11Stb 	    "000000000000000000000000000000000000000000FFFFFFFFFFFFFF00000000");
1328b8d22d11Stb 	CHECK_GOTO(len);
132980ef34bcStb 	CHECK_GOTO(bn_copy(b, a));
1330b8d22d11Stb 	CHECK_GOTO(BN_MONT_CTX_set(mont, n, ctx));
1331b8d22d11Stb 	CHECK_GOTO(BN_mod_mul_montgomery(c, a, a, mont, ctx));
1332b8d22d11Stb 	CHECK_GOTO(BN_mod_mul_montgomery(d, a, b, mont, ctx));
1333b8d22d11Stb 	if (BN_cmp(c, d)) {
1334b8d22d11Stb 		fprintf(stderr, "Montgomery multiplication test failed:"
1335b8d22d11Stb 		    " a**2 != a*a.\n");
1336b8d22d11Stb 		goto err;
1337b8d22d11Stb 	}
1338b8d22d11Stb 	/* Zero input */
1339b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(p, 1024, 0, 0));
134030ad135cStb 	BN_zero(a);
1341457e5092Stb 	if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL))
1342b8d22d11Stb 		goto err;
1343b8d22d11Stb 	if (!BN_is_zero(d)) {
1344b8d22d11Stb 		fprintf(stderr, "Modular exponentiation test failed!\n");
1345b8d22d11Stb 		goto err;
1346b8d22d11Stb 	}
1347b8d22d11Stb 	/*
1348b8d22d11Stb 	 * Craft an input whose Montgomery representation is 1, i.e., shorter
1349b8d22d11Stb 	 * than the modulus m, in order to test the const time precomputation
1350b8d22d11Stb 	 * scattering/gathering.
1351b8d22d11Stb 	 */
1352b8d22d11Stb 	CHECK_GOTO(BN_one(a));
1353b8d22d11Stb 	CHECK_GOTO(BN_MONT_CTX_set(mont, m, ctx));
1354457e5092Stb 	if (!BN_from_montgomery(e, a, mont, ctx))
1355b8d22d11Stb 		goto err;
1356457e5092Stb 	if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL))
1357b8d22d11Stb 		goto err;
1358457e5092Stb 	if (!BN_mod_exp_simple(a, e, p, m, ctx))
1359b8d22d11Stb 		goto err;
1360b8d22d11Stb 	if (BN_cmp(a, d) != 0) {
1361b8d22d11Stb 		fprintf(stderr, "Modular exponentiation test failed!\n");
1362b8d22d11Stb 		goto err;
1363b8d22d11Stb 	}
1364b8d22d11Stb 	/* Finally, some regular test vectors. */
1365b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(e, 1024, 0, 0));
1366457e5092Stb 	if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL))
1367b8d22d11Stb 		goto err;
1368457e5092Stb 	if (!BN_mod_exp_simple(a, e, p, m, ctx))
1369b8d22d11Stb 		goto err;
1370b8d22d11Stb 	if (BN_cmp(a, d) != 0) {
1371b8d22d11Stb 		fprintf(stderr, "Modular exponentiation test failed!\n");
1372b8d22d11Stb 		goto err;
1373b8d22d11Stb 	}
13742e7cce5eStb 
1375f7264475Stb 	ret = 1;
1376b8d22d11Stb  err:
13770edabd22Stb 	BN_CTX_end(ctx);
1378b8d22d11Stb 	BN_MONT_CTX_free(mont);
13792e7cce5eStb 
1380f7264475Stb 	return ret;
1381b8d22d11Stb }
1382b8d22d11Stb 
1383b8d22d11Stb int
test_exp(BIO * bp,BN_CTX * ctx)1384b8d22d11Stb test_exp(BIO *bp, BN_CTX *ctx)
1385b8d22d11Stb {
13860edabd22Stb 	BIGNUM *a, *b, *d, *e;
1387b8d22d11Stb 	int i;
1388f7264475Stb 	int ret = 0;
1389b8d22d11Stb 
13900edabd22Stb 	BN_CTX_start(ctx);
13910edabd22Stb 
13920edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
1393b8d22d11Stb 		goto err;
13940edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
1395b8d22d11Stb 		goto err;
13960edabd22Stb 	if ((d = BN_CTX_get(ctx)) == NULL)
1397b8d22d11Stb 		goto err;
13980edabd22Stb 	if ((e = BN_CTX_get(ctx)) == NULL)
1399b8d22d11Stb 		goto err;
1400b8d22d11Stb 
1401b8d22d11Stb 	for (i = 0; i < num2; i++) {
1402b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(a, 20 + i * 5, 0, 0));
1403b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(b, 2 + i, 0, 0));
1404b8d22d11Stb 
1405457e5092Stb 		if (BN_exp(d, a, b, ctx) <= 0)
14062e7cce5eStb 			goto err;
1407b8d22d11Stb 
1408b8d22d11Stb 		if (bp != NULL) {
1409b8d22d11Stb 			if (!results) {
1410b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
1411b8d22d11Stb 				BIO_puts(bp, " ^ ");
1412b8d22d11Stb 				CHECK_GOTO(BN_print(bp, b));
1413b8d22d11Stb 				BIO_puts(bp, " - ");
1414b8d22d11Stb 			}
1415b8d22d11Stb 			CHECK_GOTO(BN_print(bp, d));
1416b8d22d11Stb 			BIO_puts(bp, "\n");
1417b8d22d11Stb 		}
1418b8d22d11Stb 		CHECK_GOTO(BN_one(e));
14190edabd22Stb 		for (; !BN_is_zero(b); BN_sub_word(b, 1))
1420b8d22d11Stb 			CHECK_GOTO(BN_mul(e, e, a, ctx));
1421b8d22d11Stb 		CHECK_GOTO(BN_sub(e, e, d));
1422b8d22d11Stb 		if (!BN_is_zero(e)) {
1423b8d22d11Stb 			fprintf(stderr, "Exponentiation test failed!\n");
14242e7cce5eStb 			goto err;
1425b8d22d11Stb 		}
1426b8d22d11Stb 	}
14272e7cce5eStb 
1428f7264475Stb 	ret = 1;
1429b8d22d11Stb  err:
14300edabd22Stb 	BN_CTX_end(ctx);
14312e7cce5eStb 
1432f7264475Stb 	return ret;
1433b8d22d11Stb }
1434b8d22d11Stb 
1435b8d22d11Stb static int
genprime_cb(int p,int n,BN_GENCB * arg)1436b8d22d11Stb genprime_cb(int p, int n, BN_GENCB *arg)
1437b8d22d11Stb {
1438b8d22d11Stb 	char c = '*';
1439b8d22d11Stb 
1440b8d22d11Stb 	if (p == 0)
1441b8d22d11Stb 		c = '.';
1442b8d22d11Stb 	if (p == 1)
1443b8d22d11Stb 		c = '+';
1444b8d22d11Stb 	if (p == 2)
1445b8d22d11Stb 		c = '*';
1446b8d22d11Stb 	if (p == 3)
1447b8d22d11Stb 		c = '\n';
1448b8d22d11Stb 	putc(c, stderr);
14492e7cce5eStb 	return 1;
1450b8d22d11Stb }
1451b8d22d11Stb 
1452b8d22d11Stb int
test_kron(BIO * bp,BN_CTX * ctx)1453b8d22d11Stb test_kron(BIO *bp, BN_CTX *ctx)
1454b8d22d11Stb {
14550edabd22Stb 	BIGNUM *a, *b, *r, *t;
1456b8d22d11Stb 	BN_GENCB *cb = NULL;
1457b8d22d11Stb 	int i;
1458b8d22d11Stb 	int legendre, kronecker;
1459f7264475Stb 	int ret = 0;
1460b8d22d11Stb 
14610edabd22Stb 	BN_CTX_start(ctx);
14620edabd22Stb 
14630edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
1464b8d22d11Stb 		goto err;
14650edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
1466b8d22d11Stb 		goto err;
14670edabd22Stb 	if ((r = BN_CTX_get(ctx)) == NULL)
1468b8d22d11Stb 		goto err;
14690edabd22Stb 	if ((t = BN_CTX_get(ctx)) == NULL)
1470b8d22d11Stb 		goto err;
1471b8d22d11Stb 
1472b8d22d11Stb 	if ((cb = BN_GENCB_new()) == NULL)
1473b8d22d11Stb 		goto err;
1474b8d22d11Stb 
1475b8d22d11Stb 	BN_GENCB_set(cb, genprime_cb, NULL);
1476b8d22d11Stb 
1477b8d22d11Stb 	/*
1478b8d22d11Stb 	 * We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol). In
1479b8d22d11Stb 	 * this case we know that if b is prime, then BN_kronecker(a, b, ctx) is
1480b8d22d11Stb 	 * congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol). So we
1481b8d22d11Stb 	 * generate a random prime b and compare these values for a number of
1482b8d22d11Stb 	 * random a's.  (That is, we run the Solovay-Strassen primality test to
1483b8d22d11Stb 	 * confirm that b is prime, except that we don't want to test whether b
1484b8d22d11Stb 	 * is prime but whether BN_kronecker works.)
1485b8d22d11Stb 	 */
1486b8d22d11Stb 
1487b8d22d11Stb 	if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, cb))
1488b8d22d11Stb 		goto err;
1489b8d22d11Stb 	BN_set_negative(b, rand_neg());
1490b8d22d11Stb 	putc('\n', stderr);
1491b8d22d11Stb 
1492b8d22d11Stb 	for (i = 0; i < num0; i++) {
1493b8d22d11Stb 		if (!BN_bntest_rand(a, 512, 0, 0))
1494b8d22d11Stb 			goto err;
1495b8d22d11Stb 		BN_set_negative(a, rand_neg());
1496b8d22d11Stb 
1497b8d22d11Stb 		/* t := (|b|-1)/2  (note that b is odd) */
14988e84e241Stb 		if (!bn_copy(t, b))
1499b8d22d11Stb 			goto err;
1500b8d22d11Stb 		BN_set_negative(t, 0);
1501b8d22d11Stb 		if (!BN_sub_word(t, 1))
1502b8d22d11Stb 			goto err;
1503b8d22d11Stb 		if (!BN_rshift1(t, t))
1504b8d22d11Stb 			goto err;
1505b8d22d11Stb 		/* r := a^t mod b */
1506b8d22d11Stb 		BN_set_negative(b, 0);
1507b8d22d11Stb 
1508b8d22d11Stb 		if (!BN_mod_exp_recp(r, a, t, b, ctx))
1509b8d22d11Stb 			goto err;
1510b8d22d11Stb 		BN_set_negative(b, 1);
1511b8d22d11Stb 
1512b8d22d11Stb 		if (BN_is_word(r, 1))
1513b8d22d11Stb 			legendre = 1;
1514b8d22d11Stb 		else if (BN_is_zero(r))
1515b8d22d11Stb 			legendre = 0;
1516b8d22d11Stb 		else {
1517b8d22d11Stb 			if (!BN_add_word(r, 1))
1518b8d22d11Stb 				goto err;
1519b8d22d11Stb 			if (0 != BN_ucmp(r, b)) {
1520b8d22d11Stb 				fprintf(stderr, "Legendre symbol computation failed\n");
1521b8d22d11Stb 				goto err;
1522b8d22d11Stb 			}
1523b8d22d11Stb 			legendre = -1;
1524b8d22d11Stb 		}
1525b8d22d11Stb 
1526b8d22d11Stb 		kronecker = BN_kronecker(a, b, ctx);
1527b8d22d11Stb 		if (kronecker < -1)
1528b8d22d11Stb 			goto err;
1529b8d22d11Stb 		/* we actually need BN_kronecker(a, |b|) */
1530b8d22d11Stb 		if (BN_is_negative(a) && BN_is_negative(b))
1531b8d22d11Stb 			kronecker = -kronecker;
1532b8d22d11Stb 
1533b8d22d11Stb 		if (legendre != kronecker) {
1534b8d22d11Stb 			fprintf(stderr, "legendre != kronecker; a = ");
1535b8d22d11Stb 			CHECK_GOTO(BN_print_fp(stderr, a));
1536b8d22d11Stb 			fprintf(stderr, ", b = ");
1537b8d22d11Stb 			CHECK_GOTO(BN_print_fp(stderr, b));
1538b8d22d11Stb 			fprintf(stderr, "\n");
1539b8d22d11Stb 			goto err;
1540b8d22d11Stb 		}
1541b8d22d11Stb 
1542b8d22d11Stb 		putc('.', stderr);
1543b8d22d11Stb 	}
1544b8d22d11Stb 
1545b8d22d11Stb 	putc('\n', stderr);
1546b8d22d11Stb 
1547f7264475Stb 	ret = 1;
1548b8d22d11Stb  err:
1549b8d22d11Stb 	BN_GENCB_free(cb);
15500edabd22Stb 	BN_CTX_end(ctx);
15512e7cce5eStb 
1552f7264475Stb 	return ret;
1553b8d22d11Stb }
1554b8d22d11Stb 
1555b8d22d11Stb int
test_sqrt(BIO * bp,BN_CTX * ctx)1556b8d22d11Stb test_sqrt(BIO *bp, BN_CTX *ctx)
1557b8d22d11Stb {
15580edabd22Stb 	BIGNUM *a, *p, *r;
1559b8d22d11Stb 	BN_GENCB *cb = NULL;
1560b8d22d11Stb 	int i, j;
1561f7264475Stb 	int ret = 0;
1562b8d22d11Stb 
15630edabd22Stb 	BN_CTX_start(ctx);
15640edabd22Stb 
15650edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
1566b8d22d11Stb 		goto err;
15670edabd22Stb 	if ((p = BN_CTX_get(ctx)) == NULL)
1568b8d22d11Stb 		goto err;
15690edabd22Stb 	if ((r = BN_CTX_get(ctx)) == NULL)
1570b8d22d11Stb 		goto err;
1571b8d22d11Stb 
1572b8d22d11Stb 	if ((cb = BN_GENCB_new()) == NULL)
1573b8d22d11Stb 		goto err;
1574b8d22d11Stb 
1575b8d22d11Stb 	BN_GENCB_set(cb, genprime_cb, NULL);
1576b8d22d11Stb 
1577b8d22d11Stb 	for (i = 0; i < 16; i++) {
1578b8d22d11Stb 		if (i < 8) {
1579b8d22d11Stb 			unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
1580b8d22d11Stb 
1581b8d22d11Stb 			if (!BN_set_word(p, primes[i]))
1582b8d22d11Stb 				goto err;
1583b8d22d11Stb 		} else {
1584b8d22d11Stb 			if (!BN_set_word(a, 32))
1585b8d22d11Stb 				goto err;
1586b8d22d11Stb 			if (!BN_set_word(r, 2 * i + 1))
1587b8d22d11Stb 				goto err;
1588b8d22d11Stb 
1589b8d22d11Stb 			if (!BN_generate_prime_ex(p, 256, 0, a, r, cb))
1590b8d22d11Stb 				goto err;
1591b8d22d11Stb 			putc('\n', stderr);
1592b8d22d11Stb 		}
1593b8d22d11Stb 		BN_set_negative(p, rand_neg());
1594b8d22d11Stb 
1595b8d22d11Stb 		for (j = 0; j < num2; j++) {
1596b8d22d11Stb 			/*
1597b8d22d11Stb 			 * construct 'a' such that it is a square modulo p, but in
1598b8d22d11Stb 			 * general not a proper square and not reduced modulo p
1599b8d22d11Stb 			 */
1600b8d22d11Stb 			if (!BN_bntest_rand(r, 256, 0, 3))
1601b8d22d11Stb 				goto err;
1602b8d22d11Stb 			if (!BN_nnmod(r, r, p, ctx))
1603b8d22d11Stb 				goto err;
1604b8d22d11Stb 			if (!BN_mod_sqr(r, r, p, ctx))
1605b8d22d11Stb 				goto err;
1606b8d22d11Stb 			if (!BN_bntest_rand(a, 256, 0, 3))
1607b8d22d11Stb 				goto err;
1608b8d22d11Stb 			if (!BN_nnmod(a, a, p, ctx))
1609b8d22d11Stb 				goto err;
1610b8d22d11Stb 			if (!BN_mod_sqr(a, a, p, ctx))
1611b8d22d11Stb 				goto err;
1612b8d22d11Stb 			if (!BN_mul(a, a, r, ctx))
1613b8d22d11Stb 				goto err;
1614b8d22d11Stb 			if (rand_neg())
1615b8d22d11Stb 				if (!BN_sub(a, a, p))
1616b8d22d11Stb 					goto err;
1617b8d22d11Stb 
1618b8d22d11Stb 			if (!BN_mod_sqrt(r, a, p, ctx))
1619b8d22d11Stb 				goto err;
1620b8d22d11Stb 			if (!BN_mod_sqr(r, r, p, ctx))
1621b8d22d11Stb 				goto err;
1622b8d22d11Stb 
1623b8d22d11Stb 			if (!BN_nnmod(a, a, p, ctx))
1624b8d22d11Stb 				goto err;
1625b8d22d11Stb 
1626b8d22d11Stb 			if (BN_cmp(a, r) != 0) {
1627b8d22d11Stb 				fprintf(stderr, "BN_mod_sqrt failed: a = ");
1628b8d22d11Stb 				CHECK_GOTO(BN_print_fp(stderr, a));
1629b8d22d11Stb 				fprintf(stderr, ", r = ");
1630b8d22d11Stb 				CHECK_GOTO(BN_print_fp(stderr, r));
1631b8d22d11Stb 				fprintf(stderr, ", p = ");
1632b8d22d11Stb 				CHECK_GOTO(BN_print_fp(stderr, p));
1633b8d22d11Stb 				fprintf(stderr, "\n");
1634b8d22d11Stb 				goto err;
1635b8d22d11Stb 			}
1636b8d22d11Stb 
1637b8d22d11Stb 			putc('.', stderr);
1638b8d22d11Stb 		}
1639b8d22d11Stb 
1640b8d22d11Stb 		putc('\n', stderr);
1641b8d22d11Stb 	}
1642b8d22d11Stb 
1643f7264475Stb 	ret = 1;
1644b8d22d11Stb  err:
1645b8d22d11Stb 	BN_GENCB_free(cb);
16460edabd22Stb 	BN_CTX_end(ctx);
16472e7cce5eStb 
1648f7264475Stb 	return ret;
1649b8d22d11Stb }
1650b8d22d11Stb 
1651b8d22d11Stb int
test_lshift(BIO * bp,BN_CTX * ctx,int use_lst)16524bbad1a5Stb test_lshift(BIO *bp, BN_CTX *ctx, int use_lst)
1653b8d22d11Stb {
16540edabd22Stb 	BIGNUM *a, *b, *c, *d;
1655b8d22d11Stb 	int i;
1656f7264475Stb 	int ret = 0;
1657b8d22d11Stb 
16580edabd22Stb 	BN_CTX_start(ctx);
16590edabd22Stb 
16600edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
16614bbad1a5Stb 		goto err;
16620edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
1663b8d22d11Stb 		goto err;
16640edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
1665b8d22d11Stb 		goto err;
16660edabd22Stb 	if ((d = BN_CTX_get(ctx)) == NULL)
1667b8d22d11Stb 		goto err;
1668b8d22d11Stb 	CHECK_GOTO(BN_one(c));
1669b8d22d11Stb 
16704bbad1a5Stb 	if (use_lst) {
16714bbad1a5Stb 		if (!BN_hex2bn(&a, "C64F43042AEACA6E5836805BE8C99B04"
16724bbad1a5Stb 		    "5D4836C2FD16C964F0"))
1673b8d22d11Stb 			goto err;
16744bbad1a5Stb 	} else {
1675b8d22d11Stb 		CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0));
1676b8d22d11Stb 		BN_set_negative(a, rand_neg());
1677b8d22d11Stb 	}
1678b8d22d11Stb 	for (i = 0; i < num0; i++) {
1679b8d22d11Stb 		CHECK_GOTO(BN_lshift(b, a, i + 1));
1680b8d22d11Stb 		CHECK_GOTO(BN_add(c, c, c));
1681b8d22d11Stb 		if (bp != NULL) {
1682b8d22d11Stb 			if (!results) {
1683b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
1684b8d22d11Stb 				BIO_puts(bp, " * ");
1685b8d22d11Stb 				CHECK_GOTO(BN_print(bp, c));
1686b8d22d11Stb 				BIO_puts(bp, " - ");
1687b8d22d11Stb 			}
1688b8d22d11Stb 			CHECK_GOTO(BN_print(bp, b));
1689b8d22d11Stb 			BIO_puts(bp, "\n");
1690b8d22d11Stb 		}
1691b8d22d11Stb 		CHECK_GOTO(BN_mul(d, a, c, ctx));
1692b8d22d11Stb 		CHECK_GOTO(BN_sub(d, d, b));
1693b8d22d11Stb 		if (!BN_is_zero(d)) {
1694b8d22d11Stb 			fprintf(stderr, "Left shift test failed!\n");
1695b8d22d11Stb 			fprintf(stderr, "a=");
1696b8d22d11Stb 			CHECK_GOTO(BN_print_fp(stderr, a));
1697b8d22d11Stb 			fprintf(stderr, "\nb=");
1698b8d22d11Stb 			CHECK_GOTO(BN_print_fp(stderr, b));
1699b8d22d11Stb 			fprintf(stderr, "\nc=");
1700b8d22d11Stb 			CHECK_GOTO(BN_print_fp(stderr, c));
1701b8d22d11Stb 			fprintf(stderr, "\nd=");
1702b8d22d11Stb 			CHECK_GOTO(BN_print_fp(stderr, d));
1703b8d22d11Stb 			fprintf(stderr, "\n");
17042e7cce5eStb 			goto err;
1705b8d22d11Stb 		}
1706b8d22d11Stb 	}
17072e7cce5eStb 
1708f7264475Stb 	ret = 1;
1709b8d22d11Stb  err:
17100edabd22Stb 	BN_CTX_end(ctx);
17112e7cce5eStb 
1712f7264475Stb 	return ret;
1713b8d22d11Stb }
1714b8d22d11Stb 
1715b8d22d11Stb int
test_lshift1(BIO * bp,BN_CTX * ctx)17160edabd22Stb test_lshift1(BIO *bp, BN_CTX *ctx)
1717b8d22d11Stb {
17180edabd22Stb 	BIGNUM *a, *b, *c;
1719b8d22d11Stb 	int i;
1720f7264475Stb 	int ret = 0;
1721b8d22d11Stb 
17220edabd22Stb 	BN_CTX_start(ctx);
17230edabd22Stb 
17240edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
1725b8d22d11Stb 		goto err;
17260edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
1727b8d22d11Stb 		goto err;
17280edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
1729b8d22d11Stb 		goto err;
1730b8d22d11Stb 
1731b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0));
1732b8d22d11Stb 	BN_set_negative(a, rand_neg());
1733b8d22d11Stb 	for (i = 0; i < num0; i++) {
1734b8d22d11Stb 		CHECK_GOTO(BN_lshift1(b, a));
1735b8d22d11Stb 		if (bp != NULL) {
1736b8d22d11Stb 			if (!results) {
1737b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
1738b8d22d11Stb 				BIO_puts(bp, " * 2");
1739b8d22d11Stb 				BIO_puts(bp, " - ");
1740b8d22d11Stb 			}
1741b8d22d11Stb 			CHECK_GOTO(BN_print(bp, b));
1742b8d22d11Stb 			BIO_puts(bp, "\n");
1743b8d22d11Stb 		}
1744b8d22d11Stb 		CHECK_GOTO(BN_add(c, a, a));
1745b8d22d11Stb 		CHECK_GOTO(BN_sub(a, b, c));
1746b8d22d11Stb 		if (!BN_is_zero(a)) {
1747b8d22d11Stb 			fprintf(stderr, "Left shift one test failed!\n");
17482e7cce5eStb 			goto err;
1749b8d22d11Stb 		}
1750b8d22d11Stb 
17518e84e241Stb 		CHECK_GOTO(bn_copy(a, b));
1752b8d22d11Stb 	}
17532e7cce5eStb 
1754f7264475Stb 	ret = 1;
1755b8d22d11Stb  err:
17560edabd22Stb 	BN_CTX_end(ctx);
17572e7cce5eStb 
1758f7264475Stb 	return ret;
1759b8d22d11Stb }
1760b8d22d11Stb 
1761b8d22d11Stb int
test_rshift(BIO * bp,BN_CTX * ctx)1762b8d22d11Stb test_rshift(BIO *bp, BN_CTX *ctx)
1763b8d22d11Stb {
17640edabd22Stb 	BIGNUM *a, *b, *c, *d, *e;
1765b8d22d11Stb 	int i;
1766f7264475Stb 	int ret = 0;
1767b8d22d11Stb 
17680edabd22Stb 	BN_CTX_start(ctx);
17690edabd22Stb 
17700edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
1771b8d22d11Stb 		goto err;
17720edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
1773b8d22d11Stb 		goto err;
17740edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
1775b8d22d11Stb 		goto err;
17760edabd22Stb 	if ((d = BN_CTX_get(ctx)) == NULL)
1777b8d22d11Stb 		goto err;
17780edabd22Stb 	if ((e = BN_CTX_get(ctx)) == NULL)
1779b8d22d11Stb 		goto err;
1780b8d22d11Stb 	CHECK_GOTO(BN_one(c));
1781b8d22d11Stb 
1782b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0));
1783b8d22d11Stb 	BN_set_negative(a, rand_neg());
1784b8d22d11Stb 	for (i = 0; i < num0; i++) {
1785b8d22d11Stb 		CHECK_GOTO(BN_rshift(b, a, i + 1));
1786b8d22d11Stb 		CHECK_GOTO(BN_add(c, c, c));
1787b8d22d11Stb 		if (bp != NULL) {
1788b8d22d11Stb 			if (!results) {
1789b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
1790b8d22d11Stb 				BIO_puts(bp, " / ");
1791b8d22d11Stb 				CHECK_GOTO(BN_print(bp, c));
1792b8d22d11Stb 				BIO_puts(bp, " - ");
1793b8d22d11Stb 			}
1794b8d22d11Stb 			CHECK_GOTO(BN_print(bp, b));
1795b8d22d11Stb 			BIO_puts(bp, "\n");
1796b8d22d11Stb 		}
1797b8d22d11Stb 		CHECK_GOTO(BN_div(d, e, a, c, ctx));
1798b8d22d11Stb 		CHECK_GOTO(BN_sub(d, d, b));
1799b8d22d11Stb 		if (!BN_is_zero(d)) {
1800b8d22d11Stb 			fprintf(stderr, "Right shift test failed!\n");
18012e7cce5eStb 			goto err;
1802b8d22d11Stb 		}
1803b8d22d11Stb 	}
18042e7cce5eStb 
1805f7264475Stb 	ret = 1;
1806b8d22d11Stb  err:
18070edabd22Stb 	BN_CTX_end(ctx);
18082e7cce5eStb 
1809f7264475Stb 	return ret;
1810b8d22d11Stb }
1811b8d22d11Stb 
1812b8d22d11Stb int
test_rshift1(BIO * bp,BN_CTX * ctx)18130edabd22Stb test_rshift1(BIO *bp, BN_CTX *ctx)
1814b8d22d11Stb {
18150edabd22Stb 	BIGNUM *a, *b, *c;
1816b8d22d11Stb 	int i;
1817f7264475Stb 	int ret = 0;
1818b8d22d11Stb 
18190edabd22Stb 	BN_CTX_start(ctx);
18200edabd22Stb 
18210edabd22Stb 	if ((a = BN_CTX_get(ctx)) == NULL)
1822b8d22d11Stb 		goto err;
18230edabd22Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
1824b8d22d11Stb 		goto err;
18250edabd22Stb 	if ((c = BN_CTX_get(ctx)) == NULL)
1826b8d22d11Stb 		goto err;
1827b8d22d11Stb 
1828b8d22d11Stb 	CHECK_GOTO(BN_bntest_rand(a, 200, 0, 0));
1829b8d22d11Stb 	BN_set_negative(a, rand_neg());
1830b8d22d11Stb 	for (i = 0; i < num0; i++) {
1831b8d22d11Stb 		CHECK_GOTO(BN_rshift1(b, a));
1832b8d22d11Stb 		if (bp != NULL) {
1833b8d22d11Stb 			if (!results) {
1834b8d22d11Stb 				CHECK_GOTO(BN_print(bp, a));
1835b8d22d11Stb 				BIO_puts(bp, " / 2");
1836b8d22d11Stb 				BIO_puts(bp, " - ");
1837b8d22d11Stb 			}
1838b8d22d11Stb 			CHECK_GOTO(BN_print(bp, b));
1839b8d22d11Stb 			BIO_puts(bp, "\n");
1840b8d22d11Stb 		}
1841b8d22d11Stb 		CHECK_GOTO(BN_sub(c, a, b));
1842b8d22d11Stb 		CHECK_GOTO(BN_sub(c, c, b));
1843b8d22d11Stb 		if (!BN_is_zero(c) && !BN_abs_is_word(c, 1)) {
1844b8d22d11Stb 			fprintf(stderr, "Right shift one test failed!\n");
18452e7cce5eStb 			goto err;
1846b8d22d11Stb 		}
18478e84e241Stb 		CHECK_GOTO(bn_copy(a, b));
1848b8d22d11Stb 	}
18492e7cce5eStb 
1850f7264475Stb 	ret = 1;
1851b8d22d11Stb  err:
18520edabd22Stb 	BN_CTX_end(ctx);
18532e7cce5eStb 
1854f7264475Stb 	return ret;
1855b8d22d11Stb }
1856b8d22d11Stb 
1857b8d22d11Stb int
rand_neg(void)1858b8d22d11Stb rand_neg(void)
1859b8d22d11Stb {
1860b8d22d11Stb 	static unsigned int neg = 0;
1861b8d22d11Stb 	static int sign[8] = { 0, 0, 0, 1, 1, 0, 1, 1 };
1862b8d22d11Stb 
18630f386146Stb 	return sign[neg++ % 8];
1864b8d22d11Stb }
1865b8d22d11Stb 
1866b8d22d11Stb int
test_mod_exp_sizes(BIO * bp,BN_CTX * ctx)1867b8d22d11Stb test_mod_exp_sizes(BIO *bp, BN_CTX *ctx)
1868b8d22d11Stb {
1869b8d22d11Stb 	BN_MONT_CTX *mont_ctx = NULL;
18700edabd22Stb 	BIGNUM *p, *x, *y, *r, *r2;
1871b8d22d11Stb 	int size;
1872f7264475Stb 	int ret = 0;
1873b8d22d11Stb 
1874b8d22d11Stb 	BN_CTX_start(ctx);
1875b8d22d11Stb 	CHECK_GOTO(p = BN_CTX_get(ctx));
1876b8d22d11Stb 	CHECK_GOTO(x = BN_CTX_get(ctx));
1877b8d22d11Stb 	CHECK_GOTO(y = BN_CTX_get(ctx));
1878b8d22d11Stb 	CHECK_GOTO(r = BN_CTX_get(ctx));
1879b8d22d11Stb 	CHECK_GOTO(r2 = BN_CTX_get(ctx));
1880b8d22d11Stb 	mont_ctx = BN_MONT_CTX_new();
1881b8d22d11Stb 
1882b8d22d11Stb 	if (r2 == NULL || mont_ctx == NULL)
1883b8d22d11Stb 		goto err;
1884b8d22d11Stb 
1885b8d22d11Stb 	if (!BN_generate_prime_ex(p, 32, 0, NULL, NULL, NULL) ||
1886b8d22d11Stb 	    !BN_MONT_CTX_set(mont_ctx, p, ctx))
1887b8d22d11Stb 		goto err;
1888b8d22d11Stb 
1889b8d22d11Stb 	for (size = 32; size < 1024; size += 8) {
1890b8d22d11Stb 		if (!BN_rand(x, size, -1, 0) ||
1891b8d22d11Stb 		    !BN_rand(y, size, -1, 0) ||
1892b8d22d11Stb 		    !BN_mod_exp_mont_consttime(r, x, y, p, ctx, mont_ctx) ||
1893b8d22d11Stb 		    !BN_mod_exp(r2, x, y, p, ctx))
1894b8d22d11Stb 			goto err;
1895b8d22d11Stb 
1896b8d22d11Stb 		if (BN_cmp(r, r2) != 0) {
1897b8d22d11Stb 			char *r_str = NULL;
1898b8d22d11Stb 			char *r2_str = NULL;
1899b8d22d11Stb 			CHECK_GOTO(r_str = BN_bn2hex(r));
1900b8d22d11Stb 			CHECK_GOTO(r2_str = BN_bn2hex(r2));
1901b8d22d11Stb 
1902b8d22d11Stb 			printf("Incorrect answer at size %d: %s vs %s\n",
1903b8d22d11Stb 			    size, r_str, r2_str);
1904b8d22d11Stb 			free(r_str);
1905b8d22d11Stb 			free(r2_str);
1906b8d22d11Stb 			goto err;
1907b8d22d11Stb 		}
1908b8d22d11Stb 	}
1909b8d22d11Stb 
1910f7264475Stb 	ret = 1;
1911b8d22d11Stb  err:
1912b8d22d11Stb 	BN_CTX_end(ctx);
19130edabd22Stb 	BN_MONT_CTX_free(mont_ctx);
19142e7cce5eStb 
1915f7264475Stb 	return ret;
1916b8d22d11Stb }
1917