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