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