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