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