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