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