Import of old SSLeay release: SSLeay 0.9.0b
[openssl.git] / crypto / bn / bntest.c
1 /* crypto/bn/bntest.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  * 
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  * 
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  * 
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from 
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  * 
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * 
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include "e_os.h"
63 #include "bio.h"
64 #include "bn.h"
65 #include "rand.h"
66 #include "x509.h"
67 #include "err.h"
68
69 #ifdef WINDOWS
70 #include "../bio/bss_file.c"
71 #endif
72
73 #ifndef NOPROTO
74 int test_add (BIO *bp);
75 int test_sub (BIO *bp);
76 int test_lshift1 (BIO *bp);
77 int test_lshift (BIO *bp);
78 int test_rshift1 (BIO *bp);
79 int test_rshift (BIO *bp);
80 int test_div (BIO *bp,BN_CTX *ctx);
81 int test_mul (BIO *bp);
82 int test_sqr (BIO *bp,BN_CTX *ctx);
83 int test_mont (BIO *bp,BN_CTX *ctx);
84 int test_mod (BIO *bp,BN_CTX *ctx);
85 int test_mod_mul (BIO *bp,BN_CTX *ctx);
86 int test_mod_exp (BIO *bp,BN_CTX *ctx);
87 int rand_neg(void);
88 #else
89 int test_add ();
90 int test_sub ();
91 int test_lshift1 ();
92 int test_lshift ();
93 int test_rshift1 ();
94 int test_rshift ();
95 int test_div ();
96 int test_mul ();
97 int test_sqr ();
98 int test_mont ();
99 int test_mod ();
100 int test_mod_mul ();
101 int test_mod_exp ();
102 int rand_neg();
103 #endif
104
105 static int results=0;
106
107 #ifdef NO_STDIO
108 #define APPS_WIN16
109 #include "bss_file.c"
110 #endif
111
112 int main(argc,argv)
113 int argc;
114 char *argv[];
115         {
116         BN_CTX *ctx;
117         BIO *out;
118         char *outfile=NULL;
119
120         srand((unsigned int)time(NULL));
121
122         argc--;
123         argv++;
124         while (argc >= 1)
125                 {
126                 if (strcmp(*argv,"-results") == 0)
127                         results=1;
128                 else if (strcmp(*argv,"-out") == 0)
129                         {
130                         if (--argc < 1) break;
131                         outfile= *(++argv);
132                         }
133                 argc--;
134                 argv++;
135                 }
136
137
138         ctx=BN_CTX_new();
139         if (ctx == NULL) exit(1);
140
141         out=BIO_new(BIO_s_file());
142         if (out == NULL) exit(1);
143         if (outfile == NULL)
144                 {
145                 BIO_set_fp(out,stdout,BIO_NOCLOSE);
146                 }
147         else
148                 {
149                 if (!BIO_write_filename(out,outfile))
150                         {
151                         perror(outfile);
152                         exit(1);
153                         }
154                 }
155
156         if (!results)
157                 BIO_puts(out,"obase=16\nibase=16\n");
158
159         fprintf(stderr,"test BN_add\n");
160         if (!test_add(out)) goto err;
161         fflush(stdout);
162
163         fprintf(stderr,"test BN_sub\n");
164         if (!test_sub(out)) goto err;
165         fflush(stdout);
166
167         fprintf(stderr,"test BN_lshift1\n");
168         if (!test_lshift1(out)) goto err;
169         fflush(stdout);
170
171         fprintf(stderr,"test BN_lshift\n");
172         if (!test_lshift(out)) goto err;
173         fflush(stdout);
174
175         fprintf(stderr,"test BN_rshift1\n");
176         if (!test_rshift1(out)) goto err;
177         fflush(stdout);
178
179         fprintf(stderr,"test BN_rshift\n");
180         if (!test_rshift(out)) goto err;
181         fflush(stdout);
182
183         fprintf(stderr,"test BN_sqr\n");
184         if (!test_sqr(out,ctx)) goto err;
185         fflush(stdout);
186
187         fprintf(stderr,"test BN_mul\n");
188         if (!test_mul(out)) goto err;
189         fflush(stdout);
190
191         fprintf(stderr,"test BN_div\n");
192         if (!test_div(out,ctx)) goto err;
193         fflush(stdout);
194
195         fprintf(stderr,"test BN_mod\n");
196         if (!test_mod(out,ctx)) goto err;
197         fflush(stdout);
198
199         fprintf(stderr,"test BN_mod_mul\n");
200         if (!test_mod_mul(out,ctx)) goto err;
201         fflush(stdout);
202
203 /*
204         fprintf(stderr,"test BN_mont\n");
205         if (!test_mont(out,ctx)) goto err;
206         fflush(stdout);
207 */
208         fprintf(stderr,"test BN_mod_exp\n");
209         if (!test_mod_exp(out,ctx)) goto err;
210         fflush(stdout);
211
212 /**/
213         exit(0);
214 err:
215         ERR_load_crypto_strings();
216         ERR_print_errors(out);
217         exit(1);
218         return(1);
219         }
220
221 int test_add(bp)
222 BIO *bp;
223         {
224         BIGNUM *a,*b,*c;
225         int i;
226         int j;
227
228         a=BN_new();
229         b=BN_new();
230         c=BN_new();
231
232         BN_rand(a,512,0,0);
233         for (i=0; i<100; i++)
234                 {
235                 BN_rand(b,450+i,0,0);
236                 a->neg=rand_neg();
237                 b->neg=rand_neg();
238                 if (bp == NULL)
239                         for (j=0; j<10000; j++)
240                                 BN_add(c,a,b);
241                 BN_add(c,a,b);
242                 if (bp != NULL)
243                         {
244                         if (!results)
245                                 {
246                                 BN_print(bp,a);
247                                 BIO_puts(bp," + ");
248                                 BN_print(bp,b);
249                                 BIO_puts(bp," - ");
250                                 }
251                         BN_print(bp,c);
252                         BIO_puts(bp,"\n");
253                         }
254                 }
255         BN_free(a);
256         BN_free(b);
257         BN_free(c);
258         return(1);
259         }
260
261 int test_sub(bp)
262 BIO *bp;
263         {
264         BIGNUM *a,*b,*c;
265         int i;
266         int j;
267
268         a=BN_new();
269         b=BN_new();
270         c=BN_new();
271
272         BN_rand(a,512,0,0);
273         for (i=0; i<100; i++)
274                 {
275                 BN_rand(b,400+i,0,0);
276                 a->neg=rand_neg();
277                 b->neg=rand_neg();
278                 if (bp == NULL)
279                         for (j=0; j<10000; j++)
280                                 BN_sub(c,a,b);
281                 BN_sub(c,a,b);
282                 if (bp != NULL)
283                         {
284                         if (!results)
285                                 {
286                                 BN_print(bp,a);
287                                 BIO_puts(bp," - ");
288                                 BN_print(bp,b);
289                                 BIO_puts(bp," - ");
290                                 }
291                         BN_print(bp,c);
292                         BIO_puts(bp,"\n");
293                         }
294                 }
295         BN_free(a);
296         BN_free(b);
297         BN_free(c);
298         return(1);
299         }
300
301 int test_div(bp,ctx)
302 BIO *bp;
303 BN_CTX *ctx;
304         {
305         BIGNUM *a,*b,*c,*d;
306         int i;
307         int j;
308
309         a=BN_new();
310         b=BN_new();
311         c=BN_new();
312         d=BN_new();
313
314         BN_rand(a,400,0,0);
315         for (i=0; i<100; i++)
316                 {
317                 BN_rand(b,50+i,0,0);
318                 a->neg=rand_neg();
319                 b->neg=rand_neg();
320                 if (bp == NULL)
321                         for (j=0; j<100; j++)
322                                 BN_div(d,c,a,b,ctx);
323                 BN_div(d,c,a,b,ctx);
324                 if (bp != NULL)
325                         {
326                         if (!results)
327                                 {
328                                 BN_print(bp,a);
329                                 BIO_puts(bp," / ");
330                                 BN_print(bp,b);
331                                 BIO_puts(bp," - ");
332                                 }
333                         BN_print(bp,d);
334                         BIO_puts(bp,"\n");
335
336                         if (!results)
337                                 {
338                                 BN_print(bp,a);
339                                 BIO_puts(bp," % ");
340                                 BN_print(bp,b);
341                                 BIO_puts(bp," - ");
342                                 }
343                         BN_print(bp,c);
344                         BIO_puts(bp,"\n");
345                         }
346                 }
347         BN_free(a);
348         BN_free(b);
349         BN_free(c);
350         BN_free(d);
351         return(1);
352         }
353
354 int test_mul(bp)
355 BIO *bp;
356         {
357         BIGNUM *a,*b,*c;
358         int i;
359         int j;
360
361         a=BN_new();
362         b=BN_new();
363         c=BN_new();
364
365         BN_rand(a,200,0,0);
366         for (i=0; i<100; i++)
367                 {
368                 BN_rand(b,250+i,0,0);
369                 a->neg=rand_neg();
370                 b->neg=rand_neg();
371                 if (bp == NULL)
372                         for (j=0; j<100; j++)
373                                 BN_mul(c,a,b);
374                 BN_mul(c,a,b);
375                 if (bp != NULL)
376                         {
377                         if (!results)
378                                 {
379                                 BN_print(bp,a);
380                                 BIO_puts(bp," * ");
381                                 BN_print(bp,b);
382                                 BIO_puts(bp," - ");
383                                 }
384                         BN_print(bp,c);
385                         BIO_puts(bp,"\n");
386                         }
387                 }
388         BN_free(a);
389         BN_free(b);
390         BN_free(c);
391         return(1);
392         }
393
394 int test_sqr(bp,ctx)
395 BIO *bp;
396 BN_CTX *ctx;
397         {
398         BIGNUM *a,*c;
399         int i;
400         int j;
401
402         a=BN_new();
403         c=BN_new();
404
405         for (i=0; i<40; i++)
406                 {
407                 BN_rand(a,40+i*10,0,0);
408                 a->neg=rand_neg();
409                 if (bp == NULL)
410                         for (j=0; j<100; j++)
411                                 BN_sqr(c,a,ctx);
412                 BN_sqr(c,a,ctx);
413                 if (bp != NULL)
414                         {
415                         if (!results)
416                                 {
417                                 BN_print(bp,a);
418                                 BIO_puts(bp," * ");
419                                 BN_print(bp,a);
420                                 BIO_puts(bp," - ");
421                                 }
422                         BN_print(bp,c);
423                         BIO_puts(bp,"\n");
424                         }
425                 }
426         BN_free(a);
427         BN_free(c);
428         return(1);
429         }
430
431 int test_mont(bp,ctx)
432 BIO *bp;
433 BN_CTX *ctx;
434         {
435         BIGNUM *a,*b,*c,*A,*B;
436         BIGNUM *n;
437         int i;
438         int j;
439         BN_MONT_CTX *mont;
440
441         a=BN_new();
442         b=BN_new();
443         c=BN_new();
444         A=BN_new();
445         B=BN_new();
446         n=BN_new();
447
448         mont=BN_MONT_CTX_new();
449
450         BN_rand(a,100,0,0); /**/
451         BN_rand(b,100,0,0); /**/
452         for (i=0; i<10; i++)
453                 {
454                 BN_rand(n,(100%BN_BITS2+1)*BN_BITS2*i*BN_BITS2,0,1); /**/
455                 BN_MONT_CTX_set(mont,n,ctx);
456
457                 BN_to_montgomery(A,a,mont,ctx);
458                 BN_to_montgomery(B,b,mont,ctx);
459
460                 if (bp == NULL)
461                         for (j=0; j<100; j++)
462                                 BN_mod_mul_montgomery(c,A,B,mont,ctx);/**/
463                 BN_mod_mul_montgomery(c,A,B,mont,ctx);/**/
464                 BN_from_montgomery(A,c,mont,ctx);/**/
465                 if (bp != NULL)
466                         {
467                         if (!results)
468                                 {
469 #ifdef undef
470 fprintf(stderr,"%d * %d %% %d\n",
471 BN_num_bits(a),
472 BN_num_bits(b),
473 BN_num_bits(mont->N));
474 #endif
475                                 BN_print(bp,a);
476                                 BIO_puts(bp," * ");
477                                 BN_print(bp,b);
478                                 BIO_puts(bp," % ");
479                                 BN_print(bp,mont->N);
480                                 BIO_puts(bp," - ");
481                                 }
482                         BN_print(bp,A);
483                         BIO_puts(bp,"\n");
484                         }
485                 }
486         BN_MONT_CTX_free(mont);
487         BN_free(a);
488         BN_free(b);
489         BN_free(c);
490         return(1);
491         }
492
493 int test_mod(bp,ctx)
494 BIO *bp;
495 BN_CTX *ctx;
496         {
497         BIGNUM *a,*b,*c;
498         int i;
499         int j;
500
501         a=BN_new();
502         b=BN_new();
503         c=BN_new();
504
505         BN_rand(a,1024,0,0); /**/
506         for (i=0; i<20; i++)
507                 {
508                 BN_rand(b,450+i*10,0,0); /**/
509                 a->neg=rand_neg();
510                 b->neg=rand_neg();
511                 if (bp == NULL)
512                         for (j=0; j<100; j++)
513                                 BN_mod(c,a,b,ctx);/**/
514                 BN_mod(c,a,b,ctx);/**/
515                 if (bp != NULL)
516                         {
517                         if (!results)
518                                 {
519                                 BN_print(bp,a);
520                                 BIO_puts(bp," % ");
521                                 BN_print(bp,b);
522                                 BIO_puts(bp," - ");
523                                 }
524                         BN_print(bp,c);
525                         BIO_puts(bp,"\n");
526                         }
527                 }
528         BN_free(a);
529         BN_free(b);
530         BN_free(c);
531         return(1);
532         }
533
534 int test_mod_mul(bp,ctx)
535 BIO *bp;
536 BN_CTX *ctx;
537         {
538         BIGNUM *a,*b,*c,*d,*e;
539         int i;
540
541         a=BN_new();
542         b=BN_new();
543         c=BN_new();
544         d=BN_new();
545         e=BN_new();
546
547         BN_rand(c,1024,0,0); /**/
548         for (i=0; i<10; i++)
549                 {
550                 BN_rand(a,475+i*10,0,0); /**/
551                 BN_rand(b,425+i*10,0,0); /**/
552                 a->neg=rand_neg();
553                 b->neg=rand_neg();
554         /*      if (bp == NULL)
555                         for (j=0; j<100; j++)
556                                 BN_mod_mul(d,a,b,c,ctx);*/ /**/
557
558                 if (!BN_mod_mul(e,a,b,c,ctx))
559                         {
560                         unsigned long l;
561
562                         while ((l=ERR_get_error()))
563                                 fprintf(stderr,"ERROR:%s\n",
564                                         ERR_error_string(l,NULL));
565                         exit(1);
566                         }
567                 if (bp != NULL)
568                         {
569                         if (!results)
570                                 {
571                                 BN_print(bp,a);
572                                 BIO_puts(bp," * ");
573                                 BN_print(bp,b);
574                                 BIO_puts(bp," % ");
575                                 BN_print(bp,c);
576                                 BIO_puts(bp," - ");
577                                 }
578                         BN_print(bp,e);
579                         BIO_puts(bp,"\n");
580                         }
581                 }
582         BN_free(a);
583         BN_free(b);
584         BN_free(c);
585         BN_free(d);
586         BN_free(e);
587         return(1);
588         }
589
590 int test_mod_exp(bp,ctx)
591 BIO *bp;
592 BN_CTX *ctx;
593         {
594         BIGNUM *a,*b,*c,*d,*e;
595         int i;
596
597         a=BN_new();
598         b=BN_new();
599         c=BN_new();
600         d=BN_new();
601         e=BN_new();
602
603         BN_rand(c,30,0,1); /* must be odd for montgomery */
604         for (i=0; i<6; i++)
605                 {
606                 BN_rand(a,20+i*5,0,0); /**/
607                 BN_rand(b,2+i,0,0); /**/
608
609                 if (!BN_mod_exp(d,a,b,c,ctx))
610                         return(00);
611
612                 if (bp != NULL)
613                         {
614                         if (!results)
615                                 {
616                                 BN_print(bp,a);
617                                 BIO_puts(bp," ^ ");
618                                 BN_print(bp,b);
619                                 BIO_puts(bp," % ");
620                                 BN_print(bp,c);
621                                 BIO_puts(bp," - ");
622                                 }
623                         BN_print(bp,d);
624                         BIO_puts(bp,"\n");
625                         }
626                 }
627         BN_free(a);
628         BN_free(b);
629         BN_free(c);
630         BN_free(d);
631         BN_free(e);
632         return(1);
633         }
634
635 int test_lshift(bp)
636 BIO *bp;
637         {
638         BIGNUM *a,*b,*c;
639         int i;
640
641         a=BN_new();
642         b=BN_new();
643         c=BN_new();
644         BN_one(c);
645
646         BN_rand(a,200,0,0); /**/
647         a->neg=rand_neg();
648         for (i=0; i<70; i++)
649                 {
650                 BN_lshift(b,a,i+1);
651                 BN_add(c,c,c);
652                 if (bp != NULL)
653                         {
654                         if (!results)
655                                 {
656                                 BN_print(bp,a);
657                                 BIO_puts(bp," * ");
658                                 BN_print(bp,c);
659                                 BIO_puts(bp," - ");
660                                 }
661                         BN_print(bp,b);
662                         BIO_puts(bp,"\n");
663                         }
664                 }
665         BN_free(a);
666         BN_free(b);
667         BN_free(c);
668         return(1);
669         }
670
671 int test_lshift1(bp)
672 BIO *bp;
673         {
674         BIGNUM *a,*b;
675         int i;
676
677         a=BN_new();
678         b=BN_new();
679
680         BN_rand(a,200,0,0); /**/
681         a->neg=rand_neg();
682         for (i=0; i<70; i++)
683                 {
684                 BN_lshift1(b,a);
685                 if (bp != NULL)
686                         {
687                         if (!results)
688                                 {
689                                 BN_print(bp,a);
690                                 BIO_puts(bp," * 2");
691                                 BIO_puts(bp," - ");
692                                 }
693                         BN_print(bp,b);
694                         BIO_puts(bp,"\n");
695                         }
696                 BN_copy(a,b);
697                 }
698         BN_free(a);
699         BN_free(b);
700         return(1);
701         }
702
703 int test_rshift(bp)
704 BIO *bp;
705         {
706         BIGNUM *a,*b,*c;
707         int i;
708
709         a=BN_new();
710         b=BN_new();
711         c=BN_new();
712         BN_one(c);
713
714         BN_rand(a,200,0,0); /**/
715         a->neg=rand_neg();
716         for (i=0; i<70; i++)
717                 {
718                 BN_rshift(b,a,i+1);
719                 BN_add(c,c,c);
720                 if (bp != NULL)
721                         {
722                         if (!results)
723                                 {
724                                 BN_print(bp,a);
725                                 BIO_puts(bp," / ");
726                                 BN_print(bp,c);
727                                 BIO_puts(bp," - ");
728                                 }
729                         BN_print(bp,b);
730                         BIO_puts(bp,"\n");
731                         }
732                 }
733         BN_free(a);
734         BN_free(b);
735         BN_free(c);
736         return(1);
737         }
738
739 int test_rshift1(bp)
740 BIO *bp;
741         {
742         BIGNUM *a,*b;
743         int i;
744
745         a=BN_new();
746         b=BN_new();
747
748         BN_rand(a,200,0,0); /**/
749         a->neg=rand_neg();
750         for (i=0; i<70; i++)
751                 {
752                 BN_rshift1(b,a);
753                 if (bp != NULL)
754                         {
755                         if (!results)
756                                 {
757                                 BN_print(bp,a);
758                                 BIO_puts(bp," / 2");
759                                 BIO_puts(bp," - ");
760                                 }
761                         BN_print(bp,b);
762                         BIO_puts(bp,"\n");
763                         }
764                 BN_copy(a,b);
765                 }
766         BN_free(a);
767         BN_free(b);
768         return(1);
769         }
770
771 int rand_neg()
772         {
773         static unsigned int neg=0;
774         static int sign[8]={0,0,0,1,1,0,1,1};
775
776         return(sign[(neg++)%8]);
777         }