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