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