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