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