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