7a2f0b8d6d9bbb70ea94b5f8bcd17f8ff63f605f
[openssl.git] / crypto / bn / bntest.c
1 /* crypto/bn/bntest.c */
2 /* Copyright (C) 1995-1997 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 #ifdef WIN16
63 #define APPS_WIN16
64 #endif
65 #include "bio.h"
66 #include "bn.h"
67 #include "rand.h"
68 #include "x509.h"
69 #include "err.h"
70
71 #ifndef NOPROTO
72 int test_add (BIO *bp);
73 int test_sub (BIO *bp);
74 int test_lshift1 (BIO *bp);
75 int test_lshift (BIO *bp);
76 int test_rshift1 (BIO *bp);
77 int test_rshift (BIO *bp);
78 int test_div (BIO *bp,BN_CTX *ctx);
79 int test_mul (BIO *bp);
80 int test_sqr (BIO *bp,BN_CTX *ctx);
81 int test_mont (BIO *bp,BN_CTX *ctx);
82 int test_mod (BIO *bp,BN_CTX *ctx);
83 int test_mod_mul (BIO *bp,BN_CTX *ctx);
84 int test_mod_exp (BIO *bp,BN_CTX *ctx);
85 int rand_neg(void);
86 #else
87 int test_add ();
88 int test_sub ();
89 int test_lshift1 ();
90 int test_lshift ();
91 int test_rshift1 ();
92 int test_rshift ();
93 int test_div ();
94 int test_mul ();
95 int test_sqr ();
96 int test_mont ();
97 int test_mod ();
98 int test_mod_mul ();
99 int test_mod_exp ();
100 int rand_neg();
101 #endif
102
103 static int results=0;
104
105 #ifdef WIN16
106 #define APPS_WIN16
107 #include "../bio/bss_file.c"
108 #endif
109
110 int main(argc,argv)
111 int argc;
112 char *argv[];
113         {
114         BN_CTX *ctx;
115         BIO *out;
116         char *outfile=NULL;
117
118         srand((unsigned int)time(NULL));
119
120         argc--;
121         argv++;
122         while (argc >= 1)
123                 {
124                 if (strcmp(*argv,"-results") == 0)
125                         results=1;
126                 else if (strcmp(*argv,"-out") == 0)
127                         {
128                         if (--argc < 1) break;
129                         outfile= *(++argv);
130                         }
131                 argc--;
132                 argv++;
133                 }
134
135
136         ctx=BN_CTX_new();
137         if (ctx == NULL) exit(1);
138
139         out=BIO_new(BIO_s_file());
140         if (out == NULL) exit(1);
141         if (outfile == NULL)
142                 {
143                 BIO_set_fp(out,stdout,BIO_NOCLOSE);
144                 }
145         else
146                 {
147                 if (!BIO_write_filename(out,outfile))
148                         {
149                         perror(outfile);
150                         exit(1);
151                         }
152                 }
153
154         if (!results)
155                 BIO_puts(out,"obase=16\nibase=16\n");
156
157         fprintf(stderr,"test BN_add\n");
158         if (!test_add(out)) goto err;
159         fflush(stdout);
160
161         fprintf(stderr,"test BN_sub\n");
162         if (!test_sub(out)) goto err;
163         fflush(stdout);
164
165         fprintf(stderr,"test BN_lshift1\n");
166         if (!test_lshift1(out)) goto err;
167         fflush(stdout);
168
169         fprintf(stderr,"test BN_lshift\n");
170         if (!test_lshift(out)) goto err;
171         fflush(stdout);
172
173         fprintf(stderr,"test BN_rshift1\n");
174         if (!test_rshift1(out)) goto err;
175         fflush(stdout);
176
177         fprintf(stderr,"test BN_rshift\n");
178         if (!test_rshift(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_mod\n");
186         if (!test_mod(out,ctx)) goto err;
187         fflush(stdout);
188
189         fprintf(stderr,"test BN_mul\n");
190         if (!test_mul(out)) goto err;
191         fflush(stdout);
192
193         fprintf(stderr,"test BN_sqr\n");
194         if (!test_sqr(out,ctx)) goto err;
195         fflush(stdout);
196
197         fprintf(stderr,"test BN_mod_mul\n");
198         if (!test_mod_mul(out,ctx)) goto err;
199         fflush(stdout);
200
201 /*
202         fprintf(stderr,"test BN_mont\n");
203         if (!test_mont(out,ctx)) goto err;
204         fflush(stdout);
205 */
206         fprintf(stderr,"test BN_mod_exp\n");
207         if (!test_mod_exp(out,ctx)) goto err;
208         fflush(stdout);
209
210 /**/
211         exit(0);
212 err:
213         ERR_load_crypto_strings();
214         ERR_print_errors(out);
215         exit(1);
216         return(1);
217         }
218
219 int test_add(bp)
220 BIO *bp;
221         {
222         BIGNUM *a,*b,*c;
223         int i;
224         int j;
225
226         a=BN_new();
227         b=BN_new();
228         c=BN_new();
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                 }
253         BN_free(a);
254         BN_free(b);
255         BN_free(c);
256         return(1);
257         }
258
259 int test_sub(bp)
260 BIO *bp;
261         {
262         BIGNUM *a,*b,*c;
263         int i;
264         int j;
265
266         a=BN_new();
267         b=BN_new();
268         c=BN_new();
269
270         BN_rand(a,512,0,0);
271         for (i=0; i<100; i++)
272                 {
273                 BN_rand(b,400+i,0,0);
274                 a->neg=rand_neg();
275                 b->neg=rand_neg();
276                 if (bp == NULL)
277                         for (j=0; j<10000; j++)
278                                 BN_sub(c,a,b);
279                 BN_sub(c,a,b);
280                 if (bp != NULL)
281                         {
282                         if (!results)
283                                 {
284                                 BN_print(bp,a);
285                                 BIO_puts(bp," - ");
286                                 BN_print(bp,b);
287                                 BIO_puts(bp," - ");
288                                 }
289                         BN_print(bp,c);
290                         BIO_puts(bp,"\n");
291                         }
292                 }
293         BN_free(a);
294         BN_free(b);
295         BN_free(c);
296         return(1);
297         }
298
299 int test_div(bp,ctx)
300 BIO *bp;
301 BN_CTX *ctx;
302         {
303         BIGNUM *a,*b,*c,*d;
304         int i;
305         int j;
306
307         a=BN_new();
308         b=BN_new();
309         c=BN_new();
310         d=BN_new();
311
312         BN_rand(a,400,0,0);
313         for (i=0; i<100; i++)
314                 {
315                 BN_rand(b,50+i,0,0);
316                 a->neg=rand_neg();
317                 b->neg=rand_neg();
318                 if (bp == NULL)
319                         for (j=0; j<100; j++)
320                                 BN_div(d,c,a,b,ctx);
321                 BN_div(d,c,a,b,ctx);
322                 if (bp != NULL)
323                         {
324                         if (!results)
325                                 {
326                                 BN_print(bp,a);
327                                 BIO_puts(bp," / ");
328                                 BN_print(bp,b);
329                                 BIO_puts(bp," - ");
330                                 }
331                         BN_print(bp,d);
332                         BIO_puts(bp,"\n");
333
334                         if (!results)
335                                 {
336                                 BN_print(bp,a);
337                                 BIO_puts(bp," % ");
338                                 BN_print(bp,b);
339                                 BIO_puts(bp," - ");
340                                 }
341                         BN_print(bp,c);
342                         BIO_puts(bp,"\n");
343                         }
344                 }
345         BN_free(a);
346         BN_free(b);
347         BN_free(c);
348         BN_free(d);
349         return(1);
350         }
351
352 int test_mul(bp)
353 BIO *bp;
354         {
355         BIGNUM *a,*b,*c;
356         int i;
357         int j;
358
359         a=BN_new();
360         b=BN_new();
361         c=BN_new();
362
363         BN_rand(a,200,0,0);
364         for (i=0; i<100; i++)
365                 {
366                 BN_rand(b,250+i,0,0);
367                 a->neg=rand_neg();
368                 b->neg=rand_neg();
369                 if (bp == NULL)
370                         for (j=0; j<100; j++)
371                                 BN_mul(c,a,b);
372                 BN_mul(c,a,b);
373                 if (bp != NULL)
374                         {
375                         if (!results)
376                                 {
377                                 BN_print(bp,a);
378                                 BIO_puts(bp," * ");
379                                 BN_print(bp,b);
380                                 BIO_puts(bp," - ");
381                                 }
382                         BN_print(bp,c);
383                         BIO_puts(bp,"\n");
384                         }
385                 }
386         BN_free(a);
387         BN_free(b);
388         BN_free(c);
389         return(1);
390         }
391
392 int test_sqr(bp,ctx)
393 BIO *bp;
394 BN_CTX *ctx;
395         {
396         BIGNUM *a,*c;
397         int i;
398         int j;
399
400         a=BN_new();
401         c=BN_new();
402
403         for (i=0; i<40; i++)
404                 {
405                 BN_rand(a,40+i*10,0,0);
406                 a->neg=rand_neg();
407                 if (bp == NULL)
408                         for (j=0; j<100; j++)
409                                 BN_sqr(c,a,ctx);
410                 BN_sqr(c,a,ctx);
411                 if (bp != NULL)
412                         {
413                         if (!results)
414                                 {
415                                 BN_print(bp,a);
416                                 BIO_puts(bp," * ");
417                                 BN_print(bp,a);
418                                 BIO_puts(bp," - ");
419                                 }
420                         BN_print(bp,c);
421                         BIO_puts(bp,"\n");
422                         }
423                 }
424         BN_free(a);
425         BN_free(c);
426         return(1);
427         }
428
429 int test_mont(bp,ctx)
430 BIO *bp;
431 BN_CTX *ctx;
432         {
433         BIGNUM *a,*b,*c,*A,*B;
434         BIGNUM *n;
435         int i;
436         int j;
437         BN_MONT_CTX *mont;
438
439         a=BN_new();
440         b=BN_new();
441         c=BN_new();
442         A=BN_new();
443         B=BN_new();
444         n=BN_new();
445
446         mont=BN_MONT_CTX_new();
447
448         BN_rand(a,100,0,0); /**/
449         BN_rand(b,100,0,0); /**/
450         for (i=0; i<10; i++)
451                 {
452                 BN_rand(n,(100%BN_BITS2+1)*BN_BITS2*i*BN_BITS2,0,1); /**/
453                 BN_MONT_CTX_set(mont,n,ctx);
454
455                 BN_to_montgomery(A,a,mont,ctx);
456                 BN_to_montgomery(B,b,mont,ctx);
457
458                 if (bp == NULL)
459                         for (j=0; j<100; j++)
460                                 BN_mod_mul_montgomery(c,A,B,mont,ctx);/**/
461                 BN_mod_mul_montgomery(c,A,B,mont,ctx);/**/
462                 BN_from_montgomery(A,c,mont,ctx);/**/
463                 if (bp != NULL)
464                         {
465                         if (!results)
466                                 {
467 #ifdef undef
468 fprintf(stderr,"%d * %d %% %d\n",
469 BN_num_bits(a),
470 BN_num_bits(b),
471 BN_num_bits(mont->N));
472 #endif
473                                 BN_print(bp,a);
474                                 BIO_puts(bp," * ");
475                                 BN_print(bp,b);
476                                 BIO_puts(bp," % ");
477                                 BN_print(bp,mont->N);
478                                 BIO_puts(bp," - ");
479                                 }
480                         BN_print(bp,A);
481                         BIO_puts(bp,"\n");
482                         }
483                 }
484         BN_MONT_CTX_free(mont);
485         BN_free(a);
486         BN_free(b);
487         BN_free(c);
488         return(1);
489         }
490
491 int test_mod(bp,ctx)
492 BIO *bp;
493 BN_CTX *ctx;
494         {
495         BIGNUM *a,*b,*c;
496         int i;
497         int j;
498
499         a=BN_new();
500         b=BN_new();
501         c=BN_new();
502
503         BN_rand(a,1024,0,0); /**/
504         for (i=0; i<20; i++)
505                 {
506                 BN_rand(b,450+i*10,0,0); /**/
507                 a->neg=rand_neg();
508                 b->neg=rand_neg();
509                 if (bp == NULL)
510                         for (j=0; j<100; j++)
511                                 BN_mod(c,a,b,ctx);/**/
512                 BN_mod(c,a,b,ctx);/**/
513                 if (bp != NULL)
514                         {
515                         if (!results)
516                                 {
517                                 BN_print(bp,a);
518                                 BIO_puts(bp," % ");
519                                 BN_print(bp,b);
520                                 BIO_puts(bp," - ");
521                                 }
522                         BN_print(bp,c);
523                         BIO_puts(bp,"\n");
524                         }
525                 }
526         BN_free(a);
527         BN_free(b);
528         BN_free(c);
529         return(1);
530         }
531
532 int test_mod_mul(bp,ctx)
533 BIO *bp;
534 BN_CTX *ctx;
535         {
536         BIGNUM *a,*b,*c,*d,*e;
537         int i;
538
539         a=BN_new();
540         b=BN_new();
541         c=BN_new();
542         d=BN_new();
543         e=BN_new();
544
545         BN_rand(c,1024,0,0); /**/
546         for (i=0; i<10; i++)
547                 {
548                 BN_rand(a,475+i*10,0,0); /**/
549                 BN_rand(b,425+i*10,0,0); /**/
550                 a->neg=rand_neg();
551                 b->neg=rand_neg();
552         /*      if (bp == NULL)
553                         for (j=0; j<100; j++)
554                                 BN_mod_mul(d,a,b,c,ctx);*/ /**/
555
556                 if (!BN_mod_mul(e,a,b,c,ctx))
557                         {
558                         unsigned long l;
559
560                         while ((l=ERR_get_error()))
561                                 fprintf(stderr,"ERROR:%s\n",
562                                         ERR_error_string(l,NULL));
563                         exit(1);
564                         }
565                 if (bp != NULL)
566                         {
567                         if (!results)
568                                 {
569                                 BN_print(bp,a);
570                                 BIO_puts(bp," * ");
571                                 BN_print(bp,b);
572                                 BIO_puts(bp," % ");
573                                 BN_print(bp,c);
574                                 BIO_puts(bp," - ");
575                                 }
576                         BN_print(bp,e);
577                         BIO_puts(bp,"\n");
578                         }
579                 }
580         BN_free(a);
581         BN_free(b);
582         BN_free(c);
583         BN_free(d);
584         BN_free(e);
585         return(1);
586         }
587
588 int test_mod_exp(bp,ctx)
589 BIO *bp;
590 BN_CTX *ctx;
591         {
592         BIGNUM *a,*b,*c,*d,*e;
593         int i;
594
595         a=BN_new();
596         b=BN_new();
597         c=BN_new();
598         d=BN_new();
599         e=BN_new();
600
601         BN_rand(c,30,0,1); /* must be odd for montgomery */
602         for (i=0; i<6; i++)
603                 {
604                 BN_rand(a,20+i*5,0,0); /**/
605                 BN_rand(b,2+i,0,0); /**/
606
607                 if (!BN_mod_exp(d,a,b,c,ctx))
608                         return(00);
609
610                 if (bp != NULL)
611                         {
612                         if (!results)
613                                 {
614                                 BN_print(bp,a);
615                                 BIO_puts(bp," ^ ");
616                                 BN_print(bp,b);
617                                 BIO_puts(bp," % ");
618                                 BN_print(bp,c);
619                                 BIO_puts(bp," - ");
620                                 }
621                         BN_print(bp,d);
622                         BIO_puts(bp,"\n");
623                         }
624                 }
625         BN_free(a);
626         BN_free(b);
627         BN_free(c);
628         BN_free(d);
629         BN_free(e);
630         return(1);
631         }
632
633 int test_lshift(bp)
634 BIO *bp;
635         {
636         BIGNUM *a,*b,*c;
637         int i;
638
639         a=BN_new();
640         b=BN_new();
641         c=BN_new();
642         BN_one(c);
643
644         BN_rand(a,200,0,0); /**/
645         a->neg=rand_neg();
646         for (i=0; i<70; i++)
647                 {
648                 BN_lshift(b,a,i+1);
649                 BN_add(c,c,c);
650                 if (bp != NULL)
651                         {
652                         if (!results)
653                                 {
654                                 BN_print(bp,a);
655                                 BIO_puts(bp," * ");
656                                 BN_print(bp,c);
657                                 BIO_puts(bp," - ");
658                                 }
659                         BN_print(bp,b);
660                         BIO_puts(bp,"\n");
661                         }
662                 }
663         BN_free(a);
664         BN_free(b);
665         BN_free(c);
666         return(1);
667         }
668
669 int test_lshift1(bp)
670 BIO *bp;
671         {
672         BIGNUM *a,*b;
673         int i;
674
675         a=BN_new();
676         b=BN_new();
677
678         BN_rand(a,200,0,0); /**/
679         a->neg=rand_neg();
680         for (i=0; i<70; i++)
681                 {
682                 BN_lshift1(b,a);
683                 if (bp != NULL)
684                         {
685                         if (!results)
686                                 {
687                                 BN_print(bp,a);
688                                 BIO_puts(bp," * 2");
689                                 BIO_puts(bp," - ");
690                                 }
691                         BN_print(bp,b);
692                         BIO_puts(bp,"\n");
693                         }
694                 BN_copy(a,b);
695                 }
696         BN_free(a);
697         BN_free(b);
698         return(1);
699         }
700
701 int test_rshift(bp)
702 BIO *bp;
703         {
704         BIGNUM *a,*b,*c;
705         int i;
706
707         a=BN_new();
708         b=BN_new();
709         c=BN_new();
710         BN_one(c);
711
712         BN_rand(a,200,0,0); /**/
713         a->neg=rand_neg();
714         for (i=0; i<70; i++)
715                 {
716                 BN_rshift(b,a,i+1);
717                 BN_add(c,c,c);
718                 if (bp != NULL)
719                         {
720                         if (!results)
721                                 {
722                                 BN_print(bp,a);
723                                 BIO_puts(bp," / ");
724                                 BN_print(bp,c);
725                                 BIO_puts(bp," - ");
726                                 }
727                         BN_print(bp,b);
728                         BIO_puts(bp,"\n");
729                         }
730                 }
731         BN_free(a);
732         BN_free(b);
733         BN_free(c);
734         return(1);
735         }
736
737 int test_rshift1(bp)
738 BIO *bp;
739         {
740         BIGNUM *a,*b;
741         int i;
742
743         a=BN_new();
744         b=BN_new();
745
746         BN_rand(a,200,0,0); /**/
747         a->neg=rand_neg();
748         for (i=0; i<70; i++)
749                 {
750                 BN_rshift1(b,a);
751                 if (bp != NULL)
752                         {
753                         if (!results)
754                                 {
755                                 BN_print(bp,a);
756                                 BIO_puts(bp," / 2");
757                                 BIO_puts(bp," - ");
758                                 }
759                         BN_print(bp,b);
760                         BIO_puts(bp,"\n");
761                         }
762                 BN_copy(a,b);
763                 }
764         BN_free(a);
765         BN_free(b);
766         return(1);
767         }
768
769 int rand_neg()
770         {
771         static unsigned int neg=0;
772         static int sign[8]={0,0,0,1,1,0,1,1};
773
774         return(sign[(neg++)%8]);
775         }