Improve bntest slightly, and fix another bug in the BN library.
[openssl.git] / crypto / bn / bntest.c
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 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62
63 #include "openssl/e_os.h"
64
65 #include <openssl/bio.h>
66 #include <openssl/bn.h>
67 #include <openssl/rand.h>
68 #include <openssl/x509.h>
69 #include <openssl/err.h>
70
71 #ifdef WINDOWS
72 #include "../bio/bss_file.c"
73 #endif
74
75 const num0 = 100; /* number of tests */
76 const num1 = 50;  /* additional tests for some functions */
77 const num2 = 5;   /* number of tests for slow functions */
78
79 int test_add(BIO *bp);
80 int test_sub(BIO *bp);
81 int test_lshift1(BIO *bp);
82 int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
83 int test_rshift1(BIO *bp);
84 int test_rshift(BIO *bp,BN_CTX *ctx);
85 int test_div(BIO *bp,BN_CTX *ctx);
86 int test_div_recp(BIO *bp,BN_CTX *ctx);
87 int test_mul(BIO *bp);
88 int test_sqr(BIO *bp,BN_CTX *ctx);
89 int test_mont(BIO *bp,BN_CTX *ctx);
90 int test_mod(BIO *bp,BN_CTX *ctx);
91 int test_mod_mul(BIO *bp,BN_CTX *ctx);
92 int test_mod_exp(BIO *bp,BN_CTX *ctx);
93 int test_exp(BIO *bp,BN_CTX *ctx);
94 int rand_neg(void);
95 static int results=0;
96
97 #ifdef NO_STDIO
98 #define APPS_WIN16
99 #include "bss_file.c"
100 #endif
101
102 static unsigned char lst[]="\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
103 "\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
104
105 static const char rnd_seed[] = "string to make the random number generator think it has entropy";
106
107 void message(BIO *out, char *m)
108         {
109         fprintf(stderr, "test %s\n", m);
110 #if 1
111         BIO_puts(out, "print \"test ");
112         BIO_puts(out, m);
113         BIO_puts(out, "\\n\"\n");
114 #endif
115         }
116
117 int main(int argc, char *argv[])
118         {
119         BN_CTX *ctx;
120         BIO *out;
121         char *outfile=NULL;
122
123         results = 0;
124
125         RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we don't
126                                                * even check its return value
127                                                * (which we should) */
128
129         argc--;
130         argv++;
131         while (argc >= 1)
132                 {
133                 if (strcmp(*argv,"-results") == 0)
134                         results=1;
135                 else if (strcmp(*argv,"-out") == 0)
136                         {
137                         if (--argc < 1) break;
138                         outfile= *(++argv);
139                         }
140                 argc--;
141                 argv++;
142                 }
143
144
145         ctx=BN_CTX_new();
146         if (ctx == NULL) exit(1);
147
148         out=BIO_new(BIO_s_file());
149         if (out == NULL) exit(1);
150         if (outfile == NULL)
151                 {
152                 BIO_set_fp(out,stdout,BIO_NOCLOSE);
153                 }
154         else
155                 {
156                 if (!BIO_write_filename(out,outfile))
157                         {
158                         perror(outfile);
159                         exit(1);
160                         }
161                 }
162
163         if (!results)
164                 BIO_puts(out,"obase=16\nibase=16\n");
165
166         message(out,"BN_add");
167         if (!test_add(out)) goto err;
168         fflush(stdout);
169
170         message(out,"BN_sub");
171         if (!test_sub(out)) goto err;
172         fflush(stdout);
173
174         message(out,"BN_lshift1");
175         if (!test_lshift1(out)) goto err;
176         fflush(stdout);
177
178         message(out,"BN_lshift (fixed)");
179         if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
180             goto err;
181         fflush(stdout);
182
183         message(out,"BN_lshift");
184         if (!test_lshift(out,ctx,NULL)) goto err;
185         fflush(stdout);
186
187         message(out,"BN_rshift1");
188         if (!test_rshift1(out)) goto err;
189         fflush(stdout);
190
191         message(out,"BN_rshift");
192         if (!test_rshift(out,ctx)) goto err;
193         fflush(stdout);
194
195         message(out,"BN_sqr");
196         if (!test_sqr(out,ctx)) goto err;
197         fflush(stdout);
198
199         message(out,"BN_mul");
200         if (!test_mul(out)) goto err;
201         fflush(stdout);
202
203         message(out,"BN_div");
204         if (!test_div(out,ctx)) goto err;
205         fflush(stdout);
206
207         message(out,"BN_div_recp");
208         if (!test_div_recp(out,ctx)) goto err;
209         fflush(stdout);
210
211         message(out,"BN_mod");
212         if (!test_mod(out,ctx)) goto err;
213         fflush(stdout);
214
215         message(out,"BN_mod_mul");
216         if (!test_mod_mul(out,ctx)) goto err;
217         fflush(stdout);
218
219         message(out,"BN_mont");
220         if (!test_mont(out,ctx)) goto err;
221         fflush(stdout);
222
223         message(out,"BN_mod_exp");
224         if (!test_mod_exp(out,ctx)) goto err;
225         fflush(stdout);
226
227         message(out,"BN_exp");
228         if (!test_exp(out,ctx)) goto err;
229         fflush(stdout);
230
231         BN_CTX_free(ctx);
232         BIO_free(out);
233
234 /**/
235         exit(0);
236 err:
237         BIO_puts(out,"1\n"); /* make sure bc fails if we are piping to it */
238         ERR_load_crypto_strings();
239         ERR_print_errors_fp(stderr);
240         exit(1);
241         return(1);
242         }
243
244 int test_add(BIO *bp)
245         {
246         BIGNUM a,b,c;
247         int i;
248         int j;
249
250         BN_init(&a);
251         BN_init(&b);
252         BN_init(&c);
253
254         BN_rand(&a,512,0,0);
255         for (i=0; i<num0; i++)
256                 {
257                 BN_rand(&b,450+i,0,0);
258                 a.neg=rand_neg();
259                 b.neg=rand_neg();
260                 if (bp == NULL)
261                         for (j=0; j<10000; j++)
262                                 BN_add(&c,&a,&b);
263                 BN_add(&c,&a,&b);
264                 if (bp != NULL)
265                         {
266                         if (!results)
267                                 {
268                                 BN_print(bp,&a);
269                                 BIO_puts(bp," + ");
270                                 BN_print(bp,&b);
271                                 BIO_puts(bp," - ");
272                                 }
273                         BN_print(bp,&c);
274                         BIO_puts(bp,"\n");
275                         }
276                 a.neg=!a.neg;
277                 b.neg=!b.neg;
278                 BN_add(&c,&c,&b);
279                 BN_add(&c,&c,&a);
280                 if(!BN_is_zero(&c))
281                     {
282                     fprintf(stderr,"Add test failed!\n");
283                     return 0;
284                     }
285                 }
286         BN_free(&a);
287         BN_free(&b);
288         BN_free(&c);
289         return(1);
290         }
291
292 int test_sub(BIO *bp)
293         {
294         BIGNUM a,b,c;
295         int i;
296         int j;
297
298         BN_init(&a);
299         BN_init(&b);
300         BN_init(&c);
301
302         for (i=0; i<num0+num1; i++)
303                 {
304                 if (i < num1)
305                         {
306                         BN_rand(&a,512,0,0);
307                         BN_copy(&b,&a);
308                         if (BN_set_bit(&a,i)==0) return(0);
309                         BN_add_word(&b,i);
310                         }
311                 else
312                         {
313                         BN_rand(&b,400+i-num1,0,0);
314                         a.neg=rand_neg();
315                         b.neg=rand_neg();
316                         }
317                 if (bp == NULL)
318                         for (j=0; j<10000; j++)
319                                 BN_sub(&c,&a,&b);
320                 BN_sub(&c,&a,&b);
321                 if (bp != NULL)
322                         {
323                         if (!results)
324                                 {
325                                 BN_print(bp,&a);
326                                 BIO_puts(bp," - ");
327                                 BN_print(bp,&b);
328                                 BIO_puts(bp," - ");
329                                 }
330                         BN_print(bp,&c);
331                         BIO_puts(bp,"\n");
332                         }
333                 BN_add(&c,&c,&b);
334                 BN_sub(&c,&c,&a);
335                 if(!BN_is_zero(&c))
336                     {
337                     fprintf(stderr,"Subtract test failed!\n");
338                     return 0;
339                     }
340                 }
341         BN_free(&a);
342         BN_free(&b);
343         BN_free(&c);
344         return(1);
345         }
346
347 int test_div(BIO *bp, BN_CTX *ctx)
348         {
349         BIGNUM a,b,c,d,e;
350         int i;
351         int j;
352
353         BN_init(&a);
354         BN_init(&b);
355         BN_init(&c);
356         BN_init(&d);
357         BN_init(&e);
358
359         for (i=0; i<num0+num1; i++)
360                 {
361                 if (i < num1)
362                         {
363                         BN_rand(&a,400,0,0);
364                         BN_copy(&b,&a);
365                         BN_lshift(&a,&a,i);
366                         BN_add_word(&a,i);
367                         }
368                 else
369                         BN_rand(&b,50+3*(i-num1),0,0);
370                 a.neg=rand_neg();
371                 b.neg=rand_neg();
372                 if (bp == NULL)
373                         for (j=0; j<100; j++)
374                                 BN_div(&d,&c,&a,&b,ctx);
375                 BN_div(&d,&c,&a,&b,ctx);
376                 if (bp != NULL)
377                         {
378                         if (!results)
379                                 {
380                                 BN_print(bp,&a);
381                                 BIO_puts(bp," / ");
382                                 BN_print(bp,&b);
383                                 BIO_puts(bp," - ");
384                                 }
385                         BN_print(bp,&d);
386                         BIO_puts(bp,"\n");
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_mul(&e,&d,&b,ctx);
399                 BN_add(&d,&e,&c);
400                 BN_sub(&d,&d,&a);
401                 if(!BN_is_zero(&d))
402                     {
403                     fprintf(stderr,"Division test failed!\n");
404                     return 0;
405                     }
406                 }
407         BN_free(&a);
408         BN_free(&b);
409         BN_free(&c);
410         BN_free(&d);
411         BN_free(&e);
412         return(1);
413         }
414
415 int test_div_recp(BIO *bp, BN_CTX *ctx)
416         {
417         BIGNUM a,b,c,d,e;
418         BN_RECP_CTX recp;
419         int i;
420         int j;
421
422         BN_RECP_CTX_init(&recp);
423         BN_init(&a);
424         BN_init(&b);
425         BN_init(&c);
426         BN_init(&d);
427         BN_init(&e);
428
429         for (i=0; i<num0+num1; i++)
430                 {
431                 if (i < num1)
432                         {
433                         BN_rand(&a,400,0,0);
434                         BN_copy(&b,&a);
435                         BN_lshift(&a,&a,i);
436                         BN_add_word(&a,i);
437                         }
438                 else
439                         BN_rand(&b,50+3*(i-num1),0,0);
440                 a.neg=rand_neg();
441                 b.neg=rand_neg();
442                 BN_RECP_CTX_set(&recp,&b,ctx);
443                 if (bp == NULL)
444                         for (j=0; j<100; j++)
445                                 BN_div_recp(&d,&c,&a,&recp,ctx);
446                 BN_div_recp(&d,&c,&a,&recp,ctx);
447                 if (bp != NULL)
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,&d);
457                         BIO_puts(bp,"\n");
458
459                         if (!results)
460                                 {
461                                 BN_print(bp,&a);
462                                 BIO_puts(bp," % ");
463                                 BN_print(bp,&b);
464                                 BIO_puts(bp," - ");
465                                 }
466                         BN_print(bp,&c);
467                         BIO_puts(bp,"\n");
468                         }
469                 BN_mul(&e,&d,&b,ctx);
470                 BN_add(&d,&e,&c);
471                 BN_sub(&d,&d,&a);
472                 if(!BN_is_zero(&d))
473                     {
474                     fprintf(stderr,"Reciprocal division test failed!\n");
475                     fprintf(stderr,"a=");
476                     BN_print_fp(stderr,&a);
477                     fprintf(stderr,"\nb=");
478                     BN_print_fp(stderr,&b);
479                     fprintf(stderr,"\n");
480                     return 0;
481                     }
482                 }
483         BN_free(&a);
484         BN_free(&b);
485         BN_free(&c);
486         BN_free(&d);
487         BN_free(&e);
488         BN_RECP_CTX_free(&recp);
489         return(1);
490         }
491
492 int test_mul(BIO *bp)
493         {
494         BIGNUM a,b,c,d,e;
495         int i;
496         int j;
497         BN_CTX ctx;
498
499         BN_CTX_init(&ctx);
500         BN_init(&a);
501         BN_init(&b);
502         BN_init(&c);
503         BN_init(&d);
504         BN_init(&e);
505
506         for (i=0; i<num0+num1; i++)
507                 {
508                 if (i < num1)
509                         {
510                         BN_rand(&a,100,0,0);
511                         BN_rand(&b,100,0,0);
512                         }
513                 else
514                         BN_rand(&b,i-num1,0,0);
515                 a.neg=rand_neg();
516                 b.neg=rand_neg();
517                 if (bp == NULL)
518                         for (j=0; j<100; j++)
519                                 BN_mul(&c,&a,&b,&ctx);
520                 BN_mul(&c,&a,&b,&ctx);
521                 if (bp != NULL)
522                         {
523                         if (!results)
524                                 {
525                                 BN_print(bp,&a);
526                                 BIO_puts(bp," * ");
527                                 BN_print(bp,&b);
528                                 BIO_puts(bp," - ");
529                                 }
530                         BN_print(bp,&c);
531                         BIO_puts(bp,"\n");
532                         }
533                 BN_div(&d,&e,&c,&a,&ctx);
534                 BN_sub(&d,&d,&b);
535                 if(!BN_is_zero(&d) || !BN_is_zero(&e))
536                     {
537                     fprintf(stderr,"Multiplication test failed!\n");
538                     return 0;
539                     }
540                 }
541         BN_free(&a);
542         BN_free(&b);
543         BN_free(&c);
544         BN_free(&d);
545         BN_free(&e);
546         BN_CTX_free(&ctx);
547         return(1);
548         }
549
550 int test_sqr(BIO *bp, BN_CTX *ctx)
551         {
552         BIGNUM a,c,d,e;
553         int i;
554         int j;
555
556         BN_init(&a);
557         BN_init(&c);
558         BN_init(&d);
559         BN_init(&e);
560
561         for (i=0; i<num0; i++)
562                 {
563                 BN_rand(&a,40+i*10,0,0);
564                 a.neg=rand_neg();
565                 if (bp == NULL)
566                         for (j=0; j<100; j++)
567                                 BN_sqr(&c,&a,ctx);
568                 BN_sqr(&c,&a,ctx);
569                 if (bp != NULL)
570                         {
571                         if (!results)
572                                 {
573                                 BN_print(bp,&a);
574                                 BIO_puts(bp," * ");
575                                 BN_print(bp,&a);
576                                 BIO_puts(bp," - ");
577                                 }
578                         BN_print(bp,&c);
579                         BIO_puts(bp,"\n");
580                         }
581                 BN_div(&d,&e,&c,&a,ctx);
582                 BN_sub(&d,&d,&a);
583                 if(!BN_is_zero(&d) || !BN_is_zero(&e))
584                     {
585                     fprintf(stderr,"Square test failed!\n");
586                     return 0;
587                     }
588                 }
589         BN_free(&a);
590         BN_free(&c);
591         BN_free(&d);
592         BN_free(&e);
593         return(1);
594         }
595
596 int test_mont(BIO *bp, BN_CTX *ctx)
597         {
598         BIGNUM a,b,c,d,A,B;
599         BIGNUM n;
600         int i;
601         int j;
602         BN_MONT_CTX *mont;
603
604         BN_init(&a);
605         BN_init(&b);
606         BN_init(&c);
607         BN_init(&d);
608         BN_init(&A);
609         BN_init(&B);
610         BN_init(&n);
611
612         mont=BN_MONT_CTX_new();
613
614         BN_rand(&a,100,0,0); /**/
615         BN_rand(&b,100,0,0); /**/
616         for (i=0; i<num2; i++)
617                 {
618                 int bits = (100%BN_BITS2+1)*BN_BITS2*i*BN_BITS2;
619
620                 if (bits == 0)
621                         continue;
622                 BN_rand(&n,bits,0,1);
623                 BN_MONT_CTX_set(mont,&n,ctx);
624
625                 BN_to_montgomery(&A,&a,mont,ctx);
626                 BN_to_montgomery(&B,&b,mont,ctx);
627
628                 if (bp == NULL)
629                         for (j=0; j<100; j++)
630                                 BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
631                 BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
632                 BN_from_montgomery(&A,&c,mont,ctx);/**/
633                 if (bp != NULL)
634                         {
635                         if (!results)
636                                 {
637 #ifdef undef
638 fprintf(stderr,"%d * %d %% %d\n",
639 BN_num_bits(&a),
640 BN_num_bits(&b),
641 BN_num_bits(mont->N));
642 #endif
643                                 BN_print(bp,&a);
644                                 BIO_puts(bp," * ");
645                                 BN_print(bp,&b);
646                                 BIO_puts(bp," % ");
647                                 BN_print(bp,&(mont->N));
648                                 BIO_puts(bp," - ");
649                                 }
650                         BN_print(bp,&A);
651                         BIO_puts(bp,"\n");
652                         }
653                 BN_mod_mul(&d,&a,&b,&n,ctx);
654                 BN_sub(&d,&d,&A);
655                 if(!BN_is_zero(&d))
656                     {
657                     fprintf(stderr,"Montgomery multiplication test failed!\n");
658                     return 0;
659                     }
660                 }
661         BN_MONT_CTX_free(mont);
662         BN_free(&a);
663         BN_free(&b);
664         BN_free(&c);
665         BN_free(&d);
666         BN_free(&A);
667         BN_free(&B);
668         BN_free(&n);
669         return(1);
670         }
671
672 int test_mod(BIO *bp, BN_CTX *ctx)
673         {
674         BIGNUM *a,*b,*c,*d,*e;
675         int i;
676         int j;
677
678         a=BN_new();
679         b=BN_new();
680         c=BN_new();
681         d=BN_new();
682         e=BN_new();
683
684         BN_rand(a,1024,0,0); /**/
685         for (i=0; i<num0; i++)
686                 {
687                 BN_rand(b,450+i*10,0,0); /**/
688                 a->neg=rand_neg();
689                 b->neg=rand_neg();
690                 if (bp == NULL)
691                         for (j=0; j<100; j++)
692                                 BN_mod(c,a,b,ctx);/**/
693                 BN_mod(c,a,b,ctx);/**/
694                 if (bp != NULL)
695                         {
696                         if (!results)
697                                 {
698                                 BN_print(bp,a);
699                                 BIO_puts(bp," % ");
700                                 BN_print(bp,b);
701                                 BIO_puts(bp," - ");
702                                 }
703                         BN_print(bp,c);
704                         BIO_puts(bp,"\n");
705                         }
706                 BN_div(d,e,a,b,ctx);
707                 BN_sub(e,e,c);
708                 if(!BN_is_zero(e))
709                     {
710                     fprintf(stderr,"Modulo test failed!\n");
711                     return 0;
712                     }
713                 }
714         BN_free(a);
715         BN_free(b);
716         BN_free(c);
717         BN_free(d);
718         BN_free(e);
719         return(1);
720         }
721
722 int test_mod_mul(BIO *bp, BN_CTX *ctx)
723         {
724         BIGNUM *a,*b,*c,*d,*e;
725         int i;
726
727         a=BN_new();
728         b=BN_new();
729         c=BN_new();
730         d=BN_new();
731         e=BN_new();
732
733         BN_rand(c,1024,0,0); /**/
734         for (i=0; i<num0; i++)
735                 {
736                 BN_rand(b,425+i*10,0,0); /**/
737                 a->neg=rand_neg();
738                 b->neg=rand_neg();
739         /*      if (bp == NULL)
740                         for (j=0; j<100; j++)
741                                 BN_mod_mul(d,a,b,c,ctx);*/ /**/
742
743                 if (!BN_mod_mul(e,a,b,c,ctx))
744                         {
745                         unsigned long l;
746
747                         while ((l=ERR_get_error()))
748                                 fprintf(stderr,"ERROR:%s\n",
749                                         ERR_error_string(l,NULL));
750                         exit(1);
751                         }
752                 if (bp != NULL)
753                         {
754                         if (!results)
755                                 {
756                                 BN_print(bp,a);
757                                 BIO_puts(bp," * ");
758                                 BN_print(bp,b);
759                                 BIO_puts(bp," % ");
760                                 BN_print(bp,c);
761                                 BIO_puts(bp," - ");
762                                 }
763                         BN_print(bp,e);
764                         BIO_puts(bp,"\n");
765                         }
766                 BN_mul(d,a,b,ctx);
767                 BN_sub(d,d,e);
768                 BN_div(a,b,d,c,ctx);
769                 if(!BN_is_zero(b))
770                     {
771                     fprintf(stderr,"Modulo multiply test failed!\n");
772                     return 0;
773                     }
774                 }
775         BN_free(a);
776         BN_free(b);
777         BN_free(c);
778         BN_free(d);
779         BN_free(e);
780         return(1);
781         }
782
783 int test_mod_exp(BIO *bp, BN_CTX *ctx)
784         {
785         BIGNUM *a,*b,*c,*d,*e;
786         int i;
787
788         a=BN_new();
789         b=BN_new();
790         c=BN_new();
791         d=BN_new();
792         e=BN_new();
793
794         BN_rand(c,30,0,1); /* must be odd for montgomery */
795         for (i=0; i<num2; i++)
796                 {
797                 BN_rand(a,20+i*5,0,0); /**/
798                 BN_rand(b,2+i,0,0); /**/
799
800                 if (!BN_mod_exp(d,a,b,c,ctx))
801                         return(00);
802
803                 if (bp != NULL)
804                         {
805                         if (!results)
806                                 {
807                                 BN_print(bp,a);
808                                 BIO_puts(bp," ^ ");
809                                 BN_print(bp,b);
810                                 BIO_puts(bp," % ");
811                                 BN_print(bp,c);
812                                 BIO_puts(bp," - ");
813                                 }
814                         BN_print(bp,d);
815                         BIO_puts(bp,"\n");
816                         }
817                 BN_exp(e,a,b,ctx);
818                 BN_sub(e,e,d);
819                 BN_div(a,b,e,c,ctx);
820                 if(!BN_is_zero(b))
821                     {
822                     fprintf(stderr,"Modulo exponentiation test failed!\n");
823                     return 0;
824                     }
825                 }
826         BN_free(a);
827         BN_free(b);
828         BN_free(c);
829         BN_free(d);
830         BN_free(e);
831         return(1);
832         }
833
834 int test_exp(BIO *bp, BN_CTX *ctx)
835         {
836         BIGNUM *a,*b,*d,*e,*one;
837         int i;
838
839         a=BN_new();
840         b=BN_new();
841         d=BN_new();
842         e=BN_new();
843         one=BN_new();
844         BN_one(one);
845
846         for (i=0; i<num2; i++)
847                 {
848                 BN_rand(a,20+i*5,0,0); /**/
849                 BN_rand(b,2+i,0,0); /**/
850
851                 if (!BN_exp(d,a,b,ctx))
852                         return(00);
853
854                 if (bp != NULL)
855                         {
856                         if (!results)
857                                 {
858                                 BN_print(bp,a);
859                                 BIO_puts(bp," ^ ");
860                                 BN_print(bp,b);
861                                 BIO_puts(bp," - ");
862                                 }
863                         BN_print(bp,d);
864                         BIO_puts(bp,"\n");
865                         }
866                 BN_one(e);
867                 for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
868                     BN_mul(e,e,a,ctx);
869                 BN_sub(e,e,d);
870                 if(!BN_is_zero(e))
871                     {
872                     fprintf(stderr,"Exponentiation test failed!\n");
873                     return 0;
874                     }
875                 }
876         BN_free(a);
877         BN_free(b);
878         BN_free(d);
879         BN_free(e);
880         BN_free(one);
881         return(1);
882         }
883
884 int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
885         {
886         BIGNUM *a,*b,*c,*d;
887         int i;
888
889         b=BN_new();
890         c=BN_new();
891         d=BN_new();
892         BN_one(c);
893
894         if(a_)
895             a=a_;
896         else
897             {
898             a=BN_new();
899             BN_rand(a,200,0,0); /**/
900             a->neg=rand_neg();
901             }
902         for (i=0; i<num0; i++)
903                 {
904                 BN_lshift(b,a,i+1);
905                 BN_add(c,c,c);
906                 if (bp != NULL)
907                         {
908                         if (!results)
909                                 {
910                                 BN_print(bp,a);
911                                 BIO_puts(bp," * ");
912                                 BN_print(bp,c);
913                                 BIO_puts(bp," - ");
914                                 }
915                         BN_print(bp,b);
916                         BIO_puts(bp,"\n");
917                         }
918                 BN_mul(d,a,c,ctx);
919                 BN_sub(d,d,b);
920                 if(!BN_is_zero(d))
921                     {
922                     fprintf(stderr,"Left shift test failed!\n");
923                     fprintf(stderr,"a=");
924                     BN_print_fp(stderr,a);
925                     fprintf(stderr,"\nb=");
926                     BN_print_fp(stderr,b);
927                     fprintf(stderr,"\nc=");
928                     BN_print_fp(stderr,c);
929                     fprintf(stderr,"\nd=");
930                     BN_print_fp(stderr,d);
931                     fprintf(stderr,"\n");
932                     return 0;
933                     }
934                 }
935         BN_free(a);
936         BN_free(b);
937         BN_free(c);
938         BN_free(d);
939         return(1);
940         }
941
942 int test_lshift1(BIO *bp)
943         {
944         BIGNUM *a,*b,*c;
945         int i;
946
947         a=BN_new();
948         b=BN_new();
949         c=BN_new();
950
951         BN_rand(a,200,0,0); /**/
952         a->neg=rand_neg();
953         for (i=0; i<num0; i++)
954                 {
955                 BN_lshift1(b,a);
956                 if (bp != NULL)
957                         {
958                         if (!results)
959                                 {
960                                 BN_print(bp,a);
961                                 BIO_puts(bp," * 2");
962                                 BIO_puts(bp," - ");
963                                 }
964                         BN_print(bp,b);
965                         BIO_puts(bp,"\n");
966                         }
967                 BN_add(c,a,a);
968                 BN_sub(a,b,c);
969                 if(!BN_is_zero(a))
970                     {
971                     fprintf(stderr,"Left shift one test failed!\n");
972                     return 0;
973                     }
974                 
975                 BN_copy(a,b);
976                 }
977         BN_free(a);
978         BN_free(b);
979         BN_free(c);
980         return(1);
981         }
982
983 int test_rshift(BIO *bp,BN_CTX *ctx)
984         {
985         BIGNUM *a,*b,*c,*d,*e;
986         int i;
987
988         a=BN_new();
989         b=BN_new();
990         c=BN_new();
991         d=BN_new();
992         e=BN_new();
993         BN_one(c);
994
995         BN_rand(a,200,0,0); /**/
996         a->neg=rand_neg();
997         for (i=0; i<num0; i++)
998                 {
999                 BN_rshift(b,a,i+1);
1000                 BN_add(c,c,c);
1001                 if (bp != NULL)
1002                         {
1003                         if (!results)
1004                                 {
1005                                 BN_print(bp,a);
1006                                 BIO_puts(bp," / ");
1007                                 BN_print(bp,c);
1008                                 BIO_puts(bp," - ");
1009                                 }
1010                         BN_print(bp,b);
1011                         BIO_puts(bp,"\n");
1012                         }
1013                 BN_div(d,e,a,c,ctx);
1014                 BN_sub(d,d,b);
1015                 if(!BN_is_zero(d))
1016                     {
1017                     fprintf(stderr,"Right shift test failed!\n");
1018                     return 0;
1019                     }
1020                 }
1021         BN_free(a);
1022         BN_free(b);
1023         BN_free(c);
1024         BN_free(d);
1025         BN_free(e);
1026         return(1);
1027         }
1028
1029 int test_rshift1(BIO *bp)
1030         {
1031         BIGNUM *a,*b,*c;
1032         int i;
1033
1034         a=BN_new();
1035         b=BN_new();
1036         c=BN_new();
1037
1038         BN_rand(a,200,0,0); /**/
1039         a->neg=rand_neg();
1040         for (i=0; i<num0; i++)
1041                 {
1042                 BN_rshift1(b,a);
1043                 if (bp != NULL)
1044                         {
1045                         if (!results)
1046                                 {
1047                                 BN_print(bp,a);
1048                                 BIO_puts(bp," / 2");
1049                                 BIO_puts(bp," - ");
1050                                 }
1051                         BN_print(bp,b);
1052                         BIO_puts(bp,"\n");
1053                         }
1054                 BN_sub(c,a,b);
1055                 BN_sub(c,c,b);
1056                 if(!BN_is_zero(c) && !BN_is_one(c))
1057                     {
1058                     fprintf(stderr,"Right shift one test failed!\n");
1059                     return 0;
1060                     }
1061                 BN_copy(a,b);
1062                 }
1063         BN_free(a);
1064         BN_free(b);
1065         BN_free(c);
1066         return(1);
1067         }
1068
1069 int rand_neg(void)
1070         {
1071         static unsigned int neg=0;
1072         static int sign[8]={0,0,0,1,1,0,1,1};
1073
1074         return(sign[(neg++)%8]);
1075         }