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