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