BN_div_word() was breaking when called from BN_bn2dec() (actually, this is
[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  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60  *
61  * Portions of the attached software ("Contribution") are developed by 
62  * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63  *
64  * The Contribution is licensed pursuant to the Eric Young open source
65  * license provided above.
66  *
67  * The binary polynomial arithmetic software is originally written by 
68  * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69  *
70  */
71
72 /* Until the key-gen callbacks are modified to use newer prototypes, we allow
73  * deprecated functions for openssl-internal code */
74 #ifdef OPENSSL_NO_DEPRECATED
75 #undef OPENSSL_NO_DEPRECATED
76 #endif
77
78 #include <stdio.h>
79 #include <stdlib.h>
80 #include <string.h>
81
82 #include "e_os.h"
83
84 #include <openssl/bio.h>
85 #include <openssl/bn.h>
86 #include <openssl/rand.h>
87 #include <openssl/x509.h>
88 #include <openssl/err.h>
89
90 const int num0 = 100; /* number of tests */
91 const int num1 = 50;  /* additional tests for some functions */
92 const int num2 = 5;   /* number of tests for slow functions */
93
94 int test_add(BIO *bp);
95 int test_sub(BIO *bp);
96 int test_lshift1(BIO *bp);
97 int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
98 int test_rshift1(BIO *bp);
99 int test_rshift(BIO *bp,BN_CTX *ctx);
100 int test_div(BIO *bp,BN_CTX *ctx);
101 int test_div_word(BIO *bp);
102 int test_div_recp(BIO *bp,BN_CTX *ctx);
103 int test_mul(BIO *bp);
104 int test_sqr(BIO *bp,BN_CTX *ctx);
105 int test_mont(BIO *bp,BN_CTX *ctx);
106 int test_mod(BIO *bp,BN_CTX *ctx);
107 int test_mod_mul(BIO *bp,BN_CTX *ctx);
108 int test_mod_exp(BIO *bp,BN_CTX *ctx);
109 int test_exp(BIO *bp,BN_CTX *ctx);
110 int test_gf2m_add(BIO *bp);
111 int test_gf2m_mod(BIO *bp);
112 int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx);
113 int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx);
114 int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx);
115 int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx);
116 int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx);
117 int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx);
118 int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx);
119 int test_kron(BIO *bp,BN_CTX *ctx);
120 int test_sqrt(BIO *bp,BN_CTX *ctx);
121 int rand_neg(void);
122 static int results=0;
123
124 static unsigned char lst[]="\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
125 "\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
126
127 static const char rnd_seed[] = "string to make the random number generator think it has entropy";
128
129 static void message(BIO *out, char *m)
130         {
131         fprintf(stderr, "test %s\n", m);
132         BIO_puts(out, "print \"test ");
133         BIO_puts(out, m);
134         BIO_puts(out, "\\n\"\n");
135         }
136
137 int main(int argc, char *argv[])
138         {
139         BN_CTX *ctx;
140         BIO *out;
141         char *outfile=NULL;
142
143         results = 0;
144
145         RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
146
147         argc--;
148         argv++;
149         while (argc >= 1)
150                 {
151                 if (strcmp(*argv,"-results") == 0)
152                         results=1;
153                 else if (strcmp(*argv,"-out") == 0)
154                         {
155                         if (--argc < 1) break;
156                         outfile= *(++argv);
157                         }
158                 argc--;
159                 argv++;
160                 }
161
162
163         ctx=BN_CTX_new();
164         if (ctx == NULL) EXIT(1);
165
166         out=BIO_new(BIO_s_file());
167         if (out == NULL) EXIT(1);
168         if (outfile == NULL)
169                 {
170                 BIO_set_fp(out,stdout,BIO_NOCLOSE);
171                 }
172         else
173                 {
174                 if (!BIO_write_filename(out,outfile))
175                         {
176                         perror(outfile);
177                         EXIT(1);
178                         }
179                 }
180
181         if (!results)
182                 BIO_puts(out,"obase=16\nibase=16\n");
183
184         message(out,"BN_add");
185         if (!test_add(out)) goto err;
186         BIO_flush(out);
187
188         message(out,"BN_sub");
189         if (!test_sub(out)) goto err;
190         BIO_flush(out);
191
192         message(out,"BN_lshift1");
193         if (!test_lshift1(out)) goto err;
194         BIO_flush(out);
195
196         message(out,"BN_lshift (fixed)");
197         if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
198             goto err;
199         BIO_flush(out);
200
201         message(out,"BN_lshift");
202         if (!test_lshift(out,ctx,NULL)) goto err;
203         BIO_flush(out);
204
205         message(out,"BN_rshift1");
206         if (!test_rshift1(out)) goto err;
207         BIO_flush(out);
208
209         message(out,"BN_rshift");
210         if (!test_rshift(out,ctx)) goto err;
211         BIO_flush(out);
212
213         message(out,"BN_sqr");
214         if (!test_sqr(out,ctx)) goto err;
215         BIO_flush(out);
216
217         message(out,"BN_mul");
218         if (!test_mul(out)) goto err;
219         BIO_flush(out);
220
221         message(out,"BN_div");
222         if (!test_div(out,ctx)) goto err;
223         BIO_flush(out);
224
225         message(out,"BN_div_word");
226         if (!test_div_word(out)) goto err;
227         BIO_flush(out);
228
229         message(out,"BN_div_recp");
230         if (!test_div_recp(out,ctx)) goto err;
231         BIO_flush(out);
232
233         message(out,"BN_mod");
234         if (!test_mod(out,ctx)) goto err;
235         BIO_flush(out);
236
237         message(out,"BN_mod_mul");
238         if (!test_mod_mul(out,ctx)) goto err;
239         BIO_flush(out);
240
241         message(out,"BN_mont");
242         if (!test_mont(out,ctx)) goto err;
243         BIO_flush(out);
244
245         message(out,"BN_mod_exp");
246         if (!test_mod_exp(out,ctx)) goto err;
247         BIO_flush(out);
248
249         message(out,"BN_exp");
250         if (!test_exp(out,ctx)) goto err;
251         BIO_flush(out);
252
253         message(out,"BN_kronecker");
254         if (!test_kron(out,ctx)) goto err;
255         BIO_flush(out);
256
257         message(out,"BN_mod_sqrt");
258         if (!test_sqrt(out,ctx)) goto err;
259         BIO_flush(out);
260
261         message(out,"BN_GF2m_add");
262         if (!test_gf2m_add(out)) goto err;
263         BIO_flush(out);
264
265         message(out,"BN_GF2m_mod");
266         if (!test_gf2m_mod(out)) goto err;
267         BIO_flush(out);
268
269         message(out,"BN_GF2m_mod_mul");
270         if (!test_gf2m_mod_mul(out,ctx)) goto err;
271         BIO_flush(out);
272
273         message(out,"BN_GF2m_mod_sqr");
274         if (!test_gf2m_mod_sqr(out,ctx)) goto err;
275         BIO_flush(out);
276
277         message(out,"BN_GF2m_mod_inv");
278         if (!test_gf2m_mod_inv(out,ctx)) goto err;
279         BIO_flush(out);
280
281         message(out,"BN_GF2m_mod_div");
282         if (!test_gf2m_mod_div(out,ctx)) goto err;
283         BIO_flush(out);
284
285         message(out,"BN_GF2m_mod_exp");
286         if (!test_gf2m_mod_exp(out,ctx)) goto err;
287         BIO_flush(out);
288
289         message(out,"BN_GF2m_mod_sqrt");
290         if (!test_gf2m_mod_sqrt(out,ctx)) goto err;
291         BIO_flush(out);
292
293         message(out,"BN_GF2m_mod_solve_quad");
294         if (!test_gf2m_mod_solve_quad(out,ctx)) goto err;
295         BIO_flush(out);
296
297         BN_CTX_free(ctx);
298         BIO_free(out);
299
300 /**/
301         EXIT(0);
302 err:
303         BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices
304                               * the failure, see test_bn in test/Makefile.ssl*/
305         BIO_flush(out);
306         ERR_load_crypto_strings();
307         ERR_print_errors_fp(stderr);
308         EXIT(1);
309         return(1);
310         }
311
312 int test_add(BIO *bp)
313         {
314         BIGNUM a,b,c;
315         int i;
316
317         BN_init(&a);
318         BN_init(&b);
319         BN_init(&c);
320
321         BN_bntest_rand(&a,512,0,0);
322         for (i=0; i<num0; i++)
323                 {
324                 BN_bntest_rand(&b,450+i,0,0);
325                 a.neg=rand_neg();
326                 b.neg=rand_neg();
327                 BN_add(&c,&a,&b);
328                 if (bp != NULL)
329                         {
330                         if (!results)
331                                 {
332                                 BN_print(bp,&a);
333                                 BIO_puts(bp," + ");
334                                 BN_print(bp,&b);
335                                 BIO_puts(bp," - ");
336                                 }
337                         BN_print(bp,&c);
338                         BIO_puts(bp,"\n");
339                         }
340                 a.neg=!a.neg;
341                 b.neg=!b.neg;
342                 BN_add(&c,&c,&b);
343                 BN_add(&c,&c,&a);
344                 if(!BN_is_zero(&c))
345                     {
346                     fprintf(stderr,"Add test failed!\n");
347                     return 0;
348                     }
349                 }
350         BN_free(&a);
351         BN_free(&b);
352         BN_free(&c);
353         return(1);
354         }
355
356 int test_sub(BIO *bp)
357         {
358         BIGNUM a,b,c;
359         int i;
360
361         BN_init(&a);
362         BN_init(&b);
363         BN_init(&c);
364
365         for (i=0; i<num0+num1; i++)
366                 {
367                 if (i < num1)
368                         {
369                         BN_bntest_rand(&a,512,0,0);
370                         BN_copy(&b,&a);
371                         if (BN_set_bit(&a,i)==0) return(0);
372                         BN_add_word(&b,i);
373                         }
374                 else
375                         {
376                         BN_bntest_rand(&b,400+i-num1,0,0);
377                         a.neg=rand_neg();
378                         b.neg=rand_neg();
379                         }
380                 BN_sub(&c,&a,&b);
381                 if (bp != NULL)
382                         {
383                         if (!results)
384                                 {
385                                 BN_print(bp,&a);
386                                 BIO_puts(bp," - ");
387                                 BN_print(bp,&b);
388                                 BIO_puts(bp," - ");
389                                 }
390                         BN_print(bp,&c);
391                         BIO_puts(bp,"\n");
392                         }
393                 BN_add(&c,&c,&b);
394                 BN_sub(&c,&c,&a);
395                 if(!BN_is_zero(&c))
396                     {
397                     fprintf(stderr,"Subtract test failed!\n");
398                     return 0;
399                     }
400                 }
401         BN_free(&a);
402         BN_free(&b);
403         BN_free(&c);
404         return(1);
405         }
406
407 int test_div(BIO *bp, BN_CTX *ctx)
408         {
409         BIGNUM a,b,c,d,e;
410         int i;
411
412         BN_init(&a);
413         BN_init(&b);
414         BN_init(&c);
415         BN_init(&d);
416         BN_init(&e);
417
418         for (i=0; i<num0+num1; i++)
419                 {
420                 if (i < num1)
421                         {
422                         BN_bntest_rand(&a,400,0,0);
423                         BN_copy(&b,&a);
424                         BN_lshift(&a,&a,i);
425                         BN_add_word(&a,i);
426                         }
427                 else
428                         BN_bntest_rand(&b,50+3*(i-num1),0,0);
429                 a.neg=rand_neg();
430                 b.neg=rand_neg();
431                 BN_div(&d,&c,&a,&b,ctx);
432                 if (bp != NULL)
433                         {
434                         if (!results)
435                                 {
436                                 BN_print(bp,&a);
437                                 BIO_puts(bp," / ");
438                                 BN_print(bp,&b);
439                                 BIO_puts(bp," - ");
440                                 }
441                         BN_print(bp,&d);
442                         BIO_puts(bp,"\n");
443
444                         if (!results)
445                                 {
446                                 BN_print(bp,&a);
447                                 BIO_puts(bp," % ");
448                                 BN_print(bp,&b);
449                                 BIO_puts(bp," - ");
450                                 }
451                         BN_print(bp,&c);
452                         BIO_puts(bp,"\n");
453                         }
454                 BN_mul(&e,&d,&b,ctx);
455                 BN_add(&d,&e,&c);
456                 BN_sub(&d,&d,&a);
457                 if(!BN_is_zero(&d))
458                     {
459                     fprintf(stderr,"Division test failed!\n");
460                     return 0;
461                     }
462                 }
463         BN_free(&a);
464         BN_free(&b);
465         BN_free(&c);
466         BN_free(&d);
467         BN_free(&e);
468         return(1);
469         }
470
471 int test_div_word(BIO *bp)
472         {
473         BIGNUM   a,b;
474         BN_ULONG r,s;
475         int i;
476
477         BN_init(&a);
478         BN_init(&b);
479
480         for (i=0; i<num0; i++)
481                 {
482                 do {
483                         BN_bntest_rand(&a,512,-1,0);
484                         BN_bntest_rand(&b,BN_BITS2,-1,0);
485                         s = b.d[0];
486                 } while (!s);
487
488                 BN_copy(&b, &a);
489                 r = BN_div_word(&b, s);
490
491                 if (bp != NULL)
492                         {
493                         if (!results)
494                                 {
495                                 BN_print(bp,&a);
496                                 BIO_puts(bp," / ");
497                                 BIO_printf(bp,"%lX",s);
498                                 BIO_puts(bp," - ");
499                                 }
500                         BN_print(bp,&b);
501                         BIO_puts(bp,"\n");
502
503                         if (!results)
504                                 {
505                                 BN_print(bp,&a);
506                                 BIO_puts(bp," % ");
507                                 BIO_printf(bp,"%lX",s);
508                                 BIO_puts(bp," - ");
509                                 }
510                         BIO_printf(bp,"%lX",r);
511                         BIO_puts(bp,"\n");
512                         }
513                 BN_mul_word(&b,s);
514                 BN_add_word(&b,r);
515                 BN_sub(&b,&a,&b);
516                 if(!BN_is_zero(&b))
517                     {
518                     fprintf(stderr,"Division (word) test failed!\n");
519                     return 0;
520                     }
521                 }
522         BN_free(&a);
523         BN_free(&b);
524         return(1);
525         }
526
527 int test_div_recp(BIO *bp, BN_CTX *ctx)
528         {
529         BIGNUM a,b,c,d,e;
530         BN_RECP_CTX recp;
531         int i;
532
533         BN_RECP_CTX_init(&recp);
534         BN_init(&a);
535         BN_init(&b);
536         BN_init(&c);
537         BN_init(&d);
538         BN_init(&e);
539
540         for (i=0; i<num0+num1; i++)
541                 {
542                 if (i < num1)
543                         {
544                         BN_bntest_rand(&a,400,0,0);
545                         BN_copy(&b,&a);
546                         BN_lshift(&a,&a,i);
547                         BN_add_word(&a,i);
548                         }
549                 else
550                         BN_bntest_rand(&b,50+3*(i-num1),0,0);
551                 a.neg=rand_neg();
552                 b.neg=rand_neg();
553                 BN_RECP_CTX_set(&recp,&b,ctx);
554                 BN_div_recp(&d,&c,&a,&recp,ctx);
555                 if (bp != NULL)
556                         {
557                         if (!results)
558                                 {
559                                 BN_print(bp,&a);
560                                 BIO_puts(bp," / ");
561                                 BN_print(bp,&b);
562                                 BIO_puts(bp," - ");
563                                 }
564                         BN_print(bp,&d);
565                         BIO_puts(bp,"\n");
566
567                         if (!results)
568                                 {
569                                 BN_print(bp,&a);
570                                 BIO_puts(bp," % ");
571                                 BN_print(bp,&b);
572                                 BIO_puts(bp," - ");
573                                 }
574                         BN_print(bp,&c);
575                         BIO_puts(bp,"\n");
576                         }
577                 BN_mul(&e,&d,&b,ctx);
578                 BN_add(&d,&e,&c);
579                 BN_sub(&d,&d,&a);
580                 if(!BN_is_zero(&d))
581                     {
582                     fprintf(stderr,"Reciprocal division test failed!\n");
583                     fprintf(stderr,"a=");
584                     BN_print_fp(stderr,&a);
585                     fprintf(stderr,"\nb=");
586                     BN_print_fp(stderr,&b);
587                     fprintf(stderr,"\n");
588                     return 0;
589                     }
590                 }
591         BN_free(&a);
592         BN_free(&b);
593         BN_free(&c);
594         BN_free(&d);
595         BN_free(&e);
596         BN_RECP_CTX_free(&recp);
597         return(1);
598         }
599
600 int test_mul(BIO *bp)
601         {
602         BIGNUM a,b,c,d,e;
603         int i;
604         BN_CTX *ctx;
605
606         ctx = BN_CTX_new();
607         if (ctx == NULL) EXIT(1);
608         
609         BN_init(&a);
610         BN_init(&b);
611         BN_init(&c);
612         BN_init(&d);
613         BN_init(&e);
614
615         for (i=0; i<num0+num1; i++)
616                 {
617                 if (i <= num1)
618                         {
619                         BN_bntest_rand(&a,100,0,0);
620                         BN_bntest_rand(&b,100,0,0);
621                         }
622                 else
623                         BN_bntest_rand(&b,i-num1,0,0);
624                 a.neg=rand_neg();
625                 b.neg=rand_neg();
626                 BN_mul(&c,&a,&b,ctx);
627                 if (bp != NULL)
628                         {
629                         if (!results)
630                                 {
631                                 BN_print(bp,&a);
632                                 BIO_puts(bp," * ");
633                                 BN_print(bp,&b);
634                                 BIO_puts(bp," - ");
635                                 }
636                         BN_print(bp,&c);
637                         BIO_puts(bp,"\n");
638                         }
639                 BN_div(&d,&e,&c,&a,ctx);
640                 BN_sub(&d,&d,&b);
641                 if(!BN_is_zero(&d) || !BN_is_zero(&e))
642                     {
643                     fprintf(stderr,"Multiplication test failed!\n");
644                     return 0;
645                     }
646                 }
647         BN_free(&a);
648         BN_free(&b);
649         BN_free(&c);
650         BN_free(&d);
651         BN_free(&e);
652         BN_CTX_free(ctx);
653         return(1);
654         }
655
656 int test_sqr(BIO *bp, BN_CTX *ctx)
657         {
658         BIGNUM a,c,d,e;
659         int i;
660
661         BN_init(&a);
662         BN_init(&c);
663         BN_init(&d);
664         BN_init(&e);
665
666         for (i=0; i<num0; i++)
667                 {
668                 BN_bntest_rand(&a,40+i*10,0,0);
669                 a.neg=rand_neg();
670                 BN_sqr(&c,&a,ctx);
671                 if (bp != NULL)
672                         {
673                         if (!results)
674                                 {
675                                 BN_print(bp,&a);
676                                 BIO_puts(bp," * ");
677                                 BN_print(bp,&a);
678                                 BIO_puts(bp," - ");
679                                 }
680                         BN_print(bp,&c);
681                         BIO_puts(bp,"\n");
682                         }
683                 BN_div(&d,&e,&c,&a,ctx);
684                 BN_sub(&d,&d,&a);
685                 if(!BN_is_zero(&d) || !BN_is_zero(&e))
686                     {
687                     fprintf(stderr,"Square test failed!\n");
688                     return 0;
689                     }
690                 }
691         BN_free(&a);
692         BN_free(&c);
693         BN_free(&d);
694         BN_free(&e);
695         return(1);
696         }
697
698 int test_mont(BIO *bp, BN_CTX *ctx)
699         {
700         BIGNUM a,b,c,d,A,B;
701         BIGNUM n;
702         int i;
703         BN_MONT_CTX *mont;
704
705         BN_init(&a);
706         BN_init(&b);
707         BN_init(&c);
708         BN_init(&d);
709         BN_init(&A);
710         BN_init(&B);
711         BN_init(&n);
712
713         mont=BN_MONT_CTX_new();
714
715         BN_bntest_rand(&a,100,0,0); /**/
716         BN_bntest_rand(&b,100,0,0); /**/
717         for (i=0; i<num2; i++)
718                 {
719                 int bits = (200*(i+1))/num2;
720
721                 if (bits == 0)
722                         continue;
723                 BN_bntest_rand(&n,bits,0,1);
724                 BN_MONT_CTX_set(mont,&n,ctx);
725
726                 BN_nnmod(&a,&a,&n,ctx);
727                 BN_nnmod(&b,&b,&n,ctx);
728
729                 BN_to_montgomery(&A,&a,mont,ctx);
730                 BN_to_montgomery(&B,&b,mont,ctx);
731
732                 BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
733                 BN_from_montgomery(&A,&c,mont,ctx);/**/
734                 if (bp != NULL)
735                         {
736                         if (!results)
737                                 {
738 #ifdef undef
739 fprintf(stderr,"%d * %d %% %d\n",
740 BN_num_bits(&a),
741 BN_num_bits(&b),
742 BN_num_bits(mont->N));
743 #endif
744                                 BN_print(bp,&a);
745                                 BIO_puts(bp," * ");
746                                 BN_print(bp,&b);
747                                 BIO_puts(bp," % ");
748                                 BN_print(bp,&(mont->N));
749                                 BIO_puts(bp," - ");
750                                 }
751                         BN_print(bp,&A);
752                         BIO_puts(bp,"\n");
753                         }
754                 BN_mod_mul(&d,&a,&b,&n,ctx);
755                 BN_sub(&d,&d,&A);
756                 if(!BN_is_zero(&d))
757                     {
758                     fprintf(stderr,"Montgomery multiplication test failed!\n");
759                     return 0;
760                     }
761                 }
762         BN_MONT_CTX_free(mont);
763         BN_free(&a);
764         BN_free(&b);
765         BN_free(&c);
766         BN_free(&d);
767         BN_free(&A);
768         BN_free(&B);
769         BN_free(&n);
770         return(1);
771         }
772
773 int test_mod(BIO *bp, BN_CTX *ctx)
774         {
775         BIGNUM *a,*b,*c,*d,*e;
776         int i;
777
778         a=BN_new();
779         b=BN_new();
780         c=BN_new();
781         d=BN_new();
782         e=BN_new();
783
784         BN_bntest_rand(a,1024,0,0); /**/
785         for (i=0; i<num0; i++)
786                 {
787                 BN_bntest_rand(b,450+i*10,0,0); /**/
788                 a->neg=rand_neg();
789                 b->neg=rand_neg();
790                 BN_mod(c,a,b,ctx);/**/
791                 if (bp != NULL)
792                         {
793                         if (!results)
794                                 {
795                                 BN_print(bp,a);
796                                 BIO_puts(bp," % ");
797                                 BN_print(bp,b);
798                                 BIO_puts(bp," - ");
799                                 }
800                         BN_print(bp,c);
801                         BIO_puts(bp,"\n");
802                         }
803                 BN_div(d,e,a,b,ctx);
804                 BN_sub(e,e,c);
805                 if(!BN_is_zero(e))
806                     {
807                     fprintf(stderr,"Modulo test failed!\n");
808                     return 0;
809                     }
810                 }
811         BN_free(a);
812         BN_free(b);
813         BN_free(c);
814         BN_free(d);
815         BN_free(e);
816         return(1);
817         }
818
819 int test_mod_mul(BIO *bp, BN_CTX *ctx)
820         {
821         BIGNUM *a,*b,*c,*d,*e;
822         int i,j;
823
824         a=BN_new();
825         b=BN_new();
826         c=BN_new();
827         d=BN_new();
828         e=BN_new();
829
830         for (j=0; j<3; j++) {
831         BN_bntest_rand(c,1024,0,0); /**/
832         for (i=0; i<num0; i++)
833                 {
834                 BN_bntest_rand(a,475+i*10,0,0); /**/
835                 BN_bntest_rand(b,425+i*11,0,0); /**/
836                 a->neg=rand_neg();
837                 b->neg=rand_neg();
838                 if (!BN_mod_mul(e,a,b,c,ctx))
839                         {
840                         unsigned long l;
841
842                         while ((l=ERR_get_error()))
843                                 fprintf(stderr,"ERROR:%s\n",
844                                         ERR_error_string(l,NULL));
845                         EXIT(1);
846                         }
847                 if (bp != NULL)
848                         {
849                         if (!results)
850                                 {
851                                 BN_print(bp,a);
852                                 BIO_puts(bp," * ");
853                                 BN_print(bp,b);
854                                 BIO_puts(bp," % ");
855                                 BN_print(bp,c);
856                                 if ((a->neg ^ b->neg) && !BN_is_zero(e))
857                                         {
858                                         /* If  (a*b) % c  is negative,  c  must be added
859                                          * in order to obtain the normalized remainder
860                                          * (new with OpenSSL 0.9.7, previous versions of
861                                          * BN_mod_mul could generate negative results)
862                                          */
863                                         BIO_puts(bp," + ");
864                                         BN_print(bp,c);
865                                         }
866                                 BIO_puts(bp," - ");
867                                 }
868                         BN_print(bp,e);
869                         BIO_puts(bp,"\n");
870                         }
871                 BN_mul(d,a,b,ctx);
872                 BN_sub(d,d,e);
873                 BN_div(a,b,d,c,ctx);
874                 if(!BN_is_zero(b))
875                     {
876                     fprintf(stderr,"Modulo multiply test failed!\n");
877                     ERR_print_errors_fp(stderr);
878                     return 0;
879                     }
880                 }
881         }
882         BN_free(a);
883         BN_free(b);
884         BN_free(c);
885         BN_free(d);
886         BN_free(e);
887         return(1);
888         }
889
890 int test_mod_exp(BIO *bp, BN_CTX *ctx)
891         {
892         BIGNUM *a,*b,*c,*d,*e;
893         int i;
894
895         a=BN_new();
896         b=BN_new();
897         c=BN_new();
898         d=BN_new();
899         e=BN_new();
900
901         BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
902         for (i=0; i<num2; i++)
903                 {
904                 BN_bntest_rand(a,20+i*5,0,0); /**/
905                 BN_bntest_rand(b,2+i,0,0); /**/
906
907                 if (!BN_mod_exp(d,a,b,c,ctx))
908                         return(00);
909
910                 if (bp != NULL)
911                         {
912                         if (!results)
913                                 {
914                                 BN_print(bp,a);
915                                 BIO_puts(bp," ^ ");
916                                 BN_print(bp,b);
917                                 BIO_puts(bp," % ");
918                                 BN_print(bp,c);
919                                 BIO_puts(bp," - ");
920                                 }
921                         BN_print(bp,d);
922                         BIO_puts(bp,"\n");
923                         }
924                 BN_exp(e,a,b,ctx);
925                 BN_sub(e,e,d);
926                 BN_div(a,b,e,c,ctx);
927                 if(!BN_is_zero(b))
928                     {
929                     fprintf(stderr,"Modulo exponentiation test failed!\n");
930                     return 0;
931                     }
932                 }
933         BN_free(a);
934         BN_free(b);
935         BN_free(c);
936         BN_free(d);
937         BN_free(e);
938         return(1);
939         }
940
941 int test_exp(BIO *bp, BN_CTX *ctx)
942         {
943         BIGNUM *a,*b,*d,*e,*one;
944         int i;
945
946         a=BN_new();
947         b=BN_new();
948         d=BN_new();
949         e=BN_new();
950         one=BN_new();
951         BN_one(one);
952
953         for (i=0; i<num2; i++)
954                 {
955                 BN_bntest_rand(a,20+i*5,0,0); /**/
956                 BN_bntest_rand(b,2+i,0,0); /**/
957
958                 if (!BN_exp(d,a,b,ctx))
959                         return(00);
960
961                 if (bp != NULL)
962                         {
963                         if (!results)
964                                 {
965                                 BN_print(bp,a);
966                                 BIO_puts(bp," ^ ");
967                                 BN_print(bp,b);
968                                 BIO_puts(bp," - ");
969                                 }
970                         BN_print(bp,d);
971                         BIO_puts(bp,"\n");
972                         }
973                 BN_one(e);
974                 for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
975                     BN_mul(e,e,a,ctx);
976                 BN_sub(e,e,d);
977                 if(!BN_is_zero(e))
978                     {
979                     fprintf(stderr,"Exponentiation test failed!\n");
980                     return 0;
981                     }
982                 }
983         BN_free(a);
984         BN_free(b);
985         BN_free(d);
986         BN_free(e);
987         BN_free(one);
988         return(1);
989         }
990
991 int test_gf2m_add(BIO *bp)
992         {
993         BIGNUM a,b,c;
994         int i, ret = 0;
995
996         BN_init(&a);
997         BN_init(&b);
998         BN_init(&c);
999
1000         for (i=0; i<num0; i++)
1001                 {
1002                 BN_rand(&a,512,0,0);
1003                 BN_copy(&b, BN_value_one());
1004                 a.neg=rand_neg();
1005                 b.neg=rand_neg();
1006                 BN_GF2m_add(&c,&a,&b);
1007 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1008                 if (bp != NULL)
1009                         {
1010                         if (!results)
1011                                 {
1012                                 BN_print(bp,&a);
1013                                 BIO_puts(bp," ^ ");
1014                                 BN_print(bp,&b);
1015                                 BIO_puts(bp," = ");
1016                                 }
1017                         BN_print(bp,&c);
1018                         BIO_puts(bp,"\n");
1019                         }
1020 #endif
1021                 /* Test that two added values have the correct parity. */
1022                 if((BN_is_odd(&a) && BN_is_odd(&c)) || (!BN_is_odd(&a) && !BN_is_odd(&c)))
1023                         {
1024                     fprintf(stderr,"GF(2^m) addition test (a) failed!\n");
1025                         goto err;
1026                         }
1027                 BN_GF2m_add(&c,&c,&c);
1028                 /* Test that c + c = 0. */
1029                 if(!BN_is_zero(&c))
1030                     {
1031                     fprintf(stderr,"GF(2^m) addition test (b) failed!\n");
1032                         goto err;
1033                     }
1034                 }
1035         ret = 1;
1036   err:
1037         BN_free(&a);
1038         BN_free(&b);
1039         BN_free(&c);
1040         return ret;
1041         }
1042
1043 int test_gf2m_mod(BIO *bp)
1044         {
1045         BIGNUM *a,*b[2],*c,*d,*e;
1046         int i, j, ret = 0;
1047         unsigned int p0[] = {163,7,6,3,0};
1048         unsigned int p1[] = {193,15,0};
1049
1050         a=BN_new();
1051         b[0]=BN_new();
1052         b[1]=BN_new();
1053         c=BN_new();
1054         d=BN_new();
1055         e=BN_new();
1056
1057         BN_GF2m_arr2poly(p0, b[0]);
1058         BN_GF2m_arr2poly(p1, b[1]);
1059
1060         for (i=0; i<num0; i++)
1061                 {
1062                 BN_bntest_rand(a, 1024, 0, 0);
1063                 for (j=0; j < 2; j++)
1064                         {
1065                         BN_GF2m_mod(c, a, b[j]);
1066 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1067                         if (bp != NULL)
1068                                 {
1069                                 if (!results)
1070                                         {
1071                                         BN_print(bp,a);
1072                                         BIO_puts(bp," % ");
1073                                         BN_print(bp,b[j]);
1074                                         BIO_puts(bp," - ");
1075                                         BN_print(bp,c);
1076                                         BIO_puts(bp,"\n");
1077                                         }
1078                                 }
1079 #endif
1080                         BN_GF2m_add(d, a, c);
1081                         BN_GF2m_mod(e, d, b[j]);
1082                         /* Test that a + (a mod p) mod p == 0. */
1083                         if(!BN_is_zero(e))
1084                                 {
1085                                 fprintf(stderr,"GF(2^m) modulo test failed!\n");
1086                                 goto err;
1087                                 }
1088                         }
1089                 }
1090         ret = 1;
1091   err:
1092         BN_free(a);
1093         BN_free(b[0]);
1094         BN_free(b[1]);
1095         BN_free(c);
1096         BN_free(d);
1097         BN_free(e);
1098         return ret;
1099         }
1100
1101 int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx)
1102         {
1103         BIGNUM *a,*b[2],*c,*d,*e,*f,*g,*h;
1104         int i, j, ret = 0;
1105         unsigned int p0[] = {163,7,6,3,0};
1106         unsigned int p1[] = {193,15,0};
1107
1108         a=BN_new();
1109         b[0]=BN_new();
1110         b[1]=BN_new();
1111         c=BN_new();
1112         d=BN_new();
1113         e=BN_new();
1114         f=BN_new();
1115         g=BN_new();
1116         h=BN_new();
1117
1118         BN_GF2m_arr2poly(p0, b[0]);
1119         BN_GF2m_arr2poly(p1, b[1]);
1120
1121         for (i=0; i<num0; i++)
1122                 {
1123                 BN_bntest_rand(a, 1024, 0, 0);
1124                 BN_bntest_rand(c, 1024, 0, 0);
1125                 BN_bntest_rand(d, 1024, 0, 0);
1126                 for (j=0; j < 2; j++)
1127                         {
1128                         BN_GF2m_mod_mul(e, a, c, b[j], ctx);
1129 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1130                         if (bp != NULL)
1131                                 {
1132                                 if (!results)
1133                                         {
1134                                         BN_print(bp,a);
1135                                         BIO_puts(bp," * ");
1136                                         BN_print(bp,c);
1137                                         BIO_puts(bp," % ");
1138                                         BN_print(bp,b[j]);
1139                                         BIO_puts(bp," - ");
1140                                         BN_print(bp,e);
1141                                         BIO_puts(bp,"\n");
1142                                         }
1143                                 }
1144 #endif
1145                         BN_GF2m_add(f, a, d);
1146                         BN_GF2m_mod_mul(g, f, c, b[j], ctx);
1147                         BN_GF2m_mod_mul(h, d, c, b[j], ctx);
1148                         BN_GF2m_add(f, e, g);
1149                         BN_GF2m_add(f, f, h);
1150                         /* Test that (a+d)*c = a*c + d*c. */
1151                         if(!BN_is_zero(f))
1152                                 {
1153                                 fprintf(stderr,"GF(2^m) modular multiplication test failed!\n");
1154                                 goto err;
1155                                 }
1156                         }
1157                 }
1158         ret = 1;
1159   err:
1160         BN_free(a);
1161         BN_free(b[0]);
1162         BN_free(b[1]);
1163         BN_free(c);
1164         BN_free(d);
1165         BN_free(e);
1166         BN_free(f);
1167         BN_free(g);
1168         BN_free(h);
1169         return ret;
1170         }
1171
1172 int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx)
1173         {
1174         BIGNUM *a,*b[2],*c,*d;
1175         int i, j, ret = 0;
1176         unsigned int p0[] = {163,7,6,3,0};
1177         unsigned int p1[] = {193,15,0};
1178
1179         a=BN_new();
1180         b[0]=BN_new();
1181         b[1]=BN_new();
1182         c=BN_new();
1183         d=BN_new();
1184
1185         BN_GF2m_arr2poly(p0, b[0]);
1186         BN_GF2m_arr2poly(p1, b[1]);
1187
1188         for (i=0; i<num0; i++)
1189                 {
1190                 BN_bntest_rand(a, 1024, 0, 0);
1191                 for (j=0; j < 2; j++)
1192                         {
1193                         BN_GF2m_mod_sqr(c, a, b[j], ctx);
1194                         BN_copy(d, a);
1195                         BN_GF2m_mod_mul(d, a, d, b[j], ctx);
1196 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1197                         if (bp != NULL)
1198                                 {
1199                                 if (!results)
1200                                         {
1201                                         BN_print(bp,a);
1202                                         BIO_puts(bp," ^ 2 % ");
1203                                         BN_print(bp,b[j]);
1204                                         BIO_puts(bp, " = ");
1205                                         BN_print(bp,c);
1206                                         BIO_puts(bp,"; a * a = ");
1207                                         BN_print(bp,d);
1208                                         BIO_puts(bp,"\n");
1209                                         }
1210                                 }
1211 #endif
1212                         BN_GF2m_add(d, c, d);
1213                         /* Test that a*a = a^2. */
1214                         if(!BN_is_zero(d))
1215                                 {
1216                                 fprintf(stderr,"GF(2^m) modular squaring test failed!\n");
1217                                 goto err;
1218                                 }
1219                         }
1220                 }
1221         ret = 1;
1222   err:
1223         BN_free(a);
1224         BN_free(b[0]);
1225         BN_free(b[1]);
1226         BN_free(c);
1227         BN_free(d);
1228         return ret;
1229         }
1230
1231 int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx)
1232         {
1233         BIGNUM *a,*b[2],*c,*d;
1234         int i, j, ret = 0;
1235         unsigned int p0[] = {163,7,6,3,0};
1236         unsigned int p1[] = {193,15,0};
1237
1238         a=BN_new();
1239         b[0]=BN_new();
1240         b[1]=BN_new();
1241         c=BN_new();
1242         d=BN_new();
1243
1244         BN_GF2m_arr2poly(p0, b[0]);
1245         BN_GF2m_arr2poly(p1, b[1]);
1246
1247         for (i=0; i<num0; i++)
1248                 {
1249                 BN_bntest_rand(a, 512, 0, 0); 
1250                 for (j=0; j < 2; j++)
1251                         {
1252                         BN_GF2m_mod_inv(c, a, b[j], ctx);
1253                         BN_GF2m_mod_mul(d, a, c, b[j], ctx);
1254 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1255                         if (bp != NULL)
1256                                 {
1257                                 if (!results)
1258                                         {
1259                                         BN_print(bp,a);
1260                                         BIO_puts(bp, " * ");
1261                                         BN_print(bp,c);
1262                                         BIO_puts(bp," - 1 % ");
1263                                         BN_print(bp,b[j]);
1264                                         BIO_puts(bp,"\n");
1265                                         }
1266                                 }
1267 #endif
1268                         /* Test that ((1/a)*a) = 1. */
1269                         if(!BN_is_one(d))
1270                                 {
1271                                 fprintf(stderr,"GF(2^m) modular inversion test failed!\n");
1272                                 goto err;
1273                                 }
1274                         }
1275                 }
1276         ret = 1;
1277   err:
1278         BN_free(a);
1279         BN_free(b[0]);
1280         BN_free(b[1]);
1281         BN_free(c);
1282         BN_free(d);
1283         return ret;
1284         }
1285
1286 int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx)
1287         {
1288         BIGNUM *a,*b[2],*c,*d,*e,*f;
1289         int i, j, ret = 0;
1290         unsigned int p0[] = {163,7,6,3,0};
1291         unsigned int p1[] = {193,15,0};
1292
1293         a=BN_new();
1294         b[0]=BN_new();
1295         b[1]=BN_new();
1296         c=BN_new();
1297         d=BN_new();
1298         e=BN_new();
1299         f=BN_new();
1300
1301         BN_GF2m_arr2poly(p0, b[0]);
1302         BN_GF2m_arr2poly(p1, b[1]);
1303
1304         for (i=0; i<num0; i++)
1305                 {
1306                 BN_bntest_rand(a, 512, 0, 0); 
1307                 BN_bntest_rand(c, 512, 0, 0);
1308                 for (j=0; j < 2; j++)
1309                         {
1310                         BN_GF2m_mod_div(d, a, c, b[j], ctx);
1311                         BN_GF2m_mod_mul(e, d, c, b[j], ctx);
1312                         BN_GF2m_mod_div(f, a, e, b[j], ctx);
1313 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1314                         if (bp != NULL)
1315                                 {
1316                                 if (!results)
1317                                         {
1318                                         BN_print(bp,a);
1319                                         BIO_puts(bp, " = ");
1320                                         BN_print(bp,c);
1321                                         BIO_puts(bp," * ");
1322                                         BN_print(bp,d);
1323                                         BIO_puts(bp, " % ");
1324                                         BN_print(bp,b[j]);
1325                                         BIO_puts(bp,"\n");
1326                                         }
1327                                 }
1328 #endif
1329                         /* Test that ((a/c)*c)/a = 1. */
1330                         if(!BN_is_one(f))
1331                                 {
1332                                 fprintf(stderr,"GF(2^m) modular division test failed!\n");
1333                                 goto err;
1334                                 }
1335                         }
1336                 }
1337         ret = 1;
1338   err:
1339         BN_free(a);
1340         BN_free(b[0]);
1341         BN_free(b[1]);
1342         BN_free(c);
1343         BN_free(d);
1344         BN_free(e);
1345         BN_free(f);
1346         return ret;
1347         }
1348
1349 int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx)
1350         {
1351         BIGNUM *a,*b[2],*c,*d,*e,*f;
1352         int i, j, ret = 0;
1353         unsigned int p0[] = {163,7,6,3,0};
1354         unsigned int p1[] = {193,15,0};
1355
1356         a=BN_new();
1357         b[0]=BN_new();
1358         b[1]=BN_new();
1359         c=BN_new();
1360         d=BN_new();
1361         e=BN_new();
1362         f=BN_new();
1363
1364         BN_GF2m_arr2poly(p0, b[0]);
1365         BN_GF2m_arr2poly(p1, b[1]);
1366
1367         for (i=0; i<num0; i++)
1368                 {
1369                 BN_bntest_rand(a, 512, 0, 0);
1370                 BN_bntest_rand(c, 512, 0, 0);
1371                 BN_bntest_rand(d, 512, 0, 0);
1372                 for (j=0; j < 2; j++)
1373                         {
1374                         BN_GF2m_mod_exp(e, a, c, b[j], ctx);
1375                         BN_GF2m_mod_exp(f, a, d, b[j], ctx);
1376                         BN_GF2m_mod_mul(e, e, f, b[j], ctx);
1377                         BN_add(f, c, d);
1378                         BN_GF2m_mod_exp(f, a, f, b[j], ctx);
1379 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1380                         if (bp != NULL)
1381                                 {
1382                                 if (!results)
1383                                         {
1384                                         BN_print(bp,a);
1385                                         BIO_puts(bp, " ^ (");
1386                                         BN_print(bp,c);
1387                                         BIO_puts(bp," + ");
1388                                         BN_print(bp,d);
1389                                         BIO_puts(bp, ") = ");
1390                                         BN_print(bp,e);
1391                                         BIO_puts(bp, "; - ");
1392                                         BN_print(bp,f);
1393                                         BIO_puts(bp, " % ");
1394                                         BN_print(bp,b[j]);
1395                                         BIO_puts(bp,"\n");
1396                                         }
1397                                 }
1398 #endif
1399                         BN_GF2m_add(f, e, f);
1400                         /* Test that a^(c+d)=a^c*a^d. */
1401                         if(!BN_is_zero(f))
1402                                 {
1403                                 fprintf(stderr,"GF(2^m) modular exponentiation test failed!\n");
1404                                 goto err;
1405                                 }
1406                         }
1407                 }
1408         ret = 1;
1409   err:
1410         BN_free(a);
1411         BN_free(b[0]);
1412         BN_free(b[1]);
1413         BN_free(c);
1414         BN_free(d);
1415         BN_free(e);
1416         BN_free(f);
1417         return ret;
1418         }
1419
1420 int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx)
1421         {
1422         BIGNUM *a,*b[2],*c,*d,*e,*f;
1423         int i, j, ret = 0;
1424         unsigned int p0[] = {163,7,6,3,0};
1425         unsigned int p1[] = {193,15,0};
1426
1427         a=BN_new();
1428         b[0]=BN_new();
1429         b[1]=BN_new();
1430         c=BN_new();
1431         d=BN_new();
1432         e=BN_new();
1433         f=BN_new();
1434
1435         BN_GF2m_arr2poly(p0, b[0]);
1436         BN_GF2m_arr2poly(p1, b[1]);
1437
1438         for (i=0; i<num0; i++)
1439                 {
1440                 BN_bntest_rand(a, 512, 0, 0);
1441                 for (j=0; j < 2; j++)
1442                         {
1443                         BN_GF2m_mod(c, a, b[j]);
1444                         BN_GF2m_mod_sqrt(d, a, b[j], ctx);
1445                         BN_GF2m_mod_sqr(e, d, b[j], ctx);
1446 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1447                         if (bp != NULL)
1448                                 {
1449                                 if (!results)
1450                                         {
1451                                         BN_print(bp,d);
1452                                         BIO_puts(bp, " ^ 2 - ");
1453                                         BN_print(bp,a);
1454                                         BIO_puts(bp,"\n");
1455                                         }
1456                                 }
1457 #endif
1458                         BN_GF2m_add(f, c, e);
1459                         /* Test that d^2 = a, where d = sqrt(a). */
1460                         if(!BN_is_zero(f))
1461                                 {
1462                                 fprintf(stderr,"GF(2^m) modular square root test failed!\n");
1463                                 goto err;
1464                                 }
1465                         }
1466                 }
1467         ret = 1;
1468   err:
1469         BN_free(a);
1470         BN_free(b[0]);
1471         BN_free(b[1]);
1472         BN_free(c);
1473         BN_free(d);
1474         BN_free(e);
1475         BN_free(f);
1476         return ret;
1477         }
1478
1479 int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx)
1480         {
1481         BIGNUM *a,*b[2],*c,*d,*e;
1482         int i, j, s = 0, t, ret = 0;
1483         unsigned int p0[] = {163,7,6,3,0};
1484         unsigned int p1[] = {193,15,0};
1485
1486         a=BN_new();
1487         b[0]=BN_new();
1488         b[1]=BN_new();
1489         c=BN_new();
1490         d=BN_new();
1491         e=BN_new();
1492
1493         BN_GF2m_arr2poly(p0, b[0]);
1494         BN_GF2m_arr2poly(p1, b[1]);
1495
1496         for (i=0; i<num0; i++)
1497                 {
1498                 BN_bntest_rand(a, 512, 0, 0);
1499                 for (j=0; j < 2; j++)
1500                         {
1501                         t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
1502                         if (t)
1503                                 {
1504                                 s++;
1505                                 BN_GF2m_mod_sqr(d, c, b[j], ctx);
1506                                 BN_GF2m_add(d, c, d);
1507                                 BN_GF2m_mod(e, a, b[j]);
1508 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1509                                 if (bp != NULL)
1510                                         {
1511                                         if (!results)
1512                                                 {
1513                                                 BN_print(bp,c);
1514                                                 BIO_puts(bp, " is root of z^2 + z = ");
1515                                                 BN_print(bp,a);
1516                                                 BIO_puts(bp, " % ");
1517                                                 BN_print(bp,b[j]);
1518                                                 BIO_puts(bp, "\n");
1519                                                 }
1520                                         }
1521 #endif
1522                                 BN_GF2m_add(e, e, d);
1523                                 /* Test that solution of quadratic c satisfies c^2 + c = a. */
1524                                 if(!BN_is_zero(e))
1525                                         {
1526                                         fprintf(stderr,"GF(2^m) modular solve quadratic test failed!\n");
1527                                         goto err;
1528                                         }
1529
1530                                 }
1531                         else 
1532                                 {
1533 #if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
1534                                 if (bp != NULL)
1535                                         {
1536                                         if (!results)
1537                                                 {
1538                                                 BIO_puts(bp, "There are no roots of z^2 + z = ");
1539                                                 BN_print(bp,a);
1540                                                 BIO_puts(bp, " % ");
1541                                                 BN_print(bp,b[j]);
1542                                                 BIO_puts(bp, "\n");
1543                                                 }
1544                                         }
1545 #endif
1546                                 }
1547                         }
1548                 }
1549         if (s == 0)
1550                 {       
1551                 fprintf(stderr,"All %i tests of GF(2^m) modular solve quadratic resulted in no roots;\n", num0);
1552                 fprintf(stderr,"this is very unlikely and probably indicates an error.\n");
1553                 goto err;
1554                 }
1555         ret = 1;
1556   err:
1557         BN_free(a);
1558         BN_free(b[0]);
1559         BN_free(b[1]);
1560         BN_free(c);
1561         BN_free(d);
1562         BN_free(e);
1563         return ret;
1564         }
1565
1566 static int genprime_cb(int p, int n, BN_GENCB *arg)
1567         {
1568         char c='*';
1569
1570         if (p == 0) c='.';
1571         if (p == 1) c='+';
1572         if (p == 2) c='*';
1573         if (p == 3) c='\n';
1574         putc(c, stderr);
1575         fflush(stderr);
1576         return 1;
1577         }
1578
1579 int test_kron(BIO *bp, BN_CTX *ctx)
1580         {
1581         BN_GENCB cb;
1582         BIGNUM *a,*b,*r,*t;
1583         int i;
1584         int legendre, kronecker;
1585         int ret = 0;
1586
1587         a = BN_new();
1588         b = BN_new();
1589         r = BN_new();
1590         t = BN_new();
1591         if (a == NULL || b == NULL || r == NULL || t == NULL) goto err;
1592
1593         BN_GENCB_set(&cb, genprime_cb, NULL);
1594         
1595         /* We test BN_kronecker(a, b, ctx) just for  b  odd (Jacobi symbol).
1596          * In this case we know that if  b  is prime, then BN_kronecker(a, b, ctx)
1597          * is congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol).
1598          * So we generate a random prime  b  and compare these values
1599          * for a number of random  a's.  (That is, we run the Solovay-Strassen
1600          * primality test to confirm that  b  is prime, except that we
1601          * don't want to test whether  b  is prime but whether BN_kronecker
1602          * works.) */
1603
1604         if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, &cb)) goto err;
1605         b->neg = rand_neg();
1606         putc('\n', stderr);
1607
1608         for (i = 0; i < num0; i++)
1609                 {
1610                 if (!BN_bntest_rand(a, 512, 0, 0)) goto err;
1611                 a->neg = rand_neg();
1612
1613                 /* t := (|b|-1)/2  (note that b is odd) */
1614                 if (!BN_copy(t, b)) goto err;
1615                 t->neg = 0;
1616                 if (!BN_sub_word(t, 1)) goto err;
1617                 if (!BN_rshift1(t, t)) goto err;
1618                 /* r := a^t mod b */
1619                 b->neg=0;
1620                 
1621                 if (!BN_mod_exp_recp(r, a, t, b, ctx)) goto err;
1622                 b->neg=1;
1623
1624                 if (BN_is_word(r, 1))
1625                         legendre = 1;
1626                 else if (BN_is_zero(r))
1627                         legendre = 0;
1628                 else
1629                         {
1630                         if (!BN_add_word(r, 1)) goto err;
1631                         if (0 != BN_ucmp(r, b))
1632                                 {
1633                                 fprintf(stderr, "Legendre symbol computation failed\n");
1634                                 goto err;
1635                                 }
1636                         legendre = -1;
1637                         }
1638                 
1639                 kronecker = BN_kronecker(a, b, ctx);
1640                 if (kronecker < -1) goto err;
1641                 /* we actually need BN_kronecker(a, |b|) */
1642                 if (a->neg && b->neg)
1643                         kronecker = -kronecker;
1644                 
1645                 if (legendre != kronecker)
1646                         {
1647                         fprintf(stderr, "legendre != kronecker; a = ");
1648                         BN_print_fp(stderr, a);
1649                         fprintf(stderr, ", b = ");
1650                         BN_print_fp(stderr, b);
1651                         fprintf(stderr, "\n");
1652                         goto err;
1653                         }
1654
1655                 putc('.', stderr);
1656                 fflush(stderr);
1657                 }
1658
1659         putc('\n', stderr);
1660         fflush(stderr);
1661         ret = 1;
1662  err:
1663         if (a != NULL) BN_free(a);
1664         if (b != NULL) BN_free(b);
1665         if (r != NULL) BN_free(r);
1666         if (t != NULL) BN_free(t);
1667         return ret;
1668         }
1669
1670 int test_sqrt(BIO *bp, BN_CTX *ctx)
1671         {
1672         BN_GENCB cb;
1673         BIGNUM *a,*p,*r;
1674         int i, j;
1675         int ret = 0;
1676
1677         a = BN_new();
1678         p = BN_new();
1679         r = BN_new();
1680         if (a == NULL || p == NULL || r == NULL) goto err;
1681
1682         BN_GENCB_set(&cb, genprime_cb, NULL);
1683
1684         for (i = 0; i < 16; i++)
1685                 {
1686                 if (i < 8)
1687                         {
1688                         unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
1689                         
1690                         if (!BN_set_word(p, primes[i])) goto err;
1691                         }
1692                 else
1693                         {
1694                         if (!BN_set_word(a, 32)) goto err;
1695                         if (!BN_set_word(r, 2*i + 1)) goto err;
1696                 
1697                         if (!BN_generate_prime_ex(p, 256, 0, a, r, &cb)) goto err;
1698                         putc('\n', stderr);
1699                         }
1700                 p->neg = rand_neg();
1701
1702                 for (j = 0; j < num2; j++)
1703                         {
1704                         /* construct 'a' such that it is a square modulo p,
1705                          * but in general not a proper square and not reduced modulo p */
1706                         if (!BN_bntest_rand(r, 256, 0, 3)) goto err;
1707                         if (!BN_nnmod(r, r, p, ctx)) goto err;
1708                         if (!BN_mod_sqr(r, r, p, ctx)) goto err;
1709                         if (!BN_bntest_rand(a, 256, 0, 3)) goto err;
1710                         if (!BN_nnmod(a, a, p, ctx)) goto err;
1711                         if (!BN_mod_sqr(a, a, p, ctx)) goto err;
1712                         if (!BN_mul(a, a, r, ctx)) goto err;
1713                         if (rand_neg())
1714                                 if (!BN_sub(a, a, p)) goto err;
1715
1716                         if (!BN_mod_sqrt(r, a, p, ctx)) goto err;
1717                         if (!BN_mod_sqr(r, r, p, ctx)) goto err;
1718
1719                         if (!BN_nnmod(a, a, p, ctx)) goto err;
1720
1721                         if (BN_cmp(a, r) != 0)
1722                                 {
1723                                 fprintf(stderr, "BN_mod_sqrt failed: a = ");
1724                                 BN_print_fp(stderr, a);
1725                                 fprintf(stderr, ", r = ");
1726                                 BN_print_fp(stderr, r);
1727                                 fprintf(stderr, ", p = ");
1728                                 BN_print_fp(stderr, p);
1729                                 fprintf(stderr, "\n");
1730                                 goto err;
1731                                 }
1732
1733                         putc('.', stderr);
1734                         fflush(stderr);
1735                         }
1736                 
1737                 putc('\n', stderr);
1738                 fflush(stderr);
1739                 }
1740         ret = 1;
1741  err:
1742         if (a != NULL) BN_free(a);
1743         if (p != NULL) BN_free(p);
1744         if (r != NULL) BN_free(r);
1745         return ret;
1746         }
1747
1748 int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
1749         {
1750         BIGNUM *a,*b,*c,*d;
1751         int i;
1752
1753         b=BN_new();
1754         c=BN_new();
1755         d=BN_new();
1756         BN_one(c);
1757
1758         if(a_)
1759             a=a_;
1760         else
1761             {
1762             a=BN_new();
1763             BN_bntest_rand(a,200,0,0); /**/
1764             a->neg=rand_neg();
1765             }
1766         for (i=0; i<num0; i++)
1767                 {
1768                 BN_lshift(b,a,i+1);
1769                 BN_add(c,c,c);
1770                 if (bp != NULL)
1771                         {
1772                         if (!results)
1773                                 {
1774                                 BN_print(bp,a);
1775                                 BIO_puts(bp," * ");
1776                                 BN_print(bp,c);
1777                                 BIO_puts(bp," - ");
1778                                 }
1779                         BN_print(bp,b);
1780                         BIO_puts(bp,"\n");
1781                         }
1782                 BN_mul(d,a,c,ctx);
1783                 BN_sub(d,d,b);
1784                 if(!BN_is_zero(d))
1785                     {
1786                     fprintf(stderr,"Left shift test failed!\n");
1787                     fprintf(stderr,"a=");
1788                     BN_print_fp(stderr,a);
1789                     fprintf(stderr,"\nb=");
1790                     BN_print_fp(stderr,b);
1791                     fprintf(stderr,"\nc=");
1792                     BN_print_fp(stderr,c);
1793                     fprintf(stderr,"\nd=");
1794                     BN_print_fp(stderr,d);
1795                     fprintf(stderr,"\n");
1796                     return 0;
1797                     }
1798                 }
1799         BN_free(a);
1800         BN_free(b);
1801         BN_free(c);
1802         BN_free(d);
1803         return(1);
1804         }
1805
1806 int test_lshift1(BIO *bp)
1807         {
1808         BIGNUM *a,*b,*c;
1809         int i;
1810
1811         a=BN_new();
1812         b=BN_new();
1813         c=BN_new();
1814
1815         BN_bntest_rand(a,200,0,0); /**/
1816         a->neg=rand_neg();
1817         for (i=0; i<num0; i++)
1818                 {
1819                 BN_lshift1(b,a);
1820                 if (bp != NULL)
1821                         {
1822                         if (!results)
1823                                 {
1824                                 BN_print(bp,a);
1825                                 BIO_puts(bp," * 2");
1826                                 BIO_puts(bp," - ");
1827                                 }
1828                         BN_print(bp,b);
1829                         BIO_puts(bp,"\n");
1830                         }
1831                 BN_add(c,a,a);
1832                 BN_sub(a,b,c);
1833                 if(!BN_is_zero(a))
1834                     {
1835                     fprintf(stderr,"Left shift one test failed!\n");
1836                     return 0;
1837                     }
1838                 
1839                 BN_copy(a,b);
1840                 }
1841         BN_free(a);
1842         BN_free(b);
1843         BN_free(c);
1844         return(1);
1845         }
1846
1847 int test_rshift(BIO *bp,BN_CTX *ctx)
1848         {
1849         BIGNUM *a,*b,*c,*d,*e;
1850         int i;
1851
1852         a=BN_new();
1853         b=BN_new();
1854         c=BN_new();
1855         d=BN_new();
1856         e=BN_new();
1857         BN_one(c);
1858
1859         BN_bntest_rand(a,200,0,0); /**/
1860         a->neg=rand_neg();
1861         for (i=0; i<num0; i++)
1862                 {
1863                 BN_rshift(b,a,i+1);
1864                 BN_add(c,c,c);
1865                 if (bp != NULL)
1866                         {
1867                         if (!results)
1868                                 {
1869                                 BN_print(bp,a);
1870                                 BIO_puts(bp," / ");
1871                                 BN_print(bp,c);
1872                                 BIO_puts(bp," - ");
1873                                 }
1874                         BN_print(bp,b);
1875                         BIO_puts(bp,"\n");
1876                         }
1877                 BN_div(d,e,a,c,ctx);
1878                 BN_sub(d,d,b);
1879                 if(!BN_is_zero(d))
1880                     {
1881                     fprintf(stderr,"Right shift test failed!\n");
1882                     return 0;
1883                     }
1884                 }
1885         BN_free(a);
1886         BN_free(b);
1887         BN_free(c);
1888         BN_free(d);
1889         BN_free(e);
1890         return(1);
1891         }
1892
1893 int test_rshift1(BIO *bp)
1894         {
1895         BIGNUM *a,*b,*c;
1896         int i;
1897
1898         a=BN_new();
1899         b=BN_new();
1900         c=BN_new();
1901
1902         BN_bntest_rand(a,200,0,0); /**/
1903         a->neg=rand_neg();
1904         for (i=0; i<num0; i++)
1905                 {
1906                 BN_rshift1(b,a);
1907                 if (bp != NULL)
1908                         {
1909                         if (!results)
1910                                 {
1911                                 BN_print(bp,a);
1912                                 BIO_puts(bp," / 2");
1913                                 BIO_puts(bp," - ");
1914                                 }
1915                         BN_print(bp,b);
1916                         BIO_puts(bp,"\n");
1917                         }
1918                 BN_sub(c,a,b);
1919                 BN_sub(c,c,b);
1920                 if(!BN_is_zero(c) && !BN_abs_is_word(c, 1))
1921                     {
1922                     fprintf(stderr,"Right shift one test failed!\n");
1923                     return 0;
1924                     }
1925                 BN_copy(a,b);
1926                 }
1927         BN_free(a);
1928         BN_free(b);
1929         BN_free(c);
1930         return(1);
1931         }
1932
1933 int rand_neg(void)
1934         {
1935         static unsigned int neg=0;
1936         static int sign[8]={0,0,0,1,1,0,1,1};
1937
1938         return(sign[(neg++)%8]);
1939         }