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