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