bntest.c revision 277195
1/* crypto/bn/bntest.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to.  The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 *    must display the following acknowledgement:
33 *    "This product includes cryptographic software written by
34 *     Eric Young (eay@cryptsoft.com)"
35 *    The word 'cryptographic' can be left out if the rouines from the library
36 *    being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 *    the apps directory (application code) you must include an acknowledgement:
39 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 *
61 * Portions of the attached software ("Contribution") are developed by
62 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63 *
64 * The Contribution is licensed pursuant to the Eric Young open source
65 * license provided above.
66 *
67 * The binary polynomial arithmetic software is originally written by
68 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69 *
70 */
71
72/* Until the key-gen callbacks are modified to use newer prototypes, we allow
73 * deprecated functions for openssl-internal code */
74#ifdef OPENSSL_NO_DEPRECATED
75#undef OPENSSL_NO_DEPRECATED
76#endif
77
78#include <stdio.h>
79#include <stdlib.h>
80#include <string.h>
81
82#include "e_os.h"
83
84#include <openssl/bio.h>
85#include <openssl/bn.h>
86#include <openssl/rand.h>
87#include <openssl/x509.h>
88#include <openssl/err.h>
89
90const int num0 = 100; /* number of tests */
91const int num1 = 50;  /* additional tests for some functions */
92const int num2 = 5;   /* number of tests for slow functions */
93
94int test_add(BIO *bp);
95int test_sub(BIO *bp);
96int test_lshift1(BIO *bp);
97int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
98int test_rshift1(BIO *bp);
99int test_rshift(BIO *bp,BN_CTX *ctx);
100int test_div(BIO *bp,BN_CTX *ctx);
101int test_div_word(BIO *bp);
102int test_div_recp(BIO *bp,BN_CTX *ctx);
103int test_mul(BIO *bp);
104int test_sqr(BIO *bp,BN_CTX *ctx);
105int test_mont(BIO *bp,BN_CTX *ctx);
106int test_mod(BIO *bp,BN_CTX *ctx);
107int test_mod_mul(BIO *bp,BN_CTX *ctx);
108int test_mod_exp(BIO *bp,BN_CTX *ctx);
109int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx);
110int test_exp(BIO *bp,BN_CTX *ctx);
111int test_gf2m_add(BIO *bp);
112int test_gf2m_mod(BIO *bp);
113int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx);
114int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx);
115int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx);
116int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx);
117int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx);
118int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx);
119int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx);
120int test_kron(BIO *bp,BN_CTX *ctx);
121int test_sqrt(BIO *bp,BN_CTX *ctx);
122int rand_neg(void);
123static int results=0;
124
125static unsigned char lst[]="\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
126"\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
127
128static const char rnd_seed[] = "string to make the random number generator think it has entropy";
129
130static void message(BIO *out, char *m)
131	{
132	fprintf(stderr, "test %s\n", m);
133	BIO_puts(out, "print \"test ");
134	BIO_puts(out, m);
135	BIO_puts(out, "\\n\"\n");
136	}
137
138int main(int argc, char *argv[])
139	{
140	BN_CTX *ctx;
141	BIO *out;
142	char *outfile=NULL;
143
144	results = 0;
145
146	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
147
148	argc--;
149	argv++;
150	while (argc >= 1)
151		{
152		if (strcmp(*argv,"-results") == 0)
153			results=1;
154		else if (strcmp(*argv,"-out") == 0)
155			{
156			if (--argc < 1) break;
157			outfile= *(++argv);
158			}
159		argc--;
160		argv++;
161		}
162
163
164	ctx=BN_CTX_new();
165	if (ctx == NULL) EXIT(1);
166
167	out=BIO_new(BIO_s_file());
168	if (out == NULL) EXIT(1);
169	if (outfile == NULL)
170		{
171		BIO_set_fp(out,stdout,BIO_NOCLOSE);
172		}
173	else
174		{
175		if (!BIO_write_filename(out,outfile))
176			{
177			perror(outfile);
178			EXIT(1);
179			}
180		}
181
182	if (!results)
183		BIO_puts(out,"obase=16\nibase=16\n");
184
185	message(out,"BN_add");
186	if (!test_add(out)) goto err;
187	(void)BIO_flush(out);
188
189	message(out,"BN_sub");
190	if (!test_sub(out)) goto err;
191	(void)BIO_flush(out);
192
193	message(out,"BN_lshift1");
194	if (!test_lshift1(out)) goto err;
195	(void)BIO_flush(out);
196
197	message(out,"BN_lshift (fixed)");
198	if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
199	    goto err;
200	(void)BIO_flush(out);
201
202	message(out,"BN_lshift");
203	if (!test_lshift(out,ctx,NULL)) goto err;
204	(void)BIO_flush(out);
205
206	message(out,"BN_rshift1");
207	if (!test_rshift1(out)) goto err;
208	(void)BIO_flush(out);
209
210	message(out,"BN_rshift");
211	if (!test_rshift(out,ctx)) goto err;
212	(void)BIO_flush(out);
213
214	message(out,"BN_sqr");
215	if (!test_sqr(out,ctx)) goto err;
216	(void)BIO_flush(out);
217
218	message(out,"BN_mul");
219	if (!test_mul(out)) goto err;
220	(void)BIO_flush(out);
221
222	message(out,"BN_div");
223	if (!test_div(out,ctx)) goto err;
224	(void)BIO_flush(out);
225
226	message(out,"BN_div_word");
227	if (!test_div_word(out)) goto err;
228	(void)BIO_flush(out);
229
230	message(out,"BN_div_recp");
231	if (!test_div_recp(out,ctx)) goto err;
232	(void)BIO_flush(out);
233
234	message(out,"BN_mod");
235	if (!test_mod(out,ctx)) goto err;
236	(void)BIO_flush(out);
237
238	message(out,"BN_mod_mul");
239	if (!test_mod_mul(out,ctx)) goto err;
240	(void)BIO_flush(out);
241
242	message(out,"BN_mont");
243	if (!test_mont(out,ctx)) goto err;
244	(void)BIO_flush(out);
245
246	message(out,"BN_mod_exp");
247	if (!test_mod_exp(out,ctx)) goto err;
248	(void)BIO_flush(out);
249
250	message(out,"BN_mod_exp_mont_consttime");
251	if (!test_mod_exp_mont_consttime(out,ctx)) goto err;
252	(void)BIO_flush(out);
253
254	message(out,"BN_exp");
255	if (!test_exp(out,ctx)) goto err;
256	(void)BIO_flush(out);
257
258	message(out,"BN_kronecker");
259	if (!test_kron(out,ctx)) goto err;
260	(void)BIO_flush(out);
261
262	message(out,"BN_mod_sqrt");
263	if (!test_sqrt(out,ctx)) goto err;
264	(void)BIO_flush(out);
265
266	message(out,"BN_GF2m_add");
267	if (!test_gf2m_add(out)) goto err;
268	(void)BIO_flush(out);
269
270	message(out,"BN_GF2m_mod");
271	if (!test_gf2m_mod(out)) goto err;
272	(void)BIO_flush(out);
273
274	message(out,"BN_GF2m_mod_mul");
275	if (!test_gf2m_mod_mul(out,ctx)) goto err;
276	(void)BIO_flush(out);
277
278	message(out,"BN_GF2m_mod_sqr");
279	if (!test_gf2m_mod_sqr(out,ctx)) goto err;
280	(void)BIO_flush(out);
281
282	message(out,"BN_GF2m_mod_inv");
283	if (!test_gf2m_mod_inv(out,ctx)) goto err;
284	(void)BIO_flush(out);
285
286	message(out,"BN_GF2m_mod_div");
287	if (!test_gf2m_mod_div(out,ctx)) goto err;
288	(void)BIO_flush(out);
289
290	message(out,"BN_GF2m_mod_exp");
291	if (!test_gf2m_mod_exp(out,ctx)) goto err;
292	(void)BIO_flush(out);
293
294	message(out,"BN_GF2m_mod_sqrt");
295	if (!test_gf2m_mod_sqrt(out,ctx)) goto err;
296	(void)BIO_flush(out);
297
298	message(out,"BN_GF2m_mod_solve_quad");
299	if (!test_gf2m_mod_solve_quad(out,ctx)) goto err;
300	(void)BIO_flush(out);
301
302	BN_CTX_free(ctx);
303	BIO_free(out);
304
305/**/
306	EXIT(0);
307err:
308	BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices
309	                      * the failure, see test_bn in test/Makefile.ssl*/
310	(void)BIO_flush(out);
311	ERR_load_crypto_strings();
312	ERR_print_errors_fp(stderr);
313	EXIT(1);
314	return(1);
315	}
316
317int test_add(BIO *bp)
318	{
319	BIGNUM a,b,c;
320	int i;
321
322	BN_init(&a);
323	BN_init(&b);
324	BN_init(&c);
325
326	BN_bntest_rand(&a,512,0,0);
327	for (i=0; i<num0; i++)
328		{
329		BN_bntest_rand(&b,450+i,0,0);
330		a.neg=rand_neg();
331		b.neg=rand_neg();
332		BN_add(&c,&a,&b);
333		if (bp != NULL)
334			{
335			if (!results)
336				{
337				BN_print(bp,&a);
338				BIO_puts(bp," + ");
339				BN_print(bp,&b);
340				BIO_puts(bp," - ");
341				}
342			BN_print(bp,&c);
343			BIO_puts(bp,"\n");
344			}
345		a.neg=!a.neg;
346		b.neg=!b.neg;
347		BN_add(&c,&c,&b);
348		BN_add(&c,&c,&a);
349		if(!BN_is_zero(&c))
350		    {
351		    fprintf(stderr,"Add test failed!\n");
352		    return 0;
353		    }
354		}
355	BN_free(&a);
356	BN_free(&b);
357	BN_free(&c);
358	return(1);
359	}
360
361int test_sub(BIO *bp)
362	{
363	BIGNUM a,b,c;
364	int i;
365
366	BN_init(&a);
367	BN_init(&b);
368	BN_init(&c);
369
370	for (i=0; i<num0+num1; i++)
371		{
372		if (i < num1)
373			{
374			BN_bntest_rand(&a,512,0,0);
375			BN_copy(&b,&a);
376			if (BN_set_bit(&a,i)==0) return(0);
377			BN_add_word(&b,i);
378			}
379		else
380			{
381			BN_bntest_rand(&b,400+i-num1,0,0);
382			a.neg=rand_neg();
383			b.neg=rand_neg();
384			}
385		BN_sub(&c,&a,&b);
386		if (bp != NULL)
387			{
388			if (!results)
389				{
390				BN_print(bp,&a);
391				BIO_puts(bp," - ");
392				BN_print(bp,&b);
393				BIO_puts(bp," - ");
394				}
395			BN_print(bp,&c);
396			BIO_puts(bp,"\n");
397			}
398		BN_add(&c,&c,&b);
399		BN_sub(&c,&c,&a);
400		if(!BN_is_zero(&c))
401		    {
402		    fprintf(stderr,"Subtract test failed!\n");
403		    return 0;
404		    }
405		}
406	BN_free(&a);
407	BN_free(&b);
408	BN_free(&c);
409	return(1);
410	}
411
412int test_div(BIO *bp, BN_CTX *ctx)
413	{
414	BIGNUM a,b,c,d,e;
415	int i;
416
417	BN_init(&a);
418	BN_init(&b);
419	BN_init(&c);
420	BN_init(&d);
421	BN_init(&e);
422
423	for (i=0; i<num0+num1; i++)
424		{
425		if (i < num1)
426			{
427			BN_bntest_rand(&a,400,0,0);
428			BN_copy(&b,&a);
429			BN_lshift(&a,&a,i);
430			BN_add_word(&a,i);
431			}
432		else
433			BN_bntest_rand(&b,50+3*(i-num1),0,0);
434		a.neg=rand_neg();
435		b.neg=rand_neg();
436		BN_div(&d,&c,&a,&b,ctx);
437		if (bp != NULL)
438			{
439			if (!results)
440				{
441				BN_print(bp,&a);
442				BIO_puts(bp," / ");
443				BN_print(bp,&b);
444				BIO_puts(bp," - ");
445				}
446			BN_print(bp,&d);
447			BIO_puts(bp,"\n");
448
449			if (!results)
450				{
451				BN_print(bp,&a);
452				BIO_puts(bp," % ");
453				BN_print(bp,&b);
454				BIO_puts(bp," - ");
455				}
456			BN_print(bp,&c);
457			BIO_puts(bp,"\n");
458			}
459		BN_mul(&e,&d,&b,ctx);
460		BN_add(&d,&e,&c);
461		BN_sub(&d,&d,&a);
462		if(!BN_is_zero(&d))
463		    {
464		    fprintf(stderr,"Division test failed!\n");
465		    return 0;
466		    }
467		}
468	BN_free(&a);
469	BN_free(&b);
470	BN_free(&c);
471	BN_free(&d);
472	BN_free(&e);
473	return(1);
474	}
475
476static void print_word(BIO *bp,BN_ULONG w)
477	{
478#ifdef SIXTY_FOUR_BIT
479	if (sizeof(w) > sizeof(unsigned long))
480		{
481		unsigned long	h=(unsigned long)(w>>32),
482				l=(unsigned long)(w);
483
484		if (h)	BIO_printf(bp,"%lX%08lX",h,l);
485		else	BIO_printf(bp,"%lX",l);
486		return;
487		}
488#endif
489	BIO_printf(bp,"%lX",w);
490	}
491
492int test_div_word(BIO *bp)
493	{
494	BIGNUM   a,b;
495	BN_ULONG r,s;
496	int i;
497
498	BN_init(&a);
499	BN_init(&b);
500
501	for (i=0; i<num0; i++)
502		{
503		do {
504			BN_bntest_rand(&a,512,-1,0);
505			BN_bntest_rand(&b,BN_BITS2,-1,0);
506			s = b.d[0];
507		} while (!s);
508
509		BN_copy(&b, &a);
510		r = BN_div_word(&b, s);
511
512		if (bp != NULL)
513			{
514			if (!results)
515				{
516				BN_print(bp,&a);
517				BIO_puts(bp," / ");
518				print_word(bp,s);
519				BIO_puts(bp," - ");
520				}
521			BN_print(bp,&b);
522			BIO_puts(bp,"\n");
523
524			if (!results)
525				{
526				BN_print(bp,&a);
527				BIO_puts(bp," % ");
528				print_word(bp,s);
529				BIO_puts(bp," - ");
530				}
531			print_word(bp,r);
532			BIO_puts(bp,"\n");
533			}
534		BN_mul_word(&b,s);
535		BN_add_word(&b,r);
536		BN_sub(&b,&a,&b);
537		if(!BN_is_zero(&b))
538		    {
539		    fprintf(stderr,"Division (word) test failed!\n");
540		    return 0;
541		    }
542		}
543	BN_free(&a);
544	BN_free(&b);
545	return(1);
546	}
547
548int test_div_recp(BIO *bp, BN_CTX *ctx)
549	{
550	BIGNUM a,b,c,d,e;
551	BN_RECP_CTX recp;
552	int i;
553
554	BN_RECP_CTX_init(&recp);
555	BN_init(&a);
556	BN_init(&b);
557	BN_init(&c);
558	BN_init(&d);
559	BN_init(&e);
560
561	for (i=0; i<num0+num1; i++)
562		{
563		if (i < num1)
564			{
565			BN_bntest_rand(&a,400,0,0);
566			BN_copy(&b,&a);
567			BN_lshift(&a,&a,i);
568			BN_add_word(&a,i);
569			}
570		else
571			BN_bntest_rand(&b,50+3*(i-num1),0,0);
572		a.neg=rand_neg();
573		b.neg=rand_neg();
574		BN_RECP_CTX_set(&recp,&b,ctx);
575		BN_div_recp(&d,&c,&a,&recp,ctx);
576		if (bp != NULL)
577			{
578			if (!results)
579				{
580				BN_print(bp,&a);
581				BIO_puts(bp," / ");
582				BN_print(bp,&b);
583				BIO_puts(bp," - ");
584				}
585			BN_print(bp,&d);
586			BIO_puts(bp,"\n");
587
588			if (!results)
589				{
590				BN_print(bp,&a);
591				BIO_puts(bp," % ");
592				BN_print(bp,&b);
593				BIO_puts(bp," - ");
594				}
595			BN_print(bp,&c);
596			BIO_puts(bp,"\n");
597			}
598		BN_mul(&e,&d,&b,ctx);
599		BN_add(&d,&e,&c);
600		BN_sub(&d,&d,&a);
601		if(!BN_is_zero(&d))
602		    {
603		    fprintf(stderr,"Reciprocal division test failed!\n");
604		    fprintf(stderr,"a=");
605		    BN_print_fp(stderr,&a);
606		    fprintf(stderr,"\nb=");
607		    BN_print_fp(stderr,&b);
608		    fprintf(stderr,"\n");
609		    return 0;
610		    }
611		}
612	BN_free(&a);
613	BN_free(&b);
614	BN_free(&c);
615	BN_free(&d);
616	BN_free(&e);
617	BN_RECP_CTX_free(&recp);
618	return(1);
619	}
620
621int test_mul(BIO *bp)
622	{
623	BIGNUM a,b,c,d,e;
624	int i;
625	BN_CTX *ctx;
626
627	ctx = BN_CTX_new();
628	if (ctx == NULL) EXIT(1);
629
630	BN_init(&a);
631	BN_init(&b);
632	BN_init(&c);
633	BN_init(&d);
634	BN_init(&e);
635
636	for (i=0; i<num0+num1; i++)
637		{
638		if (i <= num1)
639			{
640			BN_bntest_rand(&a,100,0,0);
641			BN_bntest_rand(&b,100,0,0);
642			}
643		else
644			BN_bntest_rand(&b,i-num1,0,0);
645		a.neg=rand_neg();
646		b.neg=rand_neg();
647		BN_mul(&c,&a,&b,ctx);
648		if (bp != NULL)
649			{
650			if (!results)
651				{
652				BN_print(bp,&a);
653				BIO_puts(bp," * ");
654				BN_print(bp,&b);
655				BIO_puts(bp," - ");
656				}
657			BN_print(bp,&c);
658			BIO_puts(bp,"\n");
659			}
660		BN_div(&d,&e,&c,&a,ctx);
661		BN_sub(&d,&d,&b);
662		if(!BN_is_zero(&d) || !BN_is_zero(&e))
663		    {
664		    fprintf(stderr,"Multiplication test failed!\n");
665		    return 0;
666		    }
667		}
668	BN_free(&a);
669	BN_free(&b);
670	BN_free(&c);
671	BN_free(&d);
672	BN_free(&e);
673	BN_CTX_free(ctx);
674	return(1);
675	}
676
677int test_sqr(BIO *bp, BN_CTX *ctx)
678	{
679	BIGNUM *a,*c,*d,*e;
680	int i, ret = 0;
681
682	a = BN_new();
683	c = BN_new();
684	d = BN_new();
685	e = BN_new();
686	if (a == NULL || c == NULL || d == NULL || e == NULL)
687		{
688		goto err;
689		}
690
691	for (i=0; i<num0; i++)
692		{
693		BN_bntest_rand(a,40+i*10,0,0);
694		a->neg=rand_neg();
695		BN_sqr(c,a,ctx);
696		if (bp != NULL)
697			{
698			if (!results)
699				{
700				BN_print(bp,a);
701				BIO_puts(bp," * ");
702				BN_print(bp,a);
703				BIO_puts(bp," - ");
704				}
705			BN_print(bp,c);
706			BIO_puts(bp,"\n");
707			}
708		BN_div(d,e,c,a,ctx);
709		BN_sub(d,d,a);
710		if(!BN_is_zero(d) || !BN_is_zero(e))
711			{
712			fprintf(stderr,"Square test failed!\n");
713			goto err;
714			}
715		}
716
717	/* Regression test for a BN_sqr overflow bug. */
718	BN_hex2bn(&a,
719		"80000000000000008000000000000001FFFFFFFFFFFFFFFE0000000000000000");
720	BN_sqr(c, a, ctx);
721	if (bp != NULL)
722		{
723		if (!results)
724			{
725			BN_print(bp,a);
726			BIO_puts(bp," * ");
727			BN_print(bp,a);
728			BIO_puts(bp," - ");
729			}
730		BN_print(bp,c);
731		BIO_puts(bp,"\n");
732		}
733	BN_mul(d, a, a, ctx);
734	if (BN_cmp(c, d))
735		{
736		fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
737			"different results!\n");
738		goto err;
739		}
740
741	/* Regression test for a BN_sqr overflow bug. */
742	BN_hex2bn(&a,
743		"80000000000000000000000080000001FFFFFFFE000000000000000000000000");
744	BN_sqr(c, a, ctx);
745	if (bp != NULL)
746		{
747		if (!results)
748			{
749			BN_print(bp,a);
750			BIO_puts(bp," * ");
751			BN_print(bp,a);
752			BIO_puts(bp," - ");
753			}
754		BN_print(bp,c);
755		BIO_puts(bp,"\n");
756		}
757	BN_mul(d, a, a, ctx);
758	if (BN_cmp(c, d))
759		{
760		fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
761			"different results!\n");
762		goto err;
763		}
764	ret = 1;
765err:
766	if (a != NULL) BN_free(a);
767	if (c != NULL) BN_free(c);
768	if (d != NULL) BN_free(d);
769	if (e != NULL) BN_free(e);
770	return ret;
771	}
772
773int test_mont(BIO *bp, BN_CTX *ctx)
774	{
775	BIGNUM a,b,c,d,A,B;
776	BIGNUM n;
777	int i;
778	BN_MONT_CTX *mont;
779
780	BN_init(&a);
781	BN_init(&b);
782	BN_init(&c);
783	BN_init(&d);
784	BN_init(&A);
785	BN_init(&B);
786	BN_init(&n);
787
788	mont=BN_MONT_CTX_new();
789
790	BN_bntest_rand(&a,100,0,0); /**/
791	BN_bntest_rand(&b,100,0,0); /**/
792	for (i=0; i<num2; i++)
793		{
794		int bits = (200*(i+1))/num2;
795
796		if (bits == 0)
797			continue;
798		BN_bntest_rand(&n,bits,0,1);
799		BN_MONT_CTX_set(mont,&n,ctx);
800
801		BN_nnmod(&a,&a,&n,ctx);
802		BN_nnmod(&b,&b,&n,ctx);
803
804		BN_to_montgomery(&A,&a,mont,ctx);
805		BN_to_montgomery(&B,&b,mont,ctx);
806
807		BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
808		BN_from_montgomery(&A,&c,mont,ctx);/**/
809		if (bp != NULL)
810			{
811			if (!results)
812				{
813#ifdef undef
814fprintf(stderr,"%d * %d %% %d\n",
815BN_num_bits(&a),
816BN_num_bits(&b),
817BN_num_bits(mont->N));
818#endif
819				BN_print(bp,&a);
820				BIO_puts(bp," * ");
821				BN_print(bp,&b);
822				BIO_puts(bp," % ");
823				BN_print(bp,&(mont->N));
824				BIO_puts(bp," - ");
825				}
826			BN_print(bp,&A);
827			BIO_puts(bp,"\n");
828			}
829		BN_mod_mul(&d,&a,&b,&n,ctx);
830		BN_sub(&d,&d,&A);
831		if(!BN_is_zero(&d))
832		    {
833		    fprintf(stderr,"Montgomery multiplication test failed!\n");
834		    return 0;
835		    }
836		}
837	BN_MONT_CTX_free(mont);
838	BN_free(&a);
839	BN_free(&b);
840	BN_free(&c);
841	BN_free(&d);
842	BN_free(&A);
843	BN_free(&B);
844	BN_free(&n);
845	return(1);
846	}
847
848int test_mod(BIO *bp, BN_CTX *ctx)
849	{
850	BIGNUM *a,*b,*c,*d,*e;
851	int i;
852
853	a=BN_new();
854	b=BN_new();
855	c=BN_new();
856	d=BN_new();
857	e=BN_new();
858
859	BN_bntest_rand(a,1024,0,0); /**/
860	for (i=0; i<num0; i++)
861		{
862		BN_bntest_rand(b,450+i*10,0,0); /**/
863		a->neg=rand_neg();
864		b->neg=rand_neg();
865		BN_mod(c,a,b,ctx);/**/
866		if (bp != NULL)
867			{
868			if (!results)
869				{
870				BN_print(bp,a);
871				BIO_puts(bp," % ");
872				BN_print(bp,b);
873				BIO_puts(bp," - ");
874				}
875			BN_print(bp,c);
876			BIO_puts(bp,"\n");
877			}
878		BN_div(d,e,a,b,ctx);
879		BN_sub(e,e,c);
880		if(!BN_is_zero(e))
881		    {
882		    fprintf(stderr,"Modulo test failed!\n");
883		    return 0;
884		    }
885		}
886	BN_free(a);
887	BN_free(b);
888	BN_free(c);
889	BN_free(d);
890	BN_free(e);
891	return(1);
892	}
893
894int test_mod_mul(BIO *bp, BN_CTX *ctx)
895	{
896	BIGNUM *a,*b,*c,*d,*e;
897	int i,j;
898
899	a=BN_new();
900	b=BN_new();
901	c=BN_new();
902	d=BN_new();
903	e=BN_new();
904
905	for (j=0; j<3; j++) {
906	BN_bntest_rand(c,1024,0,0); /**/
907	for (i=0; i<num0; i++)
908		{
909		BN_bntest_rand(a,475+i*10,0,0); /**/
910		BN_bntest_rand(b,425+i*11,0,0); /**/
911		a->neg=rand_neg();
912		b->neg=rand_neg();
913		if (!BN_mod_mul(e,a,b,c,ctx))
914			{
915			unsigned long l;
916
917			while ((l=ERR_get_error()))
918				fprintf(stderr,"ERROR:%s\n",
919					ERR_error_string(l,NULL));
920			EXIT(1);
921			}
922		if (bp != NULL)
923			{
924			if (!results)
925				{
926				BN_print(bp,a);
927				BIO_puts(bp," * ");
928				BN_print(bp,b);
929				BIO_puts(bp," % ");
930				BN_print(bp,c);
931				if ((a->neg ^ b->neg) && !BN_is_zero(e))
932					{
933					/* If  (a*b) % c  is negative,  c  must be added
934					 * in order to obtain the normalized remainder
935					 * (new with OpenSSL 0.9.7, previous versions of
936					 * BN_mod_mul could generate negative results)
937					 */
938					BIO_puts(bp," + ");
939					BN_print(bp,c);
940					}
941				BIO_puts(bp," - ");
942				}
943			BN_print(bp,e);
944			BIO_puts(bp,"\n");
945			}
946		BN_mul(d,a,b,ctx);
947		BN_sub(d,d,e);
948		BN_div(a,b,d,c,ctx);
949		if(!BN_is_zero(b))
950		    {
951		    fprintf(stderr,"Modulo multiply test failed!\n");
952		    ERR_print_errors_fp(stderr);
953		    return 0;
954		    }
955		}
956	}
957	BN_free(a);
958	BN_free(b);
959	BN_free(c);
960	BN_free(d);
961	BN_free(e);
962	return(1);
963	}
964
965int test_mod_exp(BIO *bp, BN_CTX *ctx)
966	{
967	BIGNUM *a,*b,*c,*d,*e;
968	int i;
969
970	a=BN_new();
971	b=BN_new();
972	c=BN_new();
973	d=BN_new();
974	e=BN_new();
975
976	BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
977	for (i=0; i<num2; i++)
978		{
979		BN_bntest_rand(a,20+i*5,0,0); /**/
980		BN_bntest_rand(b,2+i,0,0); /**/
981
982		if (!BN_mod_exp(d,a,b,c,ctx))
983			return(0);
984
985		if (bp != NULL)
986			{
987			if (!results)
988				{
989				BN_print(bp,a);
990				BIO_puts(bp," ^ ");
991				BN_print(bp,b);
992				BIO_puts(bp," % ");
993				BN_print(bp,c);
994				BIO_puts(bp," - ");
995				}
996			BN_print(bp,d);
997			BIO_puts(bp,"\n");
998			}
999		BN_exp(e,a,b,ctx);
1000		BN_sub(e,e,d);
1001		BN_div(a,b,e,c,ctx);
1002		if(!BN_is_zero(b))
1003		    {
1004		    fprintf(stderr,"Modulo exponentiation test failed!\n");
1005		    return 0;
1006		    }
1007		}
1008	BN_free(a);
1009	BN_free(b);
1010	BN_free(c);
1011	BN_free(d);
1012	BN_free(e);
1013	return(1);
1014	}
1015
1016int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
1017	{
1018	BIGNUM *a,*b,*c,*d,*e;
1019	int i;
1020
1021	a=BN_new();
1022	b=BN_new();
1023	c=BN_new();
1024	d=BN_new();
1025	e=BN_new();
1026
1027	BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
1028	for (i=0; i<num2; i++)
1029		{
1030		BN_bntest_rand(a,20+i*5,0,0); /**/
1031		BN_bntest_rand(b,2+i,0,0); /**/
1032
1033		if (!BN_mod_exp_mont_consttime(d,a,b,c,ctx,NULL))
1034			return(00);
1035
1036		if (bp != NULL)
1037			{
1038			if (!results)
1039				{
1040				BN_print(bp,a);
1041				BIO_puts(bp," ^ ");
1042				BN_print(bp,b);
1043				BIO_puts(bp," % ");
1044				BN_print(bp,c);
1045				BIO_puts(bp," - ");
1046				}
1047			BN_print(bp,d);
1048			BIO_puts(bp,"\n");
1049			}
1050		BN_exp(e,a,b,ctx);
1051		BN_sub(e,e,d);
1052		BN_div(a,b,e,c,ctx);
1053		if(!BN_is_zero(b))
1054		    {
1055		    fprintf(stderr,"Modulo exponentiation test failed!\n");
1056		    return 0;
1057		    }
1058		}
1059	BN_free(a);
1060	BN_free(b);
1061	BN_free(c);
1062	BN_free(d);
1063	BN_free(e);
1064	return(1);
1065	}
1066
1067int test_exp(BIO *bp, BN_CTX *ctx)
1068	{
1069	BIGNUM *a,*b,*d,*e,*one;
1070	int i;
1071
1072	a=BN_new();
1073	b=BN_new();
1074	d=BN_new();
1075	e=BN_new();
1076	one=BN_new();
1077	BN_one(one);
1078
1079	for (i=0; i<num2; i++)
1080		{
1081		BN_bntest_rand(a,20+i*5,0,0); /**/
1082		BN_bntest_rand(b,2+i,0,0); /**/
1083
1084		if (BN_exp(d,a,b,ctx) <= 0)
1085			return(0);
1086
1087		if (bp != NULL)
1088			{
1089			if (!results)
1090				{
1091				BN_print(bp,a);
1092				BIO_puts(bp," ^ ");
1093				BN_print(bp,b);
1094				BIO_puts(bp," - ");
1095				}
1096			BN_print(bp,d);
1097			BIO_puts(bp,"\n");
1098			}
1099		BN_one(e);
1100		for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
1101		    BN_mul(e,e,a,ctx);
1102		BN_sub(e,e,d);
1103		if(!BN_is_zero(e))
1104		    {
1105		    fprintf(stderr,"Exponentiation test failed!\n");
1106		    return 0;
1107		    }
1108		}
1109	BN_free(a);
1110	BN_free(b);
1111	BN_free(d);
1112	BN_free(e);
1113	BN_free(one);
1114	return(1);
1115	}
1116
1117int test_gf2m_add(BIO *bp)
1118	{
1119	BIGNUM a,b,c;
1120	int i, ret = 0;
1121
1122	BN_init(&a);
1123	BN_init(&b);
1124	BN_init(&c);
1125
1126	for (i=0; i<num0; i++)
1127		{
1128		BN_rand(&a,512,0,0);
1129		BN_copy(&b, BN_value_one());
1130		a.neg=rand_neg();
1131		b.neg=rand_neg();
1132		BN_GF2m_add(&c,&a,&b);
1133#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1134		if (bp != NULL)
1135			{
1136			if (!results)
1137				{
1138				BN_print(bp,&a);
1139				BIO_puts(bp," ^ ");
1140				BN_print(bp,&b);
1141				BIO_puts(bp," = ");
1142				}
1143			BN_print(bp,&c);
1144			BIO_puts(bp,"\n");
1145			}
1146#endif
1147		/* Test that two added values have the correct parity. */
1148		if((BN_is_odd(&a) && BN_is_odd(&c)) || (!BN_is_odd(&a) && !BN_is_odd(&c)))
1149			{
1150		    fprintf(stderr,"GF(2^m) addition test (a) failed!\n");
1151			goto err;
1152			}
1153		BN_GF2m_add(&c,&c,&c);
1154		/* Test that c + c = 0. */
1155		if(!BN_is_zero(&c))
1156		    {
1157		    fprintf(stderr,"GF(2^m) addition test (b) failed!\n");
1158			goto err;
1159		    }
1160		}
1161	ret = 1;
1162  err:
1163	BN_free(&a);
1164	BN_free(&b);
1165	BN_free(&c);
1166	return ret;
1167	}
1168
1169int test_gf2m_mod(BIO *bp)
1170	{
1171	BIGNUM *a,*b[2],*c,*d,*e;
1172	int i, j, ret = 0;
1173	unsigned int p0[] = {163,7,6,3,0};
1174	unsigned int p1[] = {193,15,0};
1175
1176	a=BN_new();
1177	b[0]=BN_new();
1178	b[1]=BN_new();
1179	c=BN_new();
1180	d=BN_new();
1181	e=BN_new();
1182
1183	BN_GF2m_arr2poly(p0, b[0]);
1184	BN_GF2m_arr2poly(p1, b[1]);
1185
1186	for (i=0; i<num0; i++)
1187		{
1188		BN_bntest_rand(a, 1024, 0, 0);
1189		for (j=0; j < 2; j++)
1190			{
1191			BN_GF2m_mod(c, a, b[j]);
1192#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1193			if (bp != NULL)
1194				{
1195				if (!results)
1196					{
1197					BN_print(bp,a);
1198					BIO_puts(bp," % ");
1199					BN_print(bp,b[j]);
1200					BIO_puts(bp," - ");
1201					BN_print(bp,c);
1202					BIO_puts(bp,"\n");
1203					}
1204				}
1205#endif
1206			BN_GF2m_add(d, a, c);
1207			BN_GF2m_mod(e, d, b[j]);
1208			/* Test that a + (a mod p) mod p == 0. */
1209			if(!BN_is_zero(e))
1210				{
1211				fprintf(stderr,"GF(2^m) modulo test failed!\n");
1212				goto err;
1213				}
1214			}
1215		}
1216	ret = 1;
1217  err:
1218	BN_free(a);
1219	BN_free(b[0]);
1220	BN_free(b[1]);
1221	BN_free(c);
1222	BN_free(d);
1223	BN_free(e);
1224	return ret;
1225	}
1226
1227int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx)
1228	{
1229	BIGNUM *a,*b[2],*c,*d,*e,*f,*g,*h;
1230	int i, j, ret = 0;
1231	unsigned int p0[] = {163,7,6,3,0};
1232	unsigned int p1[] = {193,15,0};
1233
1234	a=BN_new();
1235	b[0]=BN_new();
1236	b[1]=BN_new();
1237	c=BN_new();
1238	d=BN_new();
1239	e=BN_new();
1240	f=BN_new();
1241	g=BN_new();
1242	h=BN_new();
1243
1244	BN_GF2m_arr2poly(p0, b[0]);
1245	BN_GF2m_arr2poly(p1, b[1]);
1246
1247	for (i=0; i<num0; i++)
1248		{
1249		BN_bntest_rand(a, 1024, 0, 0);
1250		BN_bntest_rand(c, 1024, 0, 0);
1251		BN_bntest_rand(d, 1024, 0, 0);
1252		for (j=0; j < 2; j++)
1253			{
1254			BN_GF2m_mod_mul(e, a, c, b[j], ctx);
1255#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1256			if (bp != NULL)
1257				{
1258				if (!results)
1259					{
1260					BN_print(bp,a);
1261					BIO_puts(bp," * ");
1262					BN_print(bp,c);
1263					BIO_puts(bp," % ");
1264					BN_print(bp,b[j]);
1265					BIO_puts(bp," - ");
1266					BN_print(bp,e);
1267					BIO_puts(bp,"\n");
1268					}
1269				}
1270#endif
1271			BN_GF2m_add(f, a, d);
1272			BN_GF2m_mod_mul(g, f, c, b[j], ctx);
1273			BN_GF2m_mod_mul(h, d, c, b[j], ctx);
1274			BN_GF2m_add(f, e, g);
1275			BN_GF2m_add(f, f, h);
1276			/* Test that (a+d)*c = a*c + d*c. */
1277			if(!BN_is_zero(f))
1278				{
1279				fprintf(stderr,"GF(2^m) modular multiplication test failed!\n");
1280				goto err;
1281				}
1282			}
1283		}
1284	ret = 1;
1285  err:
1286	BN_free(a);
1287	BN_free(b[0]);
1288	BN_free(b[1]);
1289	BN_free(c);
1290	BN_free(d);
1291	BN_free(e);
1292	BN_free(f);
1293	BN_free(g);
1294	BN_free(h);
1295	return ret;
1296	}
1297
1298int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx)
1299	{
1300	BIGNUM *a,*b[2],*c,*d;
1301	int i, j, ret = 0;
1302	unsigned int p0[] = {163,7,6,3,0};
1303	unsigned int p1[] = {193,15,0};
1304
1305	a=BN_new();
1306	b[0]=BN_new();
1307	b[1]=BN_new();
1308	c=BN_new();
1309	d=BN_new();
1310
1311	BN_GF2m_arr2poly(p0, b[0]);
1312	BN_GF2m_arr2poly(p1, b[1]);
1313
1314	for (i=0; i<num0; i++)
1315		{
1316		BN_bntest_rand(a, 1024, 0, 0);
1317		for (j=0; j < 2; j++)
1318			{
1319			BN_GF2m_mod_sqr(c, a, b[j], ctx);
1320			BN_copy(d, a);
1321			BN_GF2m_mod_mul(d, a, d, b[j], ctx);
1322#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1323			if (bp != NULL)
1324				{
1325				if (!results)
1326					{
1327					BN_print(bp,a);
1328					BIO_puts(bp," ^ 2 % ");
1329					BN_print(bp,b[j]);
1330					BIO_puts(bp, " = ");
1331					BN_print(bp,c);
1332					BIO_puts(bp,"; a * a = ");
1333					BN_print(bp,d);
1334					BIO_puts(bp,"\n");
1335					}
1336				}
1337#endif
1338			BN_GF2m_add(d, c, d);
1339			/* Test that a*a = a^2. */
1340			if(!BN_is_zero(d))
1341				{
1342				fprintf(stderr,"GF(2^m) modular squaring test failed!\n");
1343				goto err;
1344				}
1345			}
1346		}
1347	ret = 1;
1348  err:
1349	BN_free(a);
1350	BN_free(b[0]);
1351	BN_free(b[1]);
1352	BN_free(c);
1353	BN_free(d);
1354	return ret;
1355	}
1356
1357int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx)
1358	{
1359	BIGNUM *a,*b[2],*c,*d;
1360	int i, j, ret = 0;
1361	unsigned int p0[] = {163,7,6,3,0};
1362	unsigned int p1[] = {193,15,0};
1363
1364	a=BN_new();
1365	b[0]=BN_new();
1366	b[1]=BN_new();
1367	c=BN_new();
1368	d=BN_new();
1369
1370	BN_GF2m_arr2poly(p0, b[0]);
1371	BN_GF2m_arr2poly(p1, b[1]);
1372
1373	for (i=0; i<num0; i++)
1374		{
1375		BN_bntest_rand(a, 512, 0, 0);
1376		for (j=0; j < 2; j++)
1377			{
1378			BN_GF2m_mod_inv(c, a, b[j], ctx);
1379			BN_GF2m_mod_mul(d, a, c, b[j], ctx);
1380#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1381			if (bp != NULL)
1382				{
1383				if (!results)
1384					{
1385					BN_print(bp,a);
1386					BIO_puts(bp, " * ");
1387					BN_print(bp,c);
1388					BIO_puts(bp," - 1 % ");
1389					BN_print(bp,b[j]);
1390					BIO_puts(bp,"\n");
1391					}
1392				}
1393#endif
1394			/* Test that ((1/a)*a) = 1. */
1395			if(!BN_is_one(d))
1396				{
1397				fprintf(stderr,"GF(2^m) modular inversion test failed!\n");
1398				goto err;
1399				}
1400			}
1401		}
1402	ret = 1;
1403  err:
1404	BN_free(a);
1405	BN_free(b[0]);
1406	BN_free(b[1]);
1407	BN_free(c);
1408	BN_free(d);
1409	return ret;
1410	}
1411
1412int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx)
1413	{
1414	BIGNUM *a,*b[2],*c,*d,*e,*f;
1415	int i, j, ret = 0;
1416	unsigned int p0[] = {163,7,6,3,0};
1417	unsigned int p1[] = {193,15,0};
1418
1419	a=BN_new();
1420	b[0]=BN_new();
1421	b[1]=BN_new();
1422	c=BN_new();
1423	d=BN_new();
1424	e=BN_new();
1425	f=BN_new();
1426
1427	BN_GF2m_arr2poly(p0, b[0]);
1428	BN_GF2m_arr2poly(p1, b[1]);
1429
1430	for (i=0; i<num0; i++)
1431		{
1432		BN_bntest_rand(a, 512, 0, 0);
1433		BN_bntest_rand(c, 512, 0, 0);
1434		for (j=0; j < 2; j++)
1435			{
1436			BN_GF2m_mod_div(d, a, c, b[j], ctx);
1437			BN_GF2m_mod_mul(e, d, c, b[j], ctx);
1438			BN_GF2m_mod_div(f, a, e, b[j], ctx);
1439#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1440			if (bp != NULL)
1441				{
1442				if (!results)
1443					{
1444					BN_print(bp,a);
1445					BIO_puts(bp, " = ");
1446					BN_print(bp,c);
1447					BIO_puts(bp," * ");
1448					BN_print(bp,d);
1449					BIO_puts(bp, " % ");
1450					BN_print(bp,b[j]);
1451					BIO_puts(bp,"\n");
1452					}
1453				}
1454#endif
1455			/* Test that ((a/c)*c)/a = 1. */
1456			if(!BN_is_one(f))
1457				{
1458				fprintf(stderr,"GF(2^m) modular division test failed!\n");
1459				goto err;
1460				}
1461			}
1462		}
1463	ret = 1;
1464  err:
1465	BN_free(a);
1466	BN_free(b[0]);
1467	BN_free(b[1]);
1468	BN_free(c);
1469	BN_free(d);
1470	BN_free(e);
1471	BN_free(f);
1472	return ret;
1473	}
1474
1475int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx)
1476	{
1477	BIGNUM *a,*b[2],*c,*d,*e,*f;
1478	int i, j, ret = 0;
1479	unsigned int p0[] = {163,7,6,3,0};
1480	unsigned int p1[] = {193,15,0};
1481
1482	a=BN_new();
1483	b[0]=BN_new();
1484	b[1]=BN_new();
1485	c=BN_new();
1486	d=BN_new();
1487	e=BN_new();
1488	f=BN_new();
1489
1490	BN_GF2m_arr2poly(p0, b[0]);
1491	BN_GF2m_arr2poly(p1, b[1]);
1492
1493	for (i=0; i<num0; i++)
1494		{
1495		BN_bntest_rand(a, 512, 0, 0);
1496		BN_bntest_rand(c, 512, 0, 0);
1497		BN_bntest_rand(d, 512, 0, 0);
1498		for (j=0; j < 2; j++)
1499			{
1500			BN_GF2m_mod_exp(e, a, c, b[j], ctx);
1501			BN_GF2m_mod_exp(f, a, d, b[j], ctx);
1502			BN_GF2m_mod_mul(e, e, f, b[j], ctx);
1503			BN_add(f, c, d);
1504			BN_GF2m_mod_exp(f, a, f, b[j], ctx);
1505#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1506			if (bp != NULL)
1507				{
1508				if (!results)
1509					{
1510					BN_print(bp,a);
1511					BIO_puts(bp, " ^ (");
1512					BN_print(bp,c);
1513					BIO_puts(bp," + ");
1514					BN_print(bp,d);
1515					BIO_puts(bp, ") = ");
1516					BN_print(bp,e);
1517					BIO_puts(bp, "; - ");
1518					BN_print(bp,f);
1519					BIO_puts(bp, " % ");
1520					BN_print(bp,b[j]);
1521					BIO_puts(bp,"\n");
1522					}
1523				}
1524#endif
1525			BN_GF2m_add(f, e, f);
1526			/* Test that a^(c+d)=a^c*a^d. */
1527			if(!BN_is_zero(f))
1528				{
1529				fprintf(stderr,"GF(2^m) modular exponentiation test failed!\n");
1530				goto err;
1531				}
1532			}
1533		}
1534	ret = 1;
1535  err:
1536	BN_free(a);
1537	BN_free(b[0]);
1538	BN_free(b[1]);
1539	BN_free(c);
1540	BN_free(d);
1541	BN_free(e);
1542	BN_free(f);
1543	return ret;
1544	}
1545
1546int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx)
1547	{
1548	BIGNUM *a,*b[2],*c,*d,*e,*f;
1549	int i, j, ret = 0;
1550	unsigned int p0[] = {163,7,6,3,0};
1551	unsigned int p1[] = {193,15,0};
1552
1553	a=BN_new();
1554	b[0]=BN_new();
1555	b[1]=BN_new();
1556	c=BN_new();
1557	d=BN_new();
1558	e=BN_new();
1559	f=BN_new();
1560
1561	BN_GF2m_arr2poly(p0, b[0]);
1562	BN_GF2m_arr2poly(p1, b[1]);
1563
1564	for (i=0; i<num0; i++)
1565		{
1566		BN_bntest_rand(a, 512, 0, 0);
1567		for (j=0; j < 2; j++)
1568			{
1569			BN_GF2m_mod(c, a, b[j]);
1570			BN_GF2m_mod_sqrt(d, a, b[j], ctx);
1571			BN_GF2m_mod_sqr(e, d, b[j], ctx);
1572#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1573			if (bp != NULL)
1574				{
1575				if (!results)
1576					{
1577					BN_print(bp,d);
1578					BIO_puts(bp, " ^ 2 - ");
1579					BN_print(bp,a);
1580					BIO_puts(bp,"\n");
1581					}
1582				}
1583#endif
1584			BN_GF2m_add(f, c, e);
1585			/* Test that d^2 = a, where d = sqrt(a). */
1586			if(!BN_is_zero(f))
1587				{
1588				fprintf(stderr,"GF(2^m) modular square root test failed!\n");
1589				goto err;
1590				}
1591			}
1592		}
1593	ret = 1;
1594  err:
1595	BN_free(a);
1596	BN_free(b[0]);
1597	BN_free(b[1]);
1598	BN_free(c);
1599	BN_free(d);
1600	BN_free(e);
1601	BN_free(f);
1602	return ret;
1603	}
1604
1605int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx)
1606	{
1607	BIGNUM *a,*b[2],*c,*d,*e;
1608	int i, j, s = 0, t, ret = 0;
1609	unsigned int p0[] = {163,7,6,3,0};
1610	unsigned int p1[] = {193,15,0};
1611
1612	a=BN_new();
1613	b[0]=BN_new();
1614	b[1]=BN_new();
1615	c=BN_new();
1616	d=BN_new();
1617	e=BN_new();
1618
1619	BN_GF2m_arr2poly(p0, b[0]);
1620	BN_GF2m_arr2poly(p1, b[1]);
1621
1622	for (i=0; i<num0; i++)
1623		{
1624		BN_bntest_rand(a, 512, 0, 0);
1625		for (j=0; j < 2; j++)
1626			{
1627			t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
1628			if (t)
1629				{
1630				s++;
1631				BN_GF2m_mod_sqr(d, c, b[j], ctx);
1632				BN_GF2m_add(d, c, d);
1633				BN_GF2m_mod(e, a, b[j]);
1634#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1635				if (bp != NULL)
1636					{
1637					if (!results)
1638						{
1639						BN_print(bp,c);
1640						BIO_puts(bp, " is root of z^2 + z = ");
1641						BN_print(bp,a);
1642						BIO_puts(bp, " % ");
1643						BN_print(bp,b[j]);
1644						BIO_puts(bp, "\n");
1645						}
1646					}
1647#endif
1648				BN_GF2m_add(e, e, d);
1649				/* Test that solution of quadratic c satisfies c^2 + c = a. */
1650				if(!BN_is_zero(e))
1651					{
1652					fprintf(stderr,"GF(2^m) modular solve quadratic test failed!\n");
1653					goto err;
1654					}
1655
1656				}
1657			else
1658				{
1659#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1660				if (bp != NULL)
1661					{
1662					if (!results)
1663						{
1664						BIO_puts(bp, "There are no roots of z^2 + z = ");
1665						BN_print(bp,a);
1666						BIO_puts(bp, " % ");
1667						BN_print(bp,b[j]);
1668						BIO_puts(bp, "\n");
1669						}
1670					}
1671#endif
1672				}
1673			}
1674		}
1675	if (s == 0)
1676		{
1677		fprintf(stderr,"All %i tests of GF(2^m) modular solve quadratic resulted in no roots;\n", num0);
1678		fprintf(stderr,"this is very unlikely and probably indicates an error.\n");
1679		goto err;
1680		}
1681	ret = 1;
1682  err:
1683	BN_free(a);
1684	BN_free(b[0]);
1685	BN_free(b[1]);
1686	BN_free(c);
1687	BN_free(d);
1688	BN_free(e);
1689	return ret;
1690	}
1691
1692static int genprime_cb(int p, int n, BN_GENCB *arg)
1693	{
1694	char c='*';
1695
1696	if (p == 0) c='.';
1697	if (p == 1) c='+';
1698	if (p == 2) c='*';
1699	if (p == 3) c='\n';
1700	putc(c, stderr);
1701	fflush(stderr);
1702	return 1;
1703	}
1704
1705int test_kron(BIO *bp, BN_CTX *ctx)
1706	{
1707	BN_GENCB cb;
1708	BIGNUM *a,*b,*r,*t;
1709	int i;
1710	int legendre, kronecker;
1711	int ret = 0;
1712
1713	a = BN_new();
1714	b = BN_new();
1715	r = BN_new();
1716	t = BN_new();
1717	if (a == NULL || b == NULL || r == NULL || t == NULL) goto err;
1718
1719	BN_GENCB_set(&cb, genprime_cb, NULL);
1720
1721	/* We test BN_kronecker(a, b, ctx) just for  b  odd (Jacobi symbol).
1722	 * In this case we know that if  b  is prime, then BN_kronecker(a, b, ctx)
1723	 * is congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol).
1724	 * So we generate a random prime  b  and compare these values
1725	 * for a number of random  a's.  (That is, we run the Solovay-Strassen
1726	 * primality test to confirm that  b  is prime, except that we
1727	 * don't want to test whether  b  is prime but whether BN_kronecker
1728	 * works.) */
1729
1730	if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, &cb)) goto err;
1731	b->neg = rand_neg();
1732	putc('\n', stderr);
1733
1734	for (i = 0; i < num0; i++)
1735		{
1736		if (!BN_bntest_rand(a, 512, 0, 0)) goto err;
1737		a->neg = rand_neg();
1738
1739		/* t := (|b|-1)/2  (note that b is odd) */
1740		if (!BN_copy(t, b)) goto err;
1741		t->neg = 0;
1742		if (!BN_sub_word(t, 1)) goto err;
1743		if (!BN_rshift1(t, t)) goto err;
1744		/* r := a^t mod b */
1745		b->neg=0;
1746
1747		if (!BN_mod_exp_recp(r, a, t, b, ctx)) goto err;
1748		b->neg=1;
1749
1750		if (BN_is_word(r, 1))
1751			legendre = 1;
1752		else if (BN_is_zero(r))
1753			legendre = 0;
1754		else
1755			{
1756			if (!BN_add_word(r, 1)) goto err;
1757			if (0 != BN_ucmp(r, b))
1758				{
1759				fprintf(stderr, "Legendre symbol computation failed\n");
1760				goto err;
1761				}
1762			legendre = -1;
1763			}
1764
1765		kronecker = BN_kronecker(a, b, ctx);
1766		if (kronecker < -1) goto err;
1767		/* we actually need BN_kronecker(a, |b|) */
1768		if (a->neg && b->neg)
1769			kronecker = -kronecker;
1770
1771		if (legendre != kronecker)
1772			{
1773			fprintf(stderr, "legendre != kronecker; a = ");
1774			BN_print_fp(stderr, a);
1775			fprintf(stderr, ", b = ");
1776			BN_print_fp(stderr, b);
1777			fprintf(stderr, "\n");
1778			goto err;
1779			}
1780
1781		putc('.', stderr);
1782		fflush(stderr);
1783		}
1784
1785	putc('\n', stderr);
1786	fflush(stderr);
1787	ret = 1;
1788 err:
1789	if (a != NULL) BN_free(a);
1790	if (b != NULL) BN_free(b);
1791	if (r != NULL) BN_free(r);
1792	if (t != NULL) BN_free(t);
1793	return ret;
1794	}
1795
1796int test_sqrt(BIO *bp, BN_CTX *ctx)
1797	{
1798	BN_GENCB cb;
1799	BIGNUM *a,*p,*r;
1800	int i, j;
1801	int ret = 0;
1802
1803	a = BN_new();
1804	p = BN_new();
1805	r = BN_new();
1806	if (a == NULL || p == NULL || r == NULL) goto err;
1807
1808	BN_GENCB_set(&cb, genprime_cb, NULL);
1809
1810	for (i = 0; i < 16; i++)
1811		{
1812		if (i < 8)
1813			{
1814			unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
1815
1816			if (!BN_set_word(p, primes[i])) goto err;
1817			}
1818		else
1819			{
1820			if (!BN_set_word(a, 32)) goto err;
1821			if (!BN_set_word(r, 2*i + 1)) goto err;
1822
1823			if (!BN_generate_prime_ex(p, 256, 0, a, r, &cb)) goto err;
1824			putc('\n', stderr);
1825			}
1826		p->neg = rand_neg();
1827
1828		for (j = 0; j < num2; j++)
1829			{
1830			/* construct 'a' such that it is a square modulo p,
1831			 * but in general not a proper square and not reduced modulo p */
1832			if (!BN_bntest_rand(r, 256, 0, 3)) goto err;
1833			if (!BN_nnmod(r, r, p, ctx)) goto err;
1834			if (!BN_mod_sqr(r, r, p, ctx)) goto err;
1835			if (!BN_bntest_rand(a, 256, 0, 3)) goto err;
1836			if (!BN_nnmod(a, a, p, ctx)) goto err;
1837			if (!BN_mod_sqr(a, a, p, ctx)) goto err;
1838			if (!BN_mul(a, a, r, ctx)) goto err;
1839			if (rand_neg())
1840				if (!BN_sub(a, a, p)) goto err;
1841
1842			if (!BN_mod_sqrt(r, a, p, ctx)) goto err;
1843			if (!BN_mod_sqr(r, r, p, ctx)) goto err;
1844
1845			if (!BN_nnmod(a, a, p, ctx)) goto err;
1846
1847			if (BN_cmp(a, r) != 0)
1848				{
1849				fprintf(stderr, "BN_mod_sqrt failed: a = ");
1850				BN_print_fp(stderr, a);
1851				fprintf(stderr, ", r = ");
1852				BN_print_fp(stderr, r);
1853				fprintf(stderr, ", p = ");
1854				BN_print_fp(stderr, p);
1855				fprintf(stderr, "\n");
1856				goto err;
1857				}
1858
1859			putc('.', stderr);
1860			fflush(stderr);
1861			}
1862
1863		putc('\n', stderr);
1864		fflush(stderr);
1865		}
1866	ret = 1;
1867 err:
1868	if (a != NULL) BN_free(a);
1869	if (p != NULL) BN_free(p);
1870	if (r != NULL) BN_free(r);
1871	return ret;
1872	}
1873
1874int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
1875	{
1876	BIGNUM *a,*b,*c,*d;
1877	int i;
1878
1879	b=BN_new();
1880	c=BN_new();
1881	d=BN_new();
1882	BN_one(c);
1883
1884	if(a_)
1885	    a=a_;
1886	else
1887	    {
1888	    a=BN_new();
1889	    BN_bntest_rand(a,200,0,0); /**/
1890	    a->neg=rand_neg();
1891	    }
1892	for (i=0; i<num0; i++)
1893		{
1894		BN_lshift(b,a,i+1);
1895		BN_add(c,c,c);
1896		if (bp != NULL)
1897			{
1898			if (!results)
1899				{
1900				BN_print(bp,a);
1901				BIO_puts(bp," * ");
1902				BN_print(bp,c);
1903				BIO_puts(bp," - ");
1904				}
1905			BN_print(bp,b);
1906			BIO_puts(bp,"\n");
1907			}
1908		BN_mul(d,a,c,ctx);
1909		BN_sub(d,d,b);
1910		if(!BN_is_zero(d))
1911		    {
1912		    fprintf(stderr,"Left shift test failed!\n");
1913		    fprintf(stderr,"a=");
1914		    BN_print_fp(stderr,a);
1915		    fprintf(stderr,"\nb=");
1916		    BN_print_fp(stderr,b);
1917		    fprintf(stderr,"\nc=");
1918		    BN_print_fp(stderr,c);
1919		    fprintf(stderr,"\nd=");
1920		    BN_print_fp(stderr,d);
1921		    fprintf(stderr,"\n");
1922		    return 0;
1923		    }
1924		}
1925	BN_free(a);
1926	BN_free(b);
1927	BN_free(c);
1928	BN_free(d);
1929	return(1);
1930	}
1931
1932int test_lshift1(BIO *bp)
1933	{
1934	BIGNUM *a,*b,*c;
1935	int i;
1936
1937	a=BN_new();
1938	b=BN_new();
1939	c=BN_new();
1940
1941	BN_bntest_rand(a,200,0,0); /**/
1942	a->neg=rand_neg();
1943	for (i=0; i<num0; i++)
1944		{
1945		BN_lshift1(b,a);
1946		if (bp != NULL)
1947			{
1948			if (!results)
1949				{
1950				BN_print(bp,a);
1951				BIO_puts(bp," * 2");
1952				BIO_puts(bp," - ");
1953				}
1954			BN_print(bp,b);
1955			BIO_puts(bp,"\n");
1956			}
1957		BN_add(c,a,a);
1958		BN_sub(a,b,c);
1959		if(!BN_is_zero(a))
1960		    {
1961		    fprintf(stderr,"Left shift one test failed!\n");
1962		    return 0;
1963		    }
1964
1965		BN_copy(a,b);
1966		}
1967	BN_free(a);
1968	BN_free(b);
1969	BN_free(c);
1970	return(1);
1971	}
1972
1973int test_rshift(BIO *bp,BN_CTX *ctx)
1974	{
1975	BIGNUM *a,*b,*c,*d,*e;
1976	int i;
1977
1978	a=BN_new();
1979	b=BN_new();
1980	c=BN_new();
1981	d=BN_new();
1982	e=BN_new();
1983	BN_one(c);
1984
1985	BN_bntest_rand(a,200,0,0); /**/
1986	a->neg=rand_neg();
1987	for (i=0; i<num0; i++)
1988		{
1989		BN_rshift(b,a,i+1);
1990		BN_add(c,c,c);
1991		if (bp != NULL)
1992			{
1993			if (!results)
1994				{
1995				BN_print(bp,a);
1996				BIO_puts(bp," / ");
1997				BN_print(bp,c);
1998				BIO_puts(bp," - ");
1999				}
2000			BN_print(bp,b);
2001			BIO_puts(bp,"\n");
2002			}
2003		BN_div(d,e,a,c,ctx);
2004		BN_sub(d,d,b);
2005		if(!BN_is_zero(d))
2006		    {
2007		    fprintf(stderr,"Right shift test failed!\n");
2008		    return 0;
2009		    }
2010		}
2011	BN_free(a);
2012	BN_free(b);
2013	BN_free(c);
2014	BN_free(d);
2015	BN_free(e);
2016	return(1);
2017	}
2018
2019int test_rshift1(BIO *bp)
2020	{
2021	BIGNUM *a,*b,*c;
2022	int i;
2023
2024	a=BN_new();
2025	b=BN_new();
2026	c=BN_new();
2027
2028	BN_bntest_rand(a,200,0,0); /**/
2029	a->neg=rand_neg();
2030	for (i=0; i<num0; i++)
2031		{
2032		BN_rshift1(b,a);
2033		if (bp != NULL)
2034			{
2035			if (!results)
2036				{
2037				BN_print(bp,a);
2038				BIO_puts(bp," / 2");
2039				BIO_puts(bp," - ");
2040				}
2041			BN_print(bp,b);
2042			BIO_puts(bp,"\n");
2043			}
2044		BN_sub(c,a,b);
2045		BN_sub(c,c,b);
2046		if(!BN_is_zero(c) && !BN_abs_is_word(c, 1))
2047		    {
2048		    fprintf(stderr,"Right shift one test failed!\n");
2049		    return 0;
2050		    }
2051		BN_copy(a,b);
2052		}
2053	BN_free(a);
2054	BN_free(b);
2055	BN_free(c);
2056	return(1);
2057	}
2058
2059int rand_neg(void)
2060	{
2061	static unsigned int neg=0;
2062	static int sign[8]={0,0,0,1,1,0,1,1};
2063
2064	return(sign[(neg++)%8]);
2065	}
2066