Undo previous commit, which was an accident.
[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                                 if ((a->neg ^ b->neg) && !BN_is_zero(e))
765                                         {
766                                         /* If  (a*b) % c  is negative,  c  must be added
767                                          * in order to obtain the normalized remainder
768                                          * (new with OpenSSL 0.9.7, previous versions of
769                                          * BN_mod_mul could generate negative results)
770                                          */
771                                         BIO_puts(bp," + ");
772                                         BN_print(bp,c);
773                                         }
774                                 BIO_puts(bp," - ");
775                                 }
776                         BN_print(bp,e);
777                         BIO_puts(bp,"\n");
778                         }
779                 BN_mul(d,a,b,ctx);
780                 BN_sub(d,d,e);
781                 BN_div(a,b,d,c,ctx);
782                 if(!BN_is_zero(b))
783                     {
784                     fprintf(stderr,"Modulo multiply test failed!\n");
785                     ERR_print_errors_fp(stderr);
786                     return 0;
787                     }
788                 }
789         BN_free(a);
790         BN_free(b);
791         BN_free(c);
792         BN_free(d);
793         BN_free(e);
794         return(1);
795         }
796
797 int test_mod_exp(BIO *bp, BN_CTX *ctx)
798         {
799         BIGNUM *a,*b,*c,*d,*e;
800         int i;
801
802         a=BN_new();
803         b=BN_new();
804         c=BN_new();
805         d=BN_new();
806         e=BN_new();
807
808         BN_rand(c,30,0,1); /* must be odd for montgomery */
809         for (i=0; i<num2; i++)
810                 {
811                 BN_rand(a,20+i*5,0,0); /**/
812                 BN_rand(b,2+i,0,0); /**/
813
814                 if (!BN_mod_exp(d,a,b,c,ctx))
815                         return(00);
816
817                 if (bp != NULL)
818                         {
819                         if (!results)
820                                 {
821                                 BN_print(bp,a);
822                                 BIO_puts(bp," ^ ");
823                                 BN_print(bp,b);
824                                 BIO_puts(bp," % ");
825                                 BN_print(bp,c);
826                                 BIO_puts(bp," - ");
827                                 }
828                         BN_print(bp,d);
829                         BIO_puts(bp,"\n");
830                         }
831                 BN_exp(e,a,b,ctx);
832                 BN_sub(e,e,d);
833                 BN_div(a,b,e,c,ctx);
834                 if(!BN_is_zero(b))
835                     {
836                     fprintf(stderr,"Modulo exponentiation test failed!\n");
837                     return 0;
838                     }
839                 }
840         BN_free(a);
841         BN_free(b);
842         BN_free(c);
843         BN_free(d);
844         BN_free(e);
845         return(1);
846         }
847
848 int test_exp(BIO *bp, BN_CTX *ctx)
849         {
850         BIGNUM *a,*b,*d,*e,*one;
851         int i;
852
853         a=BN_new();
854         b=BN_new();
855         d=BN_new();
856         e=BN_new();
857         one=BN_new();
858         BN_one(one);
859
860         for (i=0; i<num2; i++)
861                 {
862                 BN_rand(a,20+i*5,0,0); /**/
863                 BN_rand(b,2+i,0,0); /**/
864
865                 if (!BN_exp(d,a,b,ctx))
866                         return(00);
867
868                 if (bp != NULL)
869                         {
870                         if (!results)
871                                 {
872                                 BN_print(bp,a);
873                                 BIO_puts(bp," ^ ");
874                                 BN_print(bp,b);
875                                 BIO_puts(bp," - ");
876                                 }
877                         BN_print(bp,d);
878                         BIO_puts(bp,"\n");
879                         }
880                 BN_one(e);
881                 for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
882                     BN_mul(e,e,a,ctx);
883                 BN_sub(e,e,d);
884                 if(!BN_is_zero(e))
885                     {
886                     fprintf(stderr,"Exponentiation test failed!\n");
887                     return 0;
888                     }
889                 }
890         BN_free(a);
891         BN_free(b);
892         BN_free(d);
893         BN_free(e);
894         BN_free(one);
895         return(1);
896         }
897
898 int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
899         {
900         BIGNUM *a,*b,*c,*d;
901         int i;
902
903         b=BN_new();
904         c=BN_new();
905         d=BN_new();
906         BN_one(c);
907
908         if(a_)
909             a=a_;
910         else
911             {
912             a=BN_new();
913             BN_rand(a,200,0,0); /**/
914             a->neg=rand_neg();
915             }
916         for (i=0; i<num0; i++)
917                 {
918                 BN_lshift(b,a,i+1);
919                 BN_add(c,c,c);
920                 if (bp != NULL)
921                         {
922                         if (!results)
923                                 {
924                                 BN_print(bp,a);
925                                 BIO_puts(bp," * ");
926                                 BN_print(bp,c);
927                                 BIO_puts(bp," - ");
928                                 }
929                         BN_print(bp,b);
930                         BIO_puts(bp,"\n");
931                         }
932                 BN_mul(d,a,c,ctx);
933                 BN_sub(d,d,b);
934                 if(!BN_is_zero(d))
935                     {
936                     fprintf(stderr,"Left shift test failed!\n");
937                     fprintf(stderr,"a=");
938                     BN_print_fp(stderr,a);
939                     fprintf(stderr,"\nb=");
940                     BN_print_fp(stderr,b);
941                     fprintf(stderr,"\nc=");
942                     BN_print_fp(stderr,c);
943                     fprintf(stderr,"\nd=");
944                     BN_print_fp(stderr,d);
945                     fprintf(stderr,"\n");
946                     return 0;
947                     }
948                 }
949         BN_free(a);
950         BN_free(b);
951         BN_free(c);
952         BN_free(d);
953         return(1);
954         }
955
956 int test_lshift1(BIO *bp)
957         {
958         BIGNUM *a,*b,*c;
959         int i;
960
961         a=BN_new();
962         b=BN_new();
963         c=BN_new();
964
965         BN_rand(a,200,0,0); /**/
966         a->neg=rand_neg();
967         for (i=0; i<num0; i++)
968                 {
969                 BN_lshift1(b,a);
970                 if (bp != NULL)
971                         {
972                         if (!results)
973                                 {
974                                 BN_print(bp,a);
975                                 BIO_puts(bp," * 2");
976                                 BIO_puts(bp," - ");
977                                 }
978                         BN_print(bp,b);
979                         BIO_puts(bp,"\n");
980                         }
981                 BN_add(c,a,a);
982                 BN_sub(a,b,c);
983                 if(!BN_is_zero(a))
984                     {
985                     fprintf(stderr,"Left shift one test failed!\n");
986                     return 0;
987                     }
988                 
989                 BN_copy(a,b);
990                 }
991         BN_free(a);
992         BN_free(b);
993         BN_free(c);
994         return(1);
995         }
996
997 int test_rshift(BIO *bp,BN_CTX *ctx)
998         {
999         BIGNUM *a,*b,*c,*d,*e;
1000         int i;
1001
1002         a=BN_new();
1003         b=BN_new();
1004         c=BN_new();
1005         d=BN_new();
1006         e=BN_new();
1007         BN_one(c);
1008
1009         BN_rand(a,200,0,0); /**/
1010         a->neg=rand_neg();
1011         for (i=0; i<num0; i++)
1012                 {
1013                 BN_rshift(b,a,i+1);
1014                 BN_add(c,c,c);
1015                 if (bp != NULL)
1016                         {
1017                         if (!results)
1018                                 {
1019                                 BN_print(bp,a);
1020                                 BIO_puts(bp," / ");
1021                                 BN_print(bp,c);
1022                                 BIO_puts(bp," - ");
1023                                 }
1024                         BN_print(bp,b);
1025                         BIO_puts(bp,"\n");
1026                         }
1027                 BN_div(d,e,a,c,ctx);
1028                 BN_sub(d,d,b);
1029                 if(!BN_is_zero(d))
1030                     {
1031                     fprintf(stderr,"Right shift test failed!\n");
1032                     return 0;
1033                     }
1034                 }
1035         BN_free(a);
1036         BN_free(b);
1037         BN_free(c);
1038         BN_free(d);
1039         BN_free(e);
1040         return(1);
1041         }
1042
1043 int test_rshift1(BIO *bp)
1044         {
1045         BIGNUM *a,*b,*c;
1046         int i;
1047
1048         a=BN_new();
1049         b=BN_new();
1050         c=BN_new();
1051
1052         BN_rand(a,200,0,0); /**/
1053         a->neg=rand_neg();
1054         for (i=0; i<num0; i++)
1055                 {
1056                 BN_rshift1(b,a);
1057                 if (bp != NULL)
1058                         {
1059                         if (!results)
1060                                 {
1061                                 BN_print(bp,a);
1062                                 BIO_puts(bp," / 2");
1063                                 BIO_puts(bp," - ");
1064                                 }
1065                         BN_print(bp,b);
1066                         BIO_puts(bp,"\n");
1067                         }
1068                 BN_sub(c,a,b);
1069                 BN_sub(c,c,b);
1070                 if(!BN_is_zero(c) && !BN_is_one(c))
1071                     {
1072                     fprintf(stderr,"Right shift one test failed!\n");
1073                     return 0;
1074                     }
1075                 BN_copy(a,b);
1076                 }
1077         BN_free(a);
1078         BN_free(b);
1079         BN_free(c);
1080         return(1);
1081         }
1082
1083 int rand_neg(void)
1084         {
1085         static unsigned int neg=0;
1086         static int sign[8]={0,0,0,1,1,0,1,1};
1087
1088         return(sign[(neg++)%8]);
1089         }