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