1/*
2 * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19/* crypto/bn/bntest.c */
20/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
21 * All rights reserved.
22 *
23 * This package is an SSL implementation written
24 * by Eric Young (eay@cryptsoft.com).
25 * The implementation was written so as to conform with Netscapes SSL.
26 *
27 * This library is free for commercial and non-commercial use as long as
28 * the following conditions are aheared to.  The following conditions
29 * apply to all code found in this distribution, be it the RC4, RSA,
30 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
31 * included with this distribution is covered by the same copyright terms
32 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
33 *
34 * Copyright remains Eric Young's, and as such any Copyright notices in
35 * the code are not to be removed.
36 * If this package is used in a product, Eric Young should be given attribution
37 * as the author of the parts of the library used.
38 * This can be in the form of a textual message at program startup or
39 * in documentation (online or textual) provided with the package.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the copyright
45 *    notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 *    notice, this list of conditions and the following disclaimer in the
48 *    documentation and/or other materials provided with the distribution.
49 * 3. All advertising materials mentioning features or use of this software
50 *    must display the following acknowledgement:
51 *    "This product includes cryptographic software written by
52 *     Eric Young (eay@cryptsoft.com)"
53 *    The word 'cryptographic' can be left out if the rouines from the library
54 *    being used are not cryptographic related :-).
55 * 4. If you include any Windows specific code (or a derivative thereof) from
56 *    the apps directory (application code) you must include an acknowledgement:
57 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
58 *
59 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * SUCH DAMAGE.
70 *
71 * The licence and distribution terms for any publically available version or
72 * derivative of this code cannot be changed.  i.e. this code cannot simply be
73 * copied and put under another distribution licence
74 * [including the GNU Public Licence.]
75 */
76
77#include <stdio.h>
78#include <stdlib.h>
79#include <string.h>
80
81#include "openssl/e_os.h"
82
83#include <openssl/bio.h>
84#include <openssl/bn.h>
85#include <openssl/rand.h>
86#include <openssl/x509.h>
87#include <openssl/err.h>
88
89#ifdef WINDOWS
90#include "../bio/bss_file.c"
91#endif
92
93const int num0 = 100; /* number of tests */
94const int num1 = 50;  /* additional tests for some functions */
95const int num2 = 5;   /* number of tests for slow functions */
96
97int test_add(BIO *bp);
98int test_sub(BIO *bp);
99int test_lshift1(BIO *bp);
100int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
101int test_rshift1(BIO *bp);
102int test_rshift(BIO *bp,BN_CTX *ctx);
103int test_div(BIO *bp,BN_CTX *ctx);
104int test_div_recp(BIO *bp,BN_CTX *ctx);
105int test_mul(BIO *bp);
106int test_sqr(BIO *bp,BN_CTX *ctx);
107int test_mont(BIO *bp,BN_CTX *ctx);
108int test_mod(BIO *bp,BN_CTX *ctx);
109int test_mod_mul(BIO *bp,BN_CTX *ctx);
110int test_mod_exp(BIO *bp,BN_CTX *ctx);
111int test_exp(BIO *bp,BN_CTX *ctx);
112int rand_neg(void);
113static int results=0;
114
115#ifdef NO_STDIO
116#define APPS_WIN16
117#include "bss_file.c"
118#endif
119
120static unsigned char lst[]="\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
121"\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
122
123static const char rnd_seed[] = "string to make the random number generator think it has entropy";
124
125static void message(BIO *out, char *m)
126	{
127	fprintf(stderr, "test %s\n", m);
128#if defined(linux) || defined(__FreeBSD__) /* can we use GNU bc features? */
129	BIO_puts(out, "print \"test ");
130	BIO_puts(out, m);
131	BIO_puts(out, "\\n\"\n");
132#endif
133	}
134
135int main(int argc, char *argv[])
136	{
137	BN_CTX *ctx;
138	BIO *out;
139	char *outfile=NULL;
140
141	results = 0;
142
143	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we don't
144	                                       * even check its return value
145	                                       * (which we should) */
146
147	argc--;
148	argv++;
149	while (argc >= 1)
150		{
151		if (strcmp(*argv,"-results") == 0)
152			results=1;
153		else if (strcmp(*argv,"-out") == 0)
154			{
155			if (--argc < 1) break;
156			outfile= *(++argv);
157			}
158		argc--;
159		argv++;
160		}
161
162
163	ctx=BN_CTX_new();
164	if (ctx == NULL) exit(1);
165
166	out=BIO_new(BIO_s_file());
167	if (out == NULL) exit(1);
168	if (outfile == NULL)
169		{
170		BIO_set_fp(out,stdout,BIO_NOCLOSE);
171		}
172	else
173		{
174		if (!BIO_write_filename(out,outfile))
175			{
176			perror(outfile);
177			exit(1);
178			}
179		}
180
181	if (!results)
182		BIO_puts(out,"obase=16\nibase=16\n");
183
184	message(out,"BN_add");
185	if (!test_add(out)) goto err;
186	BIO_flush(out);
187
188	message(out,"BN_sub");
189	if (!test_sub(out)) goto err;
190	BIO_flush(out);
191
192	message(out,"BN_lshift1");
193	if (!test_lshift1(out)) goto err;
194	BIO_flush(out);
195
196	message(out,"BN_lshift (fixed)");
197	if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
198	    goto err;
199	BIO_flush(out);
200
201	message(out,"BN_lshift");
202	if (!test_lshift(out,ctx,NULL)) goto err;
203	BIO_flush(out);
204
205	message(out,"BN_rshift1");
206	if (!test_rshift1(out)) goto err;
207	BIO_flush(out);
208
209	message(out,"BN_rshift");
210	if (!test_rshift(out,ctx)) goto err;
211	BIO_flush(out);
212
213	message(out,"BN_sqr");
214	if (!test_sqr(out,ctx)) goto err;
215	BIO_flush(out);
216
217	message(out,"BN_mul");
218	if (!test_mul(out)) goto err;
219	BIO_flush(out);
220
221	message(out,"BN_div");
222	if (!test_div(out,ctx)) goto err;
223	BIO_flush(out);
224
225	message(out,"BN_div_recp");
226	if (!test_div_recp(out,ctx)) goto err;
227	BIO_flush(out);
228
229	message(out,"BN_mod");
230	if (!test_mod(out,ctx)) goto err;
231	BIO_flush(out);
232
233	message(out,"BN_mod_mul");
234	if (!test_mod_mul(out,ctx)) goto err;
235	BIO_flush(out);
236
237	message(out,"BN_mont");
238	if (!test_mont(out,ctx)) goto err;
239	BIO_flush(out);
240
241	message(out,"BN_mod_exp");
242	if (!test_mod_exp(out,ctx)) goto err;
243	BIO_flush(out);
244
245	message(out,"BN_exp");
246	if (!test_exp(out,ctx)) goto err;
247	BIO_flush(out);
248
249	BN_CTX_free(ctx);
250	BIO_free(out);
251
252/**/
253	exit(0);
254err:
255	BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices
256	                      * the failure, see test_bn in test/Makefile.ssl*/
257	BIO_flush(out);
258	ERR_load_crypto_strings();
259	ERR_print_errors_fp(stderr);
260	exit(1);
261	return(1);
262	}
263
264int test_add(BIO *bp)
265	{
266	BIGNUM a,b,c;
267	int i;
268	int j;
269
270	BN_init(&a);
271	BN_init(&b);
272	BN_init(&c);
273
274	BN_rand(&a,512,0,0);
275	for (i=0; i<num0; i++)
276		{
277		BN_rand(&b,450+i,0,0);
278		a.neg=rand_neg();
279		b.neg=rand_neg();
280		if (bp == NULL)
281			for (j=0; j<10000; j++)
282				BN_add(&c,&a,&b);
283		BN_add(&c,&a,&b);
284		if (bp != NULL)
285			{
286			if (!results)
287				{
288				BN_print(bp,&a);
289				BIO_puts(bp," + ");
290				BN_print(bp,&b);
291				BIO_puts(bp," - ");
292				}
293			BN_print(bp,&c);
294			BIO_puts(bp,"\n");
295			}
296		a.neg=!a.neg;
297		b.neg=!b.neg;
298		BN_add(&c,&c,&b);
299		BN_add(&c,&c,&a);
300		if(!BN_is_zero(&c))
301		    {
302		    fprintf(stderr,"Add test failed!\n");
303		    return 0;
304		    }
305		}
306	BN_free(&a);
307	BN_free(&b);
308	BN_free(&c);
309	return(1);
310	}
311
312int test_sub(BIO *bp)
313	{
314	BIGNUM a,b,c;
315	int i;
316	int j;
317
318	BN_init(&a);
319	BN_init(&b);
320	BN_init(&c);
321
322	for (i=0; i<num0+num1; i++)
323		{
324		if (i < num1)
325			{
326			BN_rand(&a,512,0,0);
327			BN_copy(&b,&a);
328			if (BN_set_bit(&a,i)==0) return(0);
329			BN_add_word(&b,i);
330			}
331		else
332			{
333			BN_rand(&b,400+i-num1,0,0);
334			a.neg=rand_neg();
335			b.neg=rand_neg();
336			}
337		if (bp == NULL)
338			for (j=0; j<10000; j++)
339				BN_sub(&c,&a,&b);
340		BN_sub(&c,&a,&b);
341		if (bp != NULL)
342			{
343			if (!results)
344				{
345				BN_print(bp,&a);
346				BIO_puts(bp," - ");
347				BN_print(bp,&b);
348				BIO_puts(bp," - ");
349				}
350			BN_print(bp,&c);
351			BIO_puts(bp,"\n");
352			}
353		BN_add(&c,&c,&b);
354		BN_sub(&c,&c,&a);
355		if(!BN_is_zero(&c))
356		    {
357		    fprintf(stderr,"Subtract test failed!\n");
358		    return 0;
359		    }
360		}
361	BN_free(&a);
362	BN_free(&b);
363	BN_free(&c);
364	return(1);
365	}
366
367int test_div(BIO *bp, BN_CTX *ctx)
368	{
369	BIGNUM a,b,c,d,e;
370	int i;
371	int j;
372
373	BN_init(&a);
374	BN_init(&b);
375	BN_init(&c);
376	BN_init(&d);
377	BN_init(&e);
378
379	for (i=0; i<num0+num1; i++)
380		{
381		if (i < num1)
382			{
383			BN_rand(&a,400,0,0);
384			BN_copy(&b,&a);
385			BN_lshift(&a,&a,i);
386			BN_add_word(&a,i);
387			}
388		else
389			BN_rand(&b,50+3*(i-num1),0,0);
390		a.neg=rand_neg();
391		b.neg=rand_neg();
392		if (bp == NULL)
393			for (j=0; j<100; j++)
394				BN_div(&d,&c,&a,&b,ctx);
395		BN_div(&d,&c,&a,&b,ctx);
396		if (bp != NULL)
397			{
398			if (!results)
399				{
400				BN_print(bp,&a);
401				BIO_puts(bp," / ");
402				BN_print(bp,&b);
403				BIO_puts(bp," - ");
404				}
405			BN_print(bp,&d);
406			BIO_puts(bp,"\n");
407
408			if (!results)
409				{
410				BN_print(bp,&a);
411				BIO_puts(bp," % ");
412				BN_print(bp,&b);
413				BIO_puts(bp," - ");
414				}
415			BN_print(bp,&c);
416			BIO_puts(bp,"\n");
417			}
418		BN_mul(&e,&d,&b,ctx);
419		BN_add(&d,&e,&c);
420		BN_sub(&d,&d,&a);
421		if(!BN_is_zero(&d))
422		    {
423		    fprintf(stderr,"Division test failed!\n");
424		    return 0;
425		    }
426		}
427	BN_free(&a);
428	BN_free(&b);
429	BN_free(&c);
430	BN_free(&d);
431	BN_free(&e);
432	return(1);
433	}
434
435int test_div_recp(BIO *bp, BN_CTX *ctx)
436	{
437	BIGNUM a,b,c,d,e;
438	BN_RECP_CTX recp;
439	int i;
440	int j;
441
442	BN_RECP_CTX_init(&recp);
443	BN_init(&a);
444	BN_init(&b);
445	BN_init(&c);
446	BN_init(&d);
447	BN_init(&e);
448
449	for (i=0; i<num0+num1; i++)
450		{
451		if (i < num1)
452			{
453			BN_rand(&a,400,0,0);
454			BN_copy(&b,&a);
455			BN_lshift(&a,&a,i);
456			BN_add_word(&a,i);
457			}
458		else
459			BN_rand(&b,50+3*(i-num1),0,0);
460		a.neg=rand_neg();
461		b.neg=rand_neg();
462		BN_RECP_CTX_set(&recp,&b,ctx);
463		if (bp == NULL)
464			for (j=0; j<100; j++)
465				BN_div_recp(&d,&c,&a,&recp,ctx);
466		BN_div_recp(&d,&c,&a,&recp,ctx);
467		if (bp != NULL)
468			{
469			if (!results)
470				{
471				BN_print(bp,&a);
472				BIO_puts(bp," / ");
473				BN_print(bp,&b);
474				BIO_puts(bp," - ");
475				}
476			BN_print(bp,&d);
477			BIO_puts(bp,"\n");
478
479			if (!results)
480				{
481				BN_print(bp,&a);
482				BIO_puts(bp," % ");
483				BN_print(bp,&b);
484				BIO_puts(bp," - ");
485				}
486			BN_print(bp,&c);
487			BIO_puts(bp,"\n");
488			}
489		BN_mul(&e,&d,&b,ctx);
490		BN_add(&d,&e,&c);
491		BN_sub(&d,&d,&a);
492		if(!BN_is_zero(&d))
493		    {
494		    fprintf(stderr,"Reciprocal division test failed!\n");
495		    fprintf(stderr,"a=");
496		    BN_print_fp(stderr,&a);
497		    fprintf(stderr,"\nb=");
498		    BN_print_fp(stderr,&b);
499		    fprintf(stderr,"\n");
500		    return 0;
501		    }
502		}
503	BN_free(&a);
504	BN_free(&b);
505	BN_free(&c);
506	BN_free(&d);
507	BN_free(&e);
508	BN_RECP_CTX_free(&recp);
509	return(1);
510	}
511
512int test_mul(BIO *bp)
513	{
514	BIGNUM a,b,c,d,e;
515	int i;
516	int j;
517	BN_CTX ctx;
518
519	BN_CTX_init(&ctx);
520	BN_init(&a);
521	BN_init(&b);
522	BN_init(&c);
523	BN_init(&d);
524	BN_init(&e);
525
526	for (i=0; i<num0+num1; i++)
527		{
528		if (i <= num1)
529			{
530			BN_rand(&a,100,0,0);
531			BN_rand(&b,100,0,0);
532			}
533		else
534			BN_rand(&b,i-num1,0,0);
535		a.neg=rand_neg();
536		b.neg=rand_neg();
537		if (bp == NULL)
538			for (j=0; j<100; j++)
539				BN_mul(&c,&a,&b,&ctx);
540		BN_mul(&c,&a,&b,&ctx);
541		if (bp != NULL)
542			{
543			if (!results)
544				{
545				BN_print(bp,&a);
546				BIO_puts(bp," * ");
547				BN_print(bp,&b);
548				BIO_puts(bp," - ");
549				}
550			BN_print(bp,&c);
551			BIO_puts(bp,"\n");
552			}
553		BN_div(&d,&e,&c,&a,&ctx);
554		BN_sub(&d,&d,&b);
555		if(!BN_is_zero(&d) || !BN_is_zero(&e))
556		    {
557		    fprintf(stderr,"Multiplication test failed!\n");
558		    return 0;
559		    }
560		}
561	BN_free(&a);
562	BN_free(&b);
563	BN_free(&c);
564	BN_free(&d);
565	BN_free(&e);
566	BN_CTX_free(&ctx);
567	return(1);
568	}
569
570int test_sqr(BIO *bp, BN_CTX *ctx)
571	{
572	BIGNUM a,c,d,e;
573	int i;
574	int j;
575
576	BN_init(&a);
577	BN_init(&c);
578	BN_init(&d);
579	BN_init(&e);
580
581	for (i=0; i<num0; i++)
582		{
583		BN_rand(&a,40+i*10,0,0);
584		a.neg=rand_neg();
585		if (bp == NULL)
586			for (j=0; j<100; j++)
587				BN_sqr(&c,&a,ctx);
588		BN_sqr(&c,&a,ctx);
589		if (bp != NULL)
590			{
591			if (!results)
592				{
593				BN_print(bp,&a);
594				BIO_puts(bp," * ");
595				BN_print(bp,&a);
596				BIO_puts(bp," - ");
597				}
598			BN_print(bp,&c);
599			BIO_puts(bp,"\n");
600			}
601		BN_div(&d,&e,&c,&a,ctx);
602		BN_sub(&d,&d,&a);
603		if(!BN_is_zero(&d) || !BN_is_zero(&e))
604		    {
605		    fprintf(stderr,"Square test failed!\n");
606		    return 0;
607		    }
608		}
609	BN_free(&a);
610	BN_free(&c);
611	BN_free(&d);
612	BN_free(&e);
613	return(1);
614	}
615
616int test_mont(BIO *bp, BN_CTX *ctx)
617	{
618	BIGNUM a,b,c,d,A,B;
619	BIGNUM n;
620	int i;
621	int j;
622	BN_MONT_CTX *mont;
623
624	BN_init(&a);
625	BN_init(&b);
626	BN_init(&c);
627	BN_init(&d);
628	BN_init(&A);
629	BN_init(&B);
630	BN_init(&n);
631
632	mont=BN_MONT_CTX_new();
633
634	BN_rand(&a,100,0,0); /**/
635	BN_rand(&b,100,0,0); /**/
636	for (i=0; i<num2; i++)
637		{
638		int bits = (200*(i+1))/num2;
639
640		if (bits == 0)
641			continue;
642		BN_rand(&n,bits,0,1);
643		BN_MONT_CTX_set(mont,&n,ctx);
644
645		BN_to_montgomery(&A,&a,mont,ctx);
646		BN_to_montgomery(&B,&b,mont,ctx);
647
648		if (bp == NULL)
649			for (j=0; j<100; j++)
650				BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
651		BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
652		BN_from_montgomery(&A,&c,mont,ctx);/**/
653		if (bp != NULL)
654			{
655			if (!results)
656				{
657#ifdef undef
658fprintf(stderr,"%d * %d %% %d\n",
659BN_num_bits(&a),
660BN_num_bits(&b),
661BN_num_bits(mont->N));
662#endif
663				BN_print(bp,&a);
664				BIO_puts(bp," * ");
665				BN_print(bp,&b);
666				BIO_puts(bp," % ");
667				BN_print(bp,&(mont->N));
668				BIO_puts(bp," - ");
669				}
670			BN_print(bp,&A);
671			BIO_puts(bp,"\n");
672			}
673		BN_mod_mul(&d,&a,&b,&n,ctx);
674		BN_sub(&d,&d,&A);
675		if(!BN_is_zero(&d))
676		    {
677		    fprintf(stderr,"Montgomery multiplication test failed!\n");
678		    return 0;
679		    }
680		}
681	BN_MONT_CTX_free(mont);
682	BN_free(&a);
683	BN_free(&b);
684	BN_free(&c);
685	BN_free(&d);
686	BN_free(&A);
687	BN_free(&B);
688	BN_free(&n);
689	return(1);
690	}
691
692int test_mod(BIO *bp, BN_CTX *ctx)
693	{
694	BIGNUM *a,*b,*c,*d,*e;
695	int i;
696	int j;
697
698	a=BN_new();
699	b=BN_new();
700	c=BN_new();
701	d=BN_new();
702	e=BN_new();
703
704	BN_rand(a,1024,0,0); /**/
705	for (i=0; i<num0; i++)
706		{
707		BN_rand(b,450+i*10,0,0); /**/
708		a->neg=rand_neg();
709		b->neg=rand_neg();
710		if (bp == NULL)
711			for (j=0; j<100; j++)
712				BN_mod(c,a,b,ctx);/**/
713		BN_mod(c,a,b,ctx);/**/
714		if (bp != NULL)
715			{
716			if (!results)
717				{
718				BN_print(bp,a);
719				BIO_puts(bp," % ");
720				BN_print(bp,b);
721				BIO_puts(bp," - ");
722				}
723			BN_print(bp,c);
724			BIO_puts(bp,"\n");
725			}
726		BN_div(d,e,a,b,ctx);
727		BN_sub(e,e,c);
728		if(!BN_is_zero(e))
729		    {
730		    fprintf(stderr,"Modulo test failed!\n");
731		    return 0;
732		    }
733		}
734	BN_free(a);
735	BN_free(b);
736	BN_free(c);
737	BN_free(d);
738	BN_free(e);
739	return(1);
740	}
741
742int test_mod_mul(BIO *bp, BN_CTX *ctx)
743	{
744	BIGNUM *a,*b,*c,*d,*e;
745	int i;
746
747	a=BN_new();
748	b=BN_new();
749	c=BN_new();
750	d=BN_new();
751	e=BN_new();
752
753	BN_rand(c,1024,0,0); /**/
754	for (i=0; i<num0; i++)
755		{
756		BN_rand(a,475+i*10,0,0); /**/
757		BN_rand(b,425+i*11,0,0); /**/
758		a->neg=rand_neg();
759		b->neg=rand_neg();
760	/*	if (bp == NULL)
761			for (j=0; j<100; j++)
762				BN_mod_mul(d,a,b,c,ctx);*/ /**/
763
764		if (!BN_mod_mul(e,a,b,c,ctx))
765			{
766			unsigned long l;
767
768			while ((l=ERR_get_error()))
769				fprintf(stderr,"ERROR:%s\n",
770					ERR_error_string(l,NULL));
771			exit(1);
772			}
773		if (bp != NULL)
774			{
775			if (!results)
776				{
777				BN_print(bp,a);
778				BIO_puts(bp," * ");
779				BN_print(bp,b);
780				BIO_puts(bp," % ");
781				BN_print(bp,c);
782				BIO_puts(bp," - ");
783				}
784			BN_print(bp,e);
785			BIO_puts(bp,"\n");
786			}
787		BN_mul(d,a,b,ctx);
788		BN_sub(d,d,e);
789		BN_div(a,b,d,c,ctx);
790		if(!BN_is_zero(b))
791		    {
792		    fprintf(stderr,"Modulo multiply test failed!\n");
793		    return 0;
794		    }
795		}
796	BN_free(a);
797	BN_free(b);
798	BN_free(c);
799	BN_free(d);
800	BN_free(e);
801	return(1);
802	}
803
804int test_mod_exp(BIO *bp, BN_CTX *ctx)
805	{
806	BIGNUM *a,*b,*c,*d,*e;
807	int i;
808
809	a=BN_new();
810	b=BN_new();
811	c=BN_new();
812	d=BN_new();
813	e=BN_new();
814
815	BN_rand(c,30,0,1); /* must be odd for montgomery */
816	for (i=0; i<num2; i++)
817		{
818		BN_rand(a,20+i*5,0,0); /**/
819		BN_rand(b,2+i,0,0); /**/
820
821		if (!BN_mod_exp(d,a,b,c,ctx))
822			return(00);
823
824		if (bp != NULL)
825			{
826			if (!results)
827				{
828				BN_print(bp,a);
829				BIO_puts(bp," ^ ");
830				BN_print(bp,b);
831				BIO_puts(bp," % ");
832				BN_print(bp,c);
833				BIO_puts(bp," - ");
834				}
835			BN_print(bp,d);
836			BIO_puts(bp,"\n");
837			}
838		BN_exp(e,a,b,ctx);
839		BN_sub(e,e,d);
840		BN_div(a,b,e,c,ctx);
841		if(!BN_is_zero(b))
842		    {
843		    fprintf(stderr,"Modulo exponentiation test failed!\n");
844		    return 0;
845		    }
846		}
847	BN_free(a);
848	BN_free(b);
849	BN_free(c);
850	BN_free(d);
851	BN_free(e);
852	return(1);
853	}
854
855int test_exp(BIO *bp, BN_CTX *ctx)
856	{
857	BIGNUM *a,*b,*d,*e,*one;
858	int i;
859
860	a=BN_new();
861	b=BN_new();
862	d=BN_new();
863	e=BN_new();
864	one=BN_new();
865	BN_one(one);
866
867	for (i=0; i<num2; i++)
868		{
869		BN_rand(a,20+i*5,0,0); /**/
870		BN_rand(b,2+i,0,0); /**/
871
872		if (!BN_exp(d,a,b,ctx))
873			return(00);
874
875		if (bp != NULL)
876			{
877			if (!results)
878				{
879				BN_print(bp,a);
880				BIO_puts(bp," ^ ");
881				BN_print(bp,b);
882				BIO_puts(bp," - ");
883				}
884			BN_print(bp,d);
885			BIO_puts(bp,"\n");
886			}
887		BN_one(e);
888		for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
889		    BN_mul(e,e,a,ctx);
890		BN_sub(e,e,d);
891		if(!BN_is_zero(e))
892		    {
893		    fprintf(stderr,"Exponentiation test failed!\n");
894		    return 0;
895		    }
896		}
897	BN_free(a);
898	BN_free(b);
899	BN_free(d);
900	BN_free(e);
901	BN_free(one);
902	return(1);
903	}
904
905int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
906	{
907	BIGNUM *a,*b,*c,*d;
908	int i;
909
910	b=BN_new();
911	c=BN_new();
912	d=BN_new();
913	BN_one(c);
914
915	if(a_)
916	    a=a_;
917	else
918	    {
919	    a=BN_new();
920	    BN_rand(a,200,0,0); /**/
921	    a->neg=rand_neg();
922	    }
923	for (i=0; i<num0; i++)
924		{
925		BN_lshift(b,a,i+1);
926		BN_add(c,c,c);
927		if (bp != NULL)
928			{
929			if (!results)
930				{
931				BN_print(bp,a);
932				BIO_puts(bp," * ");
933				BN_print(bp,c);
934				BIO_puts(bp," - ");
935				}
936			BN_print(bp,b);
937			BIO_puts(bp,"\n");
938			}
939		BN_mul(d,a,c,ctx);
940		BN_sub(d,d,b);
941		if(!BN_is_zero(d))
942		    {
943		    fprintf(stderr,"Left shift test failed!\n");
944		    fprintf(stderr,"a=");
945		    BN_print_fp(stderr,a);
946		    fprintf(stderr,"\nb=");
947		    BN_print_fp(stderr,b);
948		    fprintf(stderr,"\nc=");
949		    BN_print_fp(stderr,c);
950		    fprintf(stderr,"\nd=");
951		    BN_print_fp(stderr,d);
952		    fprintf(stderr,"\n");
953		    return 0;
954		    }
955		}
956	BN_free(a);
957	BN_free(b);
958	BN_free(c);
959	BN_free(d);
960	return(1);
961	}
962
963int test_lshift1(BIO *bp)
964	{
965	BIGNUM *a,*b,*c;
966	int i;
967
968	a=BN_new();
969	b=BN_new();
970	c=BN_new();
971
972	BN_rand(a,200,0,0); /**/
973	a->neg=rand_neg();
974	for (i=0; i<num0; i++)
975		{
976		BN_lshift1(b,a);
977		if (bp != NULL)
978			{
979			if (!results)
980				{
981				BN_print(bp,a);
982				BIO_puts(bp," * 2");
983				BIO_puts(bp," - ");
984				}
985			BN_print(bp,b);
986			BIO_puts(bp,"\n");
987			}
988		BN_add(c,a,a);
989		BN_sub(a,b,c);
990		if(!BN_is_zero(a))
991		    {
992		    fprintf(stderr,"Left shift one test failed!\n");
993		    return 0;
994		    }
995
996		BN_copy(a,b);
997		}
998	BN_free(a);
999	BN_free(b);
1000	BN_free(c);
1001	return(1);
1002	}
1003
1004int test_rshift(BIO *bp,BN_CTX *ctx)
1005	{
1006	BIGNUM *a,*b,*c,*d,*e;
1007	int i;
1008
1009	a=BN_new();
1010	b=BN_new();
1011	c=BN_new();
1012	d=BN_new();
1013	e=BN_new();
1014	BN_one(c);
1015
1016	BN_rand(a,200,0,0); /**/
1017	a->neg=rand_neg();
1018	for (i=0; i<num0; i++)
1019		{
1020		BN_rshift(b,a,i+1);
1021		BN_add(c,c,c);
1022		if (bp != NULL)
1023			{
1024			if (!results)
1025				{
1026				BN_print(bp,a);
1027				BIO_puts(bp," / ");
1028				BN_print(bp,c);
1029				BIO_puts(bp," - ");
1030				}
1031			BN_print(bp,b);
1032			BIO_puts(bp,"\n");
1033			}
1034		BN_div(d,e,a,c,ctx);
1035		BN_sub(d,d,b);
1036		if(!BN_is_zero(d))
1037		    {
1038		    fprintf(stderr,"Right shift test failed!\n");
1039		    return 0;
1040		    }
1041		}
1042	BN_free(a);
1043	BN_free(b);
1044	BN_free(c);
1045	BN_free(d);
1046	BN_free(e);
1047	return(1);
1048	}
1049
1050int test_rshift1(BIO *bp)
1051	{
1052	BIGNUM *a,*b,*c;
1053	int i;
1054
1055	a=BN_new();
1056	b=BN_new();
1057	c=BN_new();
1058
1059	BN_rand(a,200,0,0); /**/
1060	a->neg=rand_neg();
1061	for (i=0; i<num0; i++)
1062		{
1063		BN_rshift1(b,a);
1064		if (bp != NULL)
1065			{
1066			if (!results)
1067				{
1068				BN_print(bp,a);
1069				BIO_puts(bp," / 2");
1070				BIO_puts(bp," - ");
1071				}
1072			BN_print(bp,b);
1073			BIO_puts(bp,"\n");
1074			}
1075		BN_sub(c,a,b);
1076		BN_sub(c,c,b);
1077		if(!BN_is_zero(c) && !BN_is_one(c))
1078		    {
1079		    fprintf(stderr,"Right shift one test failed!\n");
1080		    return 0;
1081		    }
1082		BN_copy(a,b);
1083		}
1084	BN_free(a);
1085	BN_free(b);
1086	BN_free(c);
1087	return(1);
1088	}
1089
1090int rand_neg(void)
1091	{
1092	static unsigned int neg=0;
1093	static int sign[8]={0,0,0,1,1,0,1,1};
1094
1095	return(sign[(neg++)%8]);
1096	}
1097