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