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#ifndef OPENSSL_NO_EC2M
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#endif
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,BN_HEX_FMT1,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	if (mont == NULL)
790		return 0;
791
792	BN_bntest_rand(&a,100,0,0); /**/
793	BN_bntest_rand(&b,100,0,0); /**/
794	for (i=0; i<num2; i++)
795		{
796		int bits = (200*(i+1))/num2;
797
798		if (bits == 0)
799			continue;
800		BN_bntest_rand(&n,bits,0,1);
801		BN_MONT_CTX_set(mont,&n,ctx);
802
803		BN_nnmod(&a,&a,&n,ctx);
804		BN_nnmod(&b,&b,&n,ctx);
805
806		BN_to_montgomery(&A,&a,mont,ctx);
807		BN_to_montgomery(&B,&b,mont,ctx);
808
809		BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
810		BN_from_montgomery(&A,&c,mont,ctx);/**/
811		if (bp != NULL)
812			{
813			if (!results)
814				{
815#ifdef undef
816fprintf(stderr,"%d * %d %% %d\n",
817BN_num_bits(&a),
818BN_num_bits(&b),
819BN_num_bits(mont->N));
820#endif
821				BN_print(bp,&a);
822				BIO_puts(bp," * ");
823				BN_print(bp,&b);
824				BIO_puts(bp," % ");
825				BN_print(bp,&(mont->N));
826				BIO_puts(bp," - ");
827				}
828			BN_print(bp,&A);
829			BIO_puts(bp,"\n");
830			}
831		BN_mod_mul(&d,&a,&b,&n,ctx);
832		BN_sub(&d,&d,&A);
833		if(!BN_is_zero(&d))
834		    {
835		    fprintf(stderr,"Montgomery multiplication test failed!\n");
836		    return 0;
837		    }
838		}
839	BN_MONT_CTX_free(mont);
840	BN_free(&a);
841	BN_free(&b);
842	BN_free(&c);
843	BN_free(&d);
844	BN_free(&A);
845	BN_free(&B);
846	BN_free(&n);
847	return(1);
848	}
849
850int test_mod(BIO *bp, BN_CTX *ctx)
851	{
852	BIGNUM *a,*b,*c,*d,*e;
853	int i;
854
855	a=BN_new();
856	b=BN_new();
857	c=BN_new();
858	d=BN_new();
859	e=BN_new();
860
861	BN_bntest_rand(a,1024,0,0); /**/
862	for (i=0; i<num0; i++)
863		{
864		BN_bntest_rand(b,450+i*10,0,0); /**/
865		a->neg=rand_neg();
866		b->neg=rand_neg();
867		BN_mod(c,a,b,ctx);/**/
868		if (bp != NULL)
869			{
870			if (!results)
871				{
872				BN_print(bp,a);
873				BIO_puts(bp," % ");
874				BN_print(bp,b);
875				BIO_puts(bp," - ");
876				}
877			BN_print(bp,c);
878			BIO_puts(bp,"\n");
879			}
880		BN_div(d,e,a,b,ctx);
881		BN_sub(e,e,c);
882		if(!BN_is_zero(e))
883		    {
884		    fprintf(stderr,"Modulo test failed!\n");
885		    return 0;
886		    }
887		}
888	BN_free(a);
889	BN_free(b);
890	BN_free(c);
891	BN_free(d);
892	BN_free(e);
893	return(1);
894	}
895
896int test_mod_mul(BIO *bp, BN_CTX *ctx)
897	{
898	BIGNUM *a,*b,*c,*d,*e;
899	int i,j;
900
901	a=BN_new();
902	b=BN_new();
903	c=BN_new();
904	d=BN_new();
905	e=BN_new();
906
907	for (j=0; j<3; j++) {
908	BN_bntest_rand(c,1024,0,0); /**/
909	for (i=0; i<num0; i++)
910		{
911		BN_bntest_rand(a,475+i*10,0,0); /**/
912		BN_bntest_rand(b,425+i*11,0,0); /**/
913		a->neg=rand_neg();
914		b->neg=rand_neg();
915		if (!BN_mod_mul(e,a,b,c,ctx))
916			{
917			unsigned long l;
918
919			while ((l=ERR_get_error()))
920				fprintf(stderr,"ERROR:%s\n",
921					ERR_error_string(l,NULL));
922			EXIT(1);
923			}
924		if (bp != NULL)
925			{
926			if (!results)
927				{
928				BN_print(bp,a);
929				BIO_puts(bp," * ");
930				BN_print(bp,b);
931				BIO_puts(bp," % ");
932				BN_print(bp,c);
933				if ((a->neg ^ b->neg) && !BN_is_zero(e))
934					{
935					/* If  (a*b) % c  is negative,  c  must be added
936					 * in order to obtain the normalized remainder
937					 * (new with OpenSSL 0.9.7, previous versions of
938					 * BN_mod_mul could generate negative results)
939					 */
940					BIO_puts(bp," + ");
941					BN_print(bp,c);
942					}
943				BIO_puts(bp," - ");
944				}
945			BN_print(bp,e);
946			BIO_puts(bp,"\n");
947			}
948		BN_mul(d,a,b,ctx);
949		BN_sub(d,d,e);
950		BN_div(a,b,d,c,ctx);
951		if(!BN_is_zero(b))
952		    {
953		    fprintf(stderr,"Modulo multiply test failed!\n");
954		    ERR_print_errors_fp(stderr);
955		    return 0;
956		    }
957		}
958	}
959	BN_free(a);
960	BN_free(b);
961	BN_free(c);
962	BN_free(d);
963	BN_free(e);
964	return(1);
965	}
966
967int test_mod_exp(BIO *bp, BN_CTX *ctx)
968	{
969	BIGNUM *a,*b,*c,*d,*e;
970	int i;
971
972	a=BN_new();
973	b=BN_new();
974	c=BN_new();
975	d=BN_new();
976	e=BN_new();
977
978	BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
979	for (i=0; i<num2; i++)
980		{
981		BN_bntest_rand(a,20+i*5,0,0); /**/
982		BN_bntest_rand(b,2+i,0,0); /**/
983
984		if (!BN_mod_exp(d,a,b,c,ctx))
985			return(0);
986
987		if (bp != NULL)
988			{
989			if (!results)
990				{
991				BN_print(bp,a);
992				BIO_puts(bp," ^ ");
993				BN_print(bp,b);
994				BIO_puts(bp," % ");
995				BN_print(bp,c);
996				BIO_puts(bp," - ");
997				}
998			BN_print(bp,d);
999			BIO_puts(bp,"\n");
1000			}
1001		BN_exp(e,a,b,ctx);
1002		BN_sub(e,e,d);
1003		BN_div(a,b,e,c,ctx);
1004		if(!BN_is_zero(b))
1005		    {
1006		    fprintf(stderr,"Modulo exponentiation test failed!\n");
1007		    return 0;
1008		    }
1009		}
1010	BN_free(a);
1011	BN_free(b);
1012	BN_free(c);
1013	BN_free(d);
1014	BN_free(e);
1015	return(1);
1016	}
1017
1018int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
1019	{
1020	BIGNUM *a,*b,*c,*d,*e;
1021	int i;
1022
1023	a=BN_new();
1024	b=BN_new();
1025	c=BN_new();
1026	d=BN_new();
1027	e=BN_new();
1028
1029	BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
1030	for (i=0; i<num2; i++)
1031		{
1032		BN_bntest_rand(a,20+i*5,0,0); /**/
1033		BN_bntest_rand(b,2+i,0,0); /**/
1034
1035		if (!BN_mod_exp_mont_consttime(d,a,b,c,ctx,NULL))
1036			return(00);
1037
1038		if (bp != NULL)
1039			{
1040			if (!results)
1041				{
1042				BN_print(bp,a);
1043				BIO_puts(bp," ^ ");
1044				BN_print(bp,b);
1045				BIO_puts(bp," % ");
1046				BN_print(bp,c);
1047				BIO_puts(bp," - ");
1048				}
1049			BN_print(bp,d);
1050			BIO_puts(bp,"\n");
1051			}
1052		BN_exp(e,a,b,ctx);
1053		BN_sub(e,e,d);
1054		BN_div(a,b,e,c,ctx);
1055		if(!BN_is_zero(b))
1056		    {
1057		    fprintf(stderr,"Modulo exponentiation test failed!\n");
1058		    return 0;
1059		    }
1060		}
1061	BN_free(a);
1062	BN_free(b);
1063	BN_free(c);
1064	BN_free(d);
1065	BN_free(e);
1066	return(1);
1067	}
1068
1069int test_exp(BIO *bp, BN_CTX *ctx)
1070	{
1071	BIGNUM *a,*b,*d,*e,*one;
1072	int i;
1073
1074	a=BN_new();
1075	b=BN_new();
1076	d=BN_new();
1077	e=BN_new();
1078	one=BN_new();
1079	BN_one(one);
1080
1081	for (i=0; i<num2; i++)
1082		{
1083		BN_bntest_rand(a,20+i*5,0,0); /**/
1084		BN_bntest_rand(b,2+i,0,0); /**/
1085
1086		if (BN_exp(d,a,b,ctx) <= 0)
1087			return(0);
1088
1089		if (bp != NULL)
1090			{
1091			if (!results)
1092				{
1093				BN_print(bp,a);
1094				BIO_puts(bp," ^ ");
1095				BN_print(bp,b);
1096				BIO_puts(bp," - ");
1097				}
1098			BN_print(bp,d);
1099			BIO_puts(bp,"\n");
1100			}
1101		BN_one(e);
1102		for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
1103		    BN_mul(e,e,a,ctx);
1104		BN_sub(e,e,d);
1105		if(!BN_is_zero(e))
1106		    {
1107		    fprintf(stderr,"Exponentiation test failed!\n");
1108		    return 0;
1109		    }
1110		}
1111	BN_free(a);
1112	BN_free(b);
1113	BN_free(d);
1114	BN_free(e);
1115	BN_free(one);
1116	return(1);
1117	}
1118#ifndef OPENSSL_NO_EC2M
1119int test_gf2m_add(BIO *bp)
1120	{
1121	BIGNUM a,b,c;
1122	int i, ret = 0;
1123
1124	BN_init(&a);
1125	BN_init(&b);
1126	BN_init(&c);
1127
1128	for (i=0; i<num0; i++)
1129		{
1130		BN_rand(&a,512,0,0);
1131		BN_copy(&b, BN_value_one());
1132		a.neg=rand_neg();
1133		b.neg=rand_neg();
1134		BN_GF2m_add(&c,&a,&b);
1135#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1136		if (bp != NULL)
1137			{
1138			if (!results)
1139				{
1140				BN_print(bp,&a);
1141				BIO_puts(bp," ^ ");
1142				BN_print(bp,&b);
1143				BIO_puts(bp," = ");
1144				}
1145			BN_print(bp,&c);
1146			BIO_puts(bp,"\n");
1147			}
1148#endif
1149		/* Test that two added values have the correct parity. */
1150		if((BN_is_odd(&a) && BN_is_odd(&c)) || (!BN_is_odd(&a) && !BN_is_odd(&c)))
1151			{
1152		    fprintf(stderr,"GF(2^m) addition test (a) failed!\n");
1153			goto err;
1154			}
1155		BN_GF2m_add(&c,&c,&c);
1156		/* Test that c + c = 0. */
1157		if(!BN_is_zero(&c))
1158		    {
1159		    fprintf(stderr,"GF(2^m) addition test (b) failed!\n");
1160			goto err;
1161		    }
1162		}
1163	ret = 1;
1164  err:
1165	BN_free(&a);
1166	BN_free(&b);
1167	BN_free(&c);
1168	return ret;
1169	}
1170
1171int test_gf2m_mod(BIO *bp)
1172	{
1173	BIGNUM *a,*b[2],*c,*d,*e;
1174	int i, j, ret = 0;
1175	int p0[] = {163,7,6,3,0,-1};
1176	int p1[] = {193,15,0,-1};
1177
1178	a=BN_new();
1179	b[0]=BN_new();
1180	b[1]=BN_new();
1181	c=BN_new();
1182	d=BN_new();
1183	e=BN_new();
1184
1185	BN_GF2m_arr2poly(p0, b[0]);
1186	BN_GF2m_arr2poly(p1, b[1]);
1187
1188	for (i=0; i<num0; i++)
1189		{
1190		BN_bntest_rand(a, 1024, 0, 0);
1191		for (j=0; j < 2; j++)
1192			{
1193			BN_GF2m_mod(c, a, b[j]);
1194#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1195			if (bp != NULL)
1196				{
1197				if (!results)
1198					{
1199					BN_print(bp,a);
1200					BIO_puts(bp," % ");
1201					BN_print(bp,b[j]);
1202					BIO_puts(bp," - ");
1203					BN_print(bp,c);
1204					BIO_puts(bp,"\n");
1205					}
1206				}
1207#endif
1208			BN_GF2m_add(d, a, c);
1209			BN_GF2m_mod(e, d, b[j]);
1210			/* Test that a + (a mod p) mod p == 0. */
1211			if(!BN_is_zero(e))
1212				{
1213				fprintf(stderr,"GF(2^m) modulo test failed!\n");
1214				goto err;
1215				}
1216			}
1217		}
1218	ret = 1;
1219  err:
1220	BN_free(a);
1221	BN_free(b[0]);
1222	BN_free(b[1]);
1223	BN_free(c);
1224	BN_free(d);
1225	BN_free(e);
1226	return ret;
1227	}
1228
1229int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx)
1230	{
1231	BIGNUM *a,*b[2],*c,*d,*e,*f,*g,*h;
1232	int i, j, ret = 0;
1233	int p0[] = {163,7,6,3,0,-1};
1234	int p1[] = {193,15,0,-1};
1235
1236	a=BN_new();
1237	b[0]=BN_new();
1238	b[1]=BN_new();
1239	c=BN_new();
1240	d=BN_new();
1241	e=BN_new();
1242	f=BN_new();
1243	g=BN_new();
1244	h=BN_new();
1245
1246	BN_GF2m_arr2poly(p0, b[0]);
1247	BN_GF2m_arr2poly(p1, b[1]);
1248
1249	for (i=0; i<num0; i++)
1250		{
1251		BN_bntest_rand(a, 1024, 0, 0);
1252		BN_bntest_rand(c, 1024, 0, 0);
1253		BN_bntest_rand(d, 1024, 0, 0);
1254		for (j=0; j < 2; j++)
1255			{
1256			BN_GF2m_mod_mul(e, a, c, b[j], ctx);
1257#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1258			if (bp != NULL)
1259				{
1260				if (!results)
1261					{
1262					BN_print(bp,a);
1263					BIO_puts(bp," * ");
1264					BN_print(bp,c);
1265					BIO_puts(bp," % ");
1266					BN_print(bp,b[j]);
1267					BIO_puts(bp," - ");
1268					BN_print(bp,e);
1269					BIO_puts(bp,"\n");
1270					}
1271				}
1272#endif
1273			BN_GF2m_add(f, a, d);
1274			BN_GF2m_mod_mul(g, f, c, b[j], ctx);
1275			BN_GF2m_mod_mul(h, d, c, b[j], ctx);
1276			BN_GF2m_add(f, e, g);
1277			BN_GF2m_add(f, f, h);
1278			/* Test that (a+d)*c = a*c + d*c. */
1279			if(!BN_is_zero(f))
1280				{
1281				fprintf(stderr,"GF(2^m) modular multiplication test failed!\n");
1282				goto err;
1283				}
1284			}
1285		}
1286	ret = 1;
1287  err:
1288	BN_free(a);
1289	BN_free(b[0]);
1290	BN_free(b[1]);
1291	BN_free(c);
1292	BN_free(d);
1293	BN_free(e);
1294	BN_free(f);
1295	BN_free(g);
1296	BN_free(h);
1297	return ret;
1298	}
1299
1300int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx)
1301	{
1302	BIGNUM *a,*b[2],*c,*d;
1303	int i, j, ret = 0;
1304	int p0[] = {163,7,6,3,0,-1};
1305	int p1[] = {193,15,0,-1};
1306
1307	a=BN_new();
1308	b[0]=BN_new();
1309	b[1]=BN_new();
1310	c=BN_new();
1311	d=BN_new();
1312
1313	BN_GF2m_arr2poly(p0, b[0]);
1314	BN_GF2m_arr2poly(p1, b[1]);
1315
1316	for (i=0; i<num0; i++)
1317		{
1318		BN_bntest_rand(a, 1024, 0, 0);
1319		for (j=0; j < 2; j++)
1320			{
1321			BN_GF2m_mod_sqr(c, a, b[j], ctx);
1322			BN_copy(d, a);
1323			BN_GF2m_mod_mul(d, a, d, b[j], ctx);
1324#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1325			if (bp != NULL)
1326				{
1327				if (!results)
1328					{
1329					BN_print(bp,a);
1330					BIO_puts(bp," ^ 2 % ");
1331					BN_print(bp,b[j]);
1332					BIO_puts(bp, " = ");
1333					BN_print(bp,c);
1334					BIO_puts(bp,"; a * a = ");
1335					BN_print(bp,d);
1336					BIO_puts(bp,"\n");
1337					}
1338				}
1339#endif
1340			BN_GF2m_add(d, c, d);
1341			/* Test that a*a = a^2. */
1342			if(!BN_is_zero(d))
1343				{
1344				fprintf(stderr,"GF(2^m) modular squaring test failed!\n");
1345				goto err;
1346				}
1347			}
1348		}
1349	ret = 1;
1350  err:
1351	BN_free(a);
1352	BN_free(b[0]);
1353	BN_free(b[1]);
1354	BN_free(c);
1355	BN_free(d);
1356	return ret;
1357	}
1358
1359int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx)
1360	{
1361	BIGNUM *a,*b[2],*c,*d;
1362	int i, j, ret = 0;
1363	int p0[] = {163,7,6,3,0,-1};
1364	int p1[] = {193,15,0,-1};
1365
1366	a=BN_new();
1367	b[0]=BN_new();
1368	b[1]=BN_new();
1369	c=BN_new();
1370	d=BN_new();
1371
1372	BN_GF2m_arr2poly(p0, b[0]);
1373	BN_GF2m_arr2poly(p1, b[1]);
1374
1375	for (i=0; i<num0; i++)
1376		{
1377		BN_bntest_rand(a, 512, 0, 0);
1378		for (j=0; j < 2; j++)
1379			{
1380			BN_GF2m_mod_inv(c, a, b[j], ctx);
1381			BN_GF2m_mod_mul(d, a, c, b[j], ctx);
1382#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1383			if (bp != NULL)
1384				{
1385				if (!results)
1386					{
1387					BN_print(bp,a);
1388					BIO_puts(bp, " * ");
1389					BN_print(bp,c);
1390					BIO_puts(bp," - 1 % ");
1391					BN_print(bp,b[j]);
1392					BIO_puts(bp,"\n");
1393					}
1394				}
1395#endif
1396			/* Test that ((1/a)*a) = 1. */
1397			if(!BN_is_one(d))
1398				{
1399				fprintf(stderr,"GF(2^m) modular inversion test failed!\n");
1400				goto err;
1401				}
1402			}
1403		}
1404	ret = 1;
1405  err:
1406	BN_free(a);
1407	BN_free(b[0]);
1408	BN_free(b[1]);
1409	BN_free(c);
1410	BN_free(d);
1411	return ret;
1412	}
1413
1414int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx)
1415	{
1416	BIGNUM *a,*b[2],*c,*d,*e,*f;
1417	int i, j, ret = 0;
1418	int p0[] = {163,7,6,3,0,-1};
1419	int p1[] = {193,15,0,-1};
1420
1421	a=BN_new();
1422	b[0]=BN_new();
1423	b[1]=BN_new();
1424	c=BN_new();
1425	d=BN_new();
1426	e=BN_new();
1427	f=BN_new();
1428
1429	BN_GF2m_arr2poly(p0, b[0]);
1430	BN_GF2m_arr2poly(p1, b[1]);
1431
1432	for (i=0; i<num0; i++)
1433		{
1434		BN_bntest_rand(a, 512, 0, 0);
1435		BN_bntest_rand(c, 512, 0, 0);
1436		for (j=0; j < 2; j++)
1437			{
1438			BN_GF2m_mod_div(d, a, c, b[j], ctx);
1439			BN_GF2m_mod_mul(e, d, c, b[j], ctx);
1440			BN_GF2m_mod_div(f, a, e, b[j], ctx);
1441#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1442			if (bp != NULL)
1443				{
1444				if (!results)
1445					{
1446					BN_print(bp,a);
1447					BIO_puts(bp, " = ");
1448					BN_print(bp,c);
1449					BIO_puts(bp," * ");
1450					BN_print(bp,d);
1451					BIO_puts(bp, " % ");
1452					BN_print(bp,b[j]);
1453					BIO_puts(bp,"\n");
1454					}
1455				}
1456#endif
1457			/* Test that ((a/c)*c)/a = 1. */
1458			if(!BN_is_one(f))
1459				{
1460				fprintf(stderr,"GF(2^m) modular division test failed!\n");
1461				goto err;
1462				}
1463			}
1464		}
1465	ret = 1;
1466  err:
1467	BN_free(a);
1468	BN_free(b[0]);
1469	BN_free(b[1]);
1470	BN_free(c);
1471	BN_free(d);
1472	BN_free(e);
1473	BN_free(f);
1474	return ret;
1475	}
1476
1477int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx)
1478	{
1479	BIGNUM *a,*b[2],*c,*d,*e,*f;
1480	int i, j, ret = 0;
1481	int p0[] = {163,7,6,3,0,-1};
1482	int p1[] = {193,15,0,-1};
1483
1484	a=BN_new();
1485	b[0]=BN_new();
1486	b[1]=BN_new();
1487	c=BN_new();
1488	d=BN_new();
1489	e=BN_new();
1490	f=BN_new();
1491
1492	BN_GF2m_arr2poly(p0, b[0]);
1493	BN_GF2m_arr2poly(p1, b[1]);
1494
1495	for (i=0; i<num0; i++)
1496		{
1497		BN_bntest_rand(a, 512, 0, 0);
1498		BN_bntest_rand(c, 512, 0, 0);
1499		BN_bntest_rand(d, 512, 0, 0);
1500		for (j=0; j < 2; j++)
1501			{
1502			BN_GF2m_mod_exp(e, a, c, b[j], ctx);
1503			BN_GF2m_mod_exp(f, a, d, b[j], ctx);
1504			BN_GF2m_mod_mul(e, e, f, b[j], ctx);
1505			BN_add(f, c, d);
1506			BN_GF2m_mod_exp(f, a, f, b[j], ctx);
1507#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1508			if (bp != NULL)
1509				{
1510				if (!results)
1511					{
1512					BN_print(bp,a);
1513					BIO_puts(bp, " ^ (");
1514					BN_print(bp,c);
1515					BIO_puts(bp," + ");
1516					BN_print(bp,d);
1517					BIO_puts(bp, ") = ");
1518					BN_print(bp,e);
1519					BIO_puts(bp, "; - ");
1520					BN_print(bp,f);
1521					BIO_puts(bp, " % ");
1522					BN_print(bp,b[j]);
1523					BIO_puts(bp,"\n");
1524					}
1525				}
1526#endif
1527			BN_GF2m_add(f, e, f);
1528			/* Test that a^(c+d)=a^c*a^d. */
1529			if(!BN_is_zero(f))
1530				{
1531				fprintf(stderr,"GF(2^m) modular exponentiation test failed!\n");
1532				goto err;
1533				}
1534			}
1535		}
1536	ret = 1;
1537  err:
1538	BN_free(a);
1539	BN_free(b[0]);
1540	BN_free(b[1]);
1541	BN_free(c);
1542	BN_free(d);
1543	BN_free(e);
1544	BN_free(f);
1545	return ret;
1546	}
1547
1548int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx)
1549	{
1550	BIGNUM *a,*b[2],*c,*d,*e,*f;
1551	int i, j, ret = 0;
1552	int p0[] = {163,7,6,3,0,-1};
1553	int p1[] = {193,15,0,-1};
1554
1555	a=BN_new();
1556	b[0]=BN_new();
1557	b[1]=BN_new();
1558	c=BN_new();
1559	d=BN_new();
1560	e=BN_new();
1561	f=BN_new();
1562
1563	BN_GF2m_arr2poly(p0, b[0]);
1564	BN_GF2m_arr2poly(p1, b[1]);
1565
1566	for (i=0; i<num0; i++)
1567		{
1568		BN_bntest_rand(a, 512, 0, 0);
1569		for (j=0; j < 2; j++)
1570			{
1571			BN_GF2m_mod(c, a, b[j]);
1572			BN_GF2m_mod_sqrt(d, a, b[j], ctx);
1573			BN_GF2m_mod_sqr(e, d, b[j], ctx);
1574#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1575			if (bp != NULL)
1576				{
1577				if (!results)
1578					{
1579					BN_print(bp,d);
1580					BIO_puts(bp, " ^ 2 - ");
1581					BN_print(bp,a);
1582					BIO_puts(bp,"\n");
1583					}
1584				}
1585#endif
1586			BN_GF2m_add(f, c, e);
1587			/* Test that d^2 = a, where d = sqrt(a). */
1588			if(!BN_is_zero(f))
1589				{
1590				fprintf(stderr,"GF(2^m) modular square root test failed!\n");
1591				goto err;
1592				}
1593			}
1594		}
1595	ret = 1;
1596  err:
1597	BN_free(a);
1598	BN_free(b[0]);
1599	BN_free(b[1]);
1600	BN_free(c);
1601	BN_free(d);
1602	BN_free(e);
1603	BN_free(f);
1604	return ret;
1605	}
1606
1607int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx)
1608	{
1609	BIGNUM *a,*b[2],*c,*d,*e;
1610	int i, j, s = 0, t, ret = 0;
1611	int p0[] = {163,7,6,3,0,-1};
1612	int p1[] = {193,15,0,-1};
1613
1614	a=BN_new();
1615	b[0]=BN_new();
1616	b[1]=BN_new();
1617	c=BN_new();
1618	d=BN_new();
1619	e=BN_new();
1620
1621	BN_GF2m_arr2poly(p0, b[0]);
1622	BN_GF2m_arr2poly(p1, b[1]);
1623
1624	for (i=0; i<num0; i++)
1625		{
1626		BN_bntest_rand(a, 512, 0, 0);
1627		for (j=0; j < 2; j++)
1628			{
1629			t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
1630			if (t)
1631				{
1632				s++;
1633				BN_GF2m_mod_sqr(d, c, b[j], ctx);
1634				BN_GF2m_add(d, c, d);
1635				BN_GF2m_mod(e, a, b[j]);
1636#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1637				if (bp != NULL)
1638					{
1639					if (!results)
1640						{
1641						BN_print(bp,c);
1642						BIO_puts(bp, " is root of z^2 + z = ");
1643						BN_print(bp,a);
1644						BIO_puts(bp, " % ");
1645						BN_print(bp,b[j]);
1646						BIO_puts(bp, "\n");
1647						}
1648					}
1649#endif
1650				BN_GF2m_add(e, e, d);
1651				/* Test that solution of quadratic c satisfies c^2 + c = a. */
1652				if(!BN_is_zero(e))
1653					{
1654					fprintf(stderr,"GF(2^m) modular solve quadratic test failed!\n");
1655					goto err;
1656					}
1657
1658				}
1659			else
1660				{
1661#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1662				if (bp != NULL)
1663					{
1664					if (!results)
1665						{
1666						BIO_puts(bp, "There are no roots of z^2 + z = ");
1667						BN_print(bp,a);
1668						BIO_puts(bp, " % ");
1669						BN_print(bp,b[j]);
1670						BIO_puts(bp, "\n");
1671						}
1672					}
1673#endif
1674				}
1675			}
1676		}
1677	if (s == 0)
1678		{
1679		fprintf(stderr,"All %i tests of GF(2^m) modular solve quadratic resulted in no roots;\n", num0);
1680		fprintf(stderr,"this is very unlikely and probably indicates an error.\n");
1681		goto err;
1682		}
1683	ret = 1;
1684  err:
1685	BN_free(a);
1686	BN_free(b[0]);
1687	BN_free(b[1]);
1688	BN_free(c);
1689	BN_free(d);
1690	BN_free(e);
1691	return ret;
1692	}
1693#endif
1694static int genprime_cb(int p, int n, BN_GENCB *arg)
1695	{
1696	char c='*';
1697
1698	if (p == 0) c='.';
1699	if (p == 1) c='+';
1700	if (p == 2) c='*';
1701	if (p == 3) c='\n';
1702	putc(c, stderr);
1703	fflush(stderr);
1704	return 1;
1705	}
1706
1707int test_kron(BIO *bp, BN_CTX *ctx)
1708	{
1709	BN_GENCB cb;
1710	BIGNUM *a,*b,*r,*t;
1711	int i;
1712	int legendre, kronecker;
1713	int ret = 0;
1714
1715	a = BN_new();
1716	b = BN_new();
1717	r = BN_new();
1718	t = BN_new();
1719	if (a == NULL || b == NULL || r == NULL || t == NULL) goto err;
1720
1721	BN_GENCB_set(&cb, genprime_cb, NULL);
1722
1723	/* We test BN_kronecker(a, b, ctx) just for  b  odd (Jacobi symbol).
1724	 * In this case we know that if  b  is prime, then BN_kronecker(a, b, ctx)
1725	 * is congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol).
1726	 * So we generate a random prime  b  and compare these values
1727	 * for a number of random  a's.  (That is, we run the Solovay-Strassen
1728	 * primality test to confirm that  b  is prime, except that we
1729	 * don't want to test whether  b  is prime but whether BN_kronecker
1730	 * works.) */
1731
1732	if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, &cb)) goto err;
1733	b->neg = rand_neg();
1734	putc('\n', stderr);
1735
1736	for (i = 0; i < num0; i++)
1737		{
1738		if (!BN_bntest_rand(a, 512, 0, 0)) goto err;
1739		a->neg = rand_neg();
1740
1741		/* t := (|b|-1)/2  (note that b is odd) */
1742		if (!BN_copy(t, b)) goto err;
1743		t->neg = 0;
1744		if (!BN_sub_word(t, 1)) goto err;
1745		if (!BN_rshift1(t, t)) goto err;
1746		/* r := a^t mod b */
1747		b->neg=0;
1748
1749		if (!BN_mod_exp_recp(r, a, t, b, ctx)) goto err;
1750		b->neg=1;
1751
1752		if (BN_is_word(r, 1))
1753			legendre = 1;
1754		else if (BN_is_zero(r))
1755			legendre = 0;
1756		else
1757			{
1758			if (!BN_add_word(r, 1)) goto err;
1759			if (0 != BN_ucmp(r, b))
1760				{
1761				fprintf(stderr, "Legendre symbol computation failed\n");
1762				goto err;
1763				}
1764			legendre = -1;
1765			}
1766
1767		kronecker = BN_kronecker(a, b, ctx);
1768		if (kronecker < -1) goto err;
1769		/* we actually need BN_kronecker(a, |b|) */
1770		if (a->neg && b->neg)
1771			kronecker = -kronecker;
1772
1773		if (legendre != kronecker)
1774			{
1775			fprintf(stderr, "legendre != kronecker; a = ");
1776			BN_print_fp(stderr, a);
1777			fprintf(stderr, ", b = ");
1778			BN_print_fp(stderr, b);
1779			fprintf(stderr, "\n");
1780			goto err;
1781			}
1782
1783		putc('.', stderr);
1784		fflush(stderr);
1785		}
1786
1787	putc('\n', stderr);
1788	fflush(stderr);
1789	ret = 1;
1790 err:
1791	if (a != NULL) BN_free(a);
1792	if (b != NULL) BN_free(b);
1793	if (r != NULL) BN_free(r);
1794	if (t != NULL) BN_free(t);
1795	return ret;
1796	}
1797
1798int test_sqrt(BIO *bp, BN_CTX *ctx)
1799	{
1800	BN_GENCB cb;
1801	BIGNUM *a,*p,*r;
1802	int i, j;
1803	int ret = 0;
1804
1805	a = BN_new();
1806	p = BN_new();
1807	r = BN_new();
1808	if (a == NULL || p == NULL || r == NULL) goto err;
1809
1810	BN_GENCB_set(&cb, genprime_cb, NULL);
1811
1812	for (i = 0; i < 16; i++)
1813		{
1814		if (i < 8)
1815			{
1816			unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
1817
1818			if (!BN_set_word(p, primes[i])) goto err;
1819			}
1820		else
1821			{
1822			if (!BN_set_word(a, 32)) goto err;
1823			if (!BN_set_word(r, 2*i + 1)) goto err;
1824
1825			if (!BN_generate_prime_ex(p, 256, 0, a, r, &cb)) goto err;
1826			putc('\n', stderr);
1827			}
1828		p->neg = rand_neg();
1829
1830		for (j = 0; j < num2; j++)
1831			{
1832			/* construct 'a' such that it is a square modulo p,
1833			 * but in general not a proper square and not reduced modulo p */
1834			if (!BN_bntest_rand(r, 256, 0, 3)) goto err;
1835			if (!BN_nnmod(r, r, p, ctx)) goto err;
1836			if (!BN_mod_sqr(r, r, p, ctx)) goto err;
1837			if (!BN_bntest_rand(a, 256, 0, 3)) goto err;
1838			if (!BN_nnmod(a, a, p, ctx)) goto err;
1839			if (!BN_mod_sqr(a, a, p, ctx)) goto err;
1840			if (!BN_mul(a, a, r, ctx)) goto err;
1841			if (rand_neg())
1842				if (!BN_sub(a, a, p)) goto err;
1843
1844			if (!BN_mod_sqrt(r, a, p, ctx)) goto err;
1845			if (!BN_mod_sqr(r, r, p, ctx)) goto err;
1846
1847			if (!BN_nnmod(a, a, p, ctx)) goto err;
1848
1849			if (BN_cmp(a, r) != 0)
1850				{
1851				fprintf(stderr, "BN_mod_sqrt failed: a = ");
1852				BN_print_fp(stderr, a);
1853				fprintf(stderr, ", r = ");
1854				BN_print_fp(stderr, r);
1855				fprintf(stderr, ", p = ");
1856				BN_print_fp(stderr, p);
1857				fprintf(stderr, "\n");
1858				goto err;
1859				}
1860
1861			putc('.', stderr);
1862			fflush(stderr);
1863			}
1864
1865		putc('\n', stderr);
1866		fflush(stderr);
1867		}
1868	ret = 1;
1869 err:
1870	if (a != NULL) BN_free(a);
1871	if (p != NULL) BN_free(p);
1872	if (r != NULL) BN_free(r);
1873	return ret;
1874	}
1875
1876int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
1877	{
1878	BIGNUM *a,*b,*c,*d;
1879	int i;
1880
1881	b=BN_new();
1882	c=BN_new();
1883	d=BN_new();
1884	BN_one(c);
1885
1886	if(a_)
1887	    a=a_;
1888	else
1889	    {
1890	    a=BN_new();
1891	    BN_bntest_rand(a,200,0,0); /**/
1892	    a->neg=rand_neg();
1893	    }
1894	for (i=0; i<num0; i++)
1895		{
1896		BN_lshift(b,a,i+1);
1897		BN_add(c,c,c);
1898		if (bp != NULL)
1899			{
1900			if (!results)
1901				{
1902				BN_print(bp,a);
1903				BIO_puts(bp," * ");
1904				BN_print(bp,c);
1905				BIO_puts(bp," - ");
1906				}
1907			BN_print(bp,b);
1908			BIO_puts(bp,"\n");
1909			}
1910		BN_mul(d,a,c,ctx);
1911		BN_sub(d,d,b);
1912		if(!BN_is_zero(d))
1913		    {
1914		    fprintf(stderr,"Left shift test failed!\n");
1915		    fprintf(stderr,"a=");
1916		    BN_print_fp(stderr,a);
1917		    fprintf(stderr,"\nb=");
1918		    BN_print_fp(stderr,b);
1919		    fprintf(stderr,"\nc=");
1920		    BN_print_fp(stderr,c);
1921		    fprintf(stderr,"\nd=");
1922		    BN_print_fp(stderr,d);
1923		    fprintf(stderr,"\n");
1924		    return 0;
1925		    }
1926		}
1927	BN_free(a);
1928	BN_free(b);
1929	BN_free(c);
1930	BN_free(d);
1931	return(1);
1932	}
1933
1934int test_lshift1(BIO *bp)
1935	{
1936	BIGNUM *a,*b,*c;
1937	int i;
1938
1939	a=BN_new();
1940	b=BN_new();
1941	c=BN_new();
1942
1943	BN_bntest_rand(a,200,0,0); /**/
1944	a->neg=rand_neg();
1945	for (i=0; i<num0; i++)
1946		{
1947		BN_lshift1(b,a);
1948		if (bp != NULL)
1949			{
1950			if (!results)
1951				{
1952				BN_print(bp,a);
1953				BIO_puts(bp," * 2");
1954				BIO_puts(bp," - ");
1955				}
1956			BN_print(bp,b);
1957			BIO_puts(bp,"\n");
1958			}
1959		BN_add(c,a,a);
1960		BN_sub(a,b,c);
1961		if(!BN_is_zero(a))
1962		    {
1963		    fprintf(stderr,"Left shift one test failed!\n");
1964		    return 0;
1965		    }
1966
1967		BN_copy(a,b);
1968		}
1969	BN_free(a);
1970	BN_free(b);
1971	BN_free(c);
1972	return(1);
1973	}
1974
1975int test_rshift(BIO *bp,BN_CTX *ctx)
1976	{
1977	BIGNUM *a,*b,*c,*d,*e;
1978	int i;
1979
1980	a=BN_new();
1981	b=BN_new();
1982	c=BN_new();
1983	d=BN_new();
1984	e=BN_new();
1985	BN_one(c);
1986
1987	BN_bntest_rand(a,200,0,0); /**/
1988	a->neg=rand_neg();
1989	for (i=0; i<num0; i++)
1990		{
1991		BN_rshift(b,a,i+1);
1992		BN_add(c,c,c);
1993		if (bp != NULL)
1994			{
1995			if (!results)
1996				{
1997				BN_print(bp,a);
1998				BIO_puts(bp," / ");
1999				BN_print(bp,c);
2000				BIO_puts(bp," - ");
2001				}
2002			BN_print(bp,b);
2003			BIO_puts(bp,"\n");
2004			}
2005		BN_div(d,e,a,c,ctx);
2006		BN_sub(d,d,b);
2007		if(!BN_is_zero(d))
2008		    {
2009		    fprintf(stderr,"Right shift test failed!\n");
2010		    return 0;
2011		    }
2012		}
2013	BN_free(a);
2014	BN_free(b);
2015	BN_free(c);
2016	BN_free(d);
2017	BN_free(e);
2018	return(1);
2019	}
2020
2021int test_rshift1(BIO *bp)
2022	{
2023	BIGNUM *a,*b,*c;
2024	int i;
2025
2026	a=BN_new();
2027	b=BN_new();
2028	c=BN_new();
2029
2030	BN_bntest_rand(a,200,0,0); /**/
2031	a->neg=rand_neg();
2032	for (i=0; i<num0; i++)
2033		{
2034		BN_rshift1(b,a);
2035		if (bp != NULL)
2036			{
2037			if (!results)
2038				{
2039				BN_print(bp,a);
2040				BIO_puts(bp," / 2");
2041				BIO_puts(bp," - ");
2042				}
2043			BN_print(bp,b);
2044			BIO_puts(bp,"\n");
2045			}
2046		BN_sub(c,a,b);
2047		BN_sub(c,c,b);
2048		if(!BN_is_zero(c) && !BN_abs_is_word(c, 1))
2049		    {
2050		    fprintf(stderr,"Right shift one test failed!\n");
2051		    return 0;
2052		    }
2053		BN_copy(a,b);
2054		}
2055	BN_free(a);
2056	BN_free(b);
2057	BN_free(c);
2058	return(1);
2059	}
2060
2061int rand_neg(void)
2062	{
2063	static unsigned int neg=0;
2064	static int sign[8]={0,0,0,1,1,0,1,1};
2065
2066	return(sign[(neg++)%8]);
2067	}
2068