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