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