1 /* $NetBSD: demo.c,v 1.1.1.1 2011/04/13 18:15:06 elric Exp $ */ 2 3 #include <time.h> 4 5 #ifdef IOWNANATHLON 6 #include <unistd.h> 7 #define SLEEP sleep(4) 8 #else 9 #define SLEEP 10 #endif 11 12 #include "tommath.h" 13 14 void ndraw(mp_int * a, char *name) 15 { 16 char buf[16000]; 17 18 printf("%s: ", name); 19 mp_toradix(a, buf, 10); 20 printf("%s\n", buf); 21 } 22 23 static void draw(mp_int * a) 24 { 25 ndraw(a, ""); 26 } 27 28 29 unsigned long lfsr = 0xAAAAAAAAUL; 30 31 int lbit(void) 32 { 33 if (lfsr & 0x80000000UL) { 34 lfsr = ((lfsr << 1) ^ 0x8000001BUL) & 0xFFFFFFFFUL; 35 return 1; 36 } else { 37 lfsr <<= 1; 38 return 0; 39 } 40 } 41 42 int myrng(unsigned char *dst, int len, void *dat) 43 { 44 int x; 45 46 for (x = 0; x < len; x++) 47 dst[x] = rand() & 0xFF; 48 return len; 49 } 50 51 52 53 char cmd[4096], buf[4096]; 54 int main(void) 55 { 56 mp_int a, b, c, d, e, f; 57 unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, 58 gcd_n, lcm_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n, t; 59 unsigned rr; 60 int i, n, err, cnt, ix, old_kara_m, old_kara_s; 61 mp_digit mp; 62 63 64 mp_init(&a); 65 mp_init(&b); 66 mp_init(&c); 67 mp_init(&d); 68 mp_init(&e); 69 mp_init(&f); 70 71 srand(time(NULL)); 72 73 #if 0 74 // test montgomery 75 printf("Testing montgomery...\n"); 76 for (i = 1; i < 10; i++) { 77 printf("Testing digit size: %d\n", i); 78 for (n = 0; n < 1000; n++) { 79 mp_rand(&a, i); 80 a.dp[0] |= 1; 81 82 // let's see if R is right 83 mp_montgomery_calc_normalization(&b, &a); 84 mp_montgomery_setup(&a, &mp); 85 86 // now test a random reduction 87 for (ix = 0; ix < 100; ix++) { 88 mp_rand(&c, 1 + abs(rand()) % (2*i)); 89 mp_copy(&c, &d); 90 mp_copy(&c, &e); 91 92 mp_mod(&d, &a, &d); 93 mp_montgomery_reduce(&c, &a, mp); 94 mp_mulmod(&c, &b, &a, &c); 95 96 if (mp_cmp(&c, &d) != MP_EQ) { 97 printf("d = e mod a, c = e MOD a\n"); 98 mp_todecimal(&a, buf); printf("a = %s\n", buf); 99 mp_todecimal(&e, buf); printf("e = %s\n", buf); 100 mp_todecimal(&d, buf); printf("d = %s\n", buf); 101 mp_todecimal(&c, buf); printf("c = %s\n", buf); 102 printf("compare no compare!\n"); exit(EXIT_FAILURE); } 103 } 104 } 105 } 106 printf("done\n"); 107 108 // test mp_get_int 109 printf("Testing: mp_get_int\n"); 110 for (i = 0; i < 1000; ++i) { 111 t = ((unsigned long) rand() * rand() + 1) & 0xFFFFFFFF; 112 mp_set_int(&a, t); 113 if (t != mp_get_int(&a)) { 114 printf("mp_get_int() bad result!\n"); 115 return 1; 116 } 117 } 118 mp_set_int(&a, 0); 119 if (mp_get_int(&a) != 0) { 120 printf("mp_get_int() bad result!\n"); 121 return 1; 122 } 123 mp_set_int(&a, 0xffffffff); 124 if (mp_get_int(&a) != 0xffffffff) { 125 printf("mp_get_int() bad result!\n"); 126 return 1; 127 } 128 // test mp_sqrt 129 printf("Testing: mp_sqrt\n"); 130 for (i = 0; i < 1000; ++i) { 131 printf("%6d\r", i); 132 fflush(stdout); 133 n = (rand() & 15) + 1; 134 mp_rand(&a, n); 135 if (mp_sqrt(&a, &b) != MP_OKAY) { 136 printf("mp_sqrt() error!\n"); 137 return 1; 138 } 139 mp_n_root(&a, 2, &a); 140 if (mp_cmp_mag(&b, &a) != MP_EQ) { 141 printf("mp_sqrt() bad result!\n"); 142 return 1; 143 } 144 } 145 146 printf("\nTesting: mp_is_square\n"); 147 for (i = 0; i < 1000; ++i) { 148 printf("%6d\r", i); 149 fflush(stdout); 150 151 /* test mp_is_square false negatives */ 152 n = (rand() & 7) + 1; 153 mp_rand(&a, n); 154 mp_sqr(&a, &a); 155 if (mp_is_square(&a, &n) != MP_OKAY) { 156 printf("fn:mp_is_square() error!\n"); 157 return 1; 158 } 159 if (n == 0) { 160 printf("fn:mp_is_square() bad result!\n"); 161 return 1; 162 } 163 164 /* test for false positives */ 165 mp_add_d(&a, 1, &a); 166 if (mp_is_square(&a, &n) != MP_OKAY) { 167 printf("fp:mp_is_square() error!\n"); 168 return 1; 169 } 170 if (n == 1) { 171 printf("fp:mp_is_square() bad result!\n"); 172 return 1; 173 } 174 175 } 176 printf("\n\n"); 177 178 /* test for size */ 179 for (ix = 10; ix < 128; ix++) { 180 printf("Testing (not safe-prime): %9d bits \r", ix); 181 fflush(stdout); 182 err = 183 mp_prime_random_ex(&a, 8, ix, 184 (rand() & 1) ? LTM_PRIME_2MSB_OFF : 185 LTM_PRIME_2MSB_ON, myrng, NULL); 186 if (err != MP_OKAY) { 187 printf("failed with err code %d\n", err); 188 return EXIT_FAILURE; 189 } 190 if (mp_count_bits(&a) != ix) { 191 printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix); 192 return EXIT_FAILURE; 193 } 194 } 195 196 for (ix = 16; ix < 128; ix++) { 197 printf("Testing ( safe-prime): %9d bits \r", ix); 198 fflush(stdout); 199 err = 200 mp_prime_random_ex(&a, 8, ix, 201 ((rand() & 1) ? LTM_PRIME_2MSB_OFF : 202 LTM_PRIME_2MSB_ON) | LTM_PRIME_SAFE, myrng, 203 NULL); 204 if (err != MP_OKAY) { 205 printf("failed with err code %d\n", err); 206 return EXIT_FAILURE; 207 } 208 if (mp_count_bits(&a) != ix) { 209 printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix); 210 return EXIT_FAILURE; 211 } 212 /* let's see if it's really a safe prime */ 213 mp_sub_d(&a, 1, &a); 214 mp_div_2(&a, &a); 215 mp_prime_is_prime(&a, 8, &cnt); 216 if (cnt != MP_YES) { 217 printf("sub is not prime!\n"); 218 return EXIT_FAILURE; 219 } 220 } 221 222 printf("\n\n"); 223 224 mp_read_radix(&a, "123456", 10); 225 mp_toradix_n(&a, buf, 10, 3); 226 printf("a == %s\n", buf); 227 mp_toradix_n(&a, buf, 10, 4); 228 printf("a == %s\n", buf); 229 mp_toradix_n(&a, buf, 10, 30); 230 printf("a == %s\n", buf); 231 232 233 #if 0 234 for (;;) { 235 fgets(buf, sizeof(buf), stdin); 236 mp_read_radix(&a, buf, 10); 237 mp_prime_next_prime(&a, 5, 1); 238 mp_toradix(&a, buf, 10); 239 printf("%s, %lu\n", buf, a.dp[0] & 3); 240 } 241 #endif 242 243 /* test mp_cnt_lsb */ 244 printf("testing mp_cnt_lsb...\n"); 245 mp_set(&a, 1); 246 for (ix = 0; ix < 1024; ix++) { 247 if (mp_cnt_lsb(&a) != ix) { 248 printf("Failed at %d, %d\n", ix, mp_cnt_lsb(&a)); 249 return 0; 250 } 251 mp_mul_2(&a, &a); 252 } 253 254 /* test mp_reduce_2k */ 255 printf("Testing mp_reduce_2k...\n"); 256 for (cnt = 3; cnt <= 128; ++cnt) { 257 mp_digit tmp; 258 259 mp_2expt(&a, cnt); 260 mp_sub_d(&a, 2, &a); /* a = 2**cnt - 2 */ 261 262 263 printf("\nTesting %4d bits", cnt); 264 printf("(%d)", mp_reduce_is_2k(&a)); 265 mp_reduce_2k_setup(&a, &tmp); 266 printf("(%d)", tmp); 267 for (ix = 0; ix < 1000; ix++) { 268 if (!(ix & 127)) { 269 printf("."); 270 fflush(stdout); 271 } 272 mp_rand(&b, (cnt / DIGIT_BIT + 1) * 2); 273 mp_copy(&c, &b); 274 mp_mod(&c, &a, &c); 275 mp_reduce_2k(&b, &a, 2); 276 if (mp_cmp(&c, &b)) { 277 printf("FAILED\n"); 278 exit(0); 279 } 280 } 281 } 282 283 /* test mp_div_3 */ 284 printf("Testing mp_div_3...\n"); 285 mp_set(&d, 3); 286 for (cnt = 0; cnt < 10000;) { 287 mp_digit r1, r2; 288 289 if (!(++cnt & 127)) 290 printf("%9d\r", cnt); 291 mp_rand(&a, abs(rand()) % 128 + 1); 292 mp_div(&a, &d, &b, &e); 293 mp_div_3(&a, &c, &r2); 294 295 if (mp_cmp(&b, &c) || mp_cmp_d(&e, r2)) { 296 printf("\n\nmp_div_3 => Failure\n"); 297 } 298 } 299 printf("\n\nPassed div_3 testing\n"); 300 301 /* test the DR reduction */ 302 printf("testing mp_dr_reduce...\n"); 303 for (cnt = 2; cnt < 32; cnt++) { 304 printf("%d digit modulus\n", cnt); 305 mp_grow(&a, cnt); 306 mp_zero(&a); 307 for (ix = 1; ix < cnt; ix++) { 308 a.dp[ix] = MP_MASK; 309 } 310 a.used = cnt; 311 a.dp[0] = 3; 312 313 mp_rand(&b, cnt - 1); 314 mp_copy(&b, &c); 315 316 rr = 0; 317 do { 318 if (!(rr & 127)) { 319 printf("%9lu\r", rr); 320 fflush(stdout); 321 } 322 mp_sqr(&b, &b); 323 mp_add_d(&b, 1, &b); 324 mp_copy(&b, &c); 325 326 mp_mod(&b, &a, &b); 327 mp_dr_reduce(&c, &a, (((mp_digit) 1) << DIGIT_BIT) - a.dp[0]); 328 329 if (mp_cmp(&b, &c) != MP_EQ) { 330 printf("Failed on trial %lu\n", rr); 331 exit(-1); 332 333 } 334 } while (++rr < 500); 335 printf("Passed DR test for %d digits\n", cnt); 336 } 337 338 #endif 339 340 /* test the mp_reduce_2k_l code */ 341 #if 0 342 #if 0 343 /* first load P with 2^1024 - 0x2A434 B9FDEC95 D8F9D550 FFFFFFFF FFFFFFFF */ 344 mp_2expt(&a, 1024); 345 mp_read_radix(&b, "2A434B9FDEC95D8F9D550FFFFFFFFFFFFFFFF", 16); 346 mp_sub(&a, &b, &a); 347 #elif 1 348 /* p = 2^2048 - 0x1 00000000 00000000 00000000 00000000 4945DDBF 8EA2A91D 5776399B B83E188F */ 349 mp_2expt(&a, 2048); 350 mp_read_radix(&b, 351 "1000000000000000000000000000000004945DDBF8EA2A91D5776399BB83E188F", 352 16); 353 mp_sub(&a, &b, &a); 354 #endif 355 356 mp_todecimal(&a, buf); 357 printf("p==%s\n", buf); 358 /* now mp_reduce_is_2k_l() should return */ 359 if (mp_reduce_is_2k_l(&a) != 1) { 360 printf("mp_reduce_is_2k_l() return 0, should be 1\n"); 361 return EXIT_FAILURE; 362 } 363 mp_reduce_2k_setup_l(&a, &d); 364 /* now do a million square+1 to see if it varies */ 365 mp_rand(&b, 64); 366 mp_mod(&b, &a, &b); 367 mp_copy(&b, &c); 368 printf("testing mp_reduce_2k_l..."); 369 fflush(stdout); 370 for (cnt = 0; cnt < (1UL << 20); cnt++) { 371 mp_sqr(&b, &b); 372 mp_add_d(&b, 1, &b); 373 mp_reduce_2k_l(&b, &a, &d); 374 mp_sqr(&c, &c); 375 mp_add_d(&c, 1, &c); 376 mp_mod(&c, &a, &c); 377 if (mp_cmp(&b, &c) != MP_EQ) { 378 printf("mp_reduce_2k_l() failed at step %lu\n", cnt); 379 mp_tohex(&b, buf); 380 printf("b == %s\n", buf); 381 mp_tohex(&c, buf); 382 printf("c == %s\n", buf); 383 return EXIT_FAILURE; 384 } 385 } 386 printf("...Passed\n"); 387 #endif 388 389 div2_n = mul2_n = inv_n = expt_n = lcm_n = gcd_n = add_n = 390 sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = add_d_n = 391 sub_d_n = 0; 392 393 /* force KARA and TOOM to enable despite cutoffs */ 394 KARATSUBA_SQR_CUTOFF = KARATSUBA_MUL_CUTOFF = 8; 395 TOOM_SQR_CUTOFF = TOOM_MUL_CUTOFF = 16; 396 397 for (;;) { 398 /* randomly clear and re-init one variable, this has the affect of triming the alloc space */ 399 switch (abs(rand()) % 7) { 400 case 0: 401 mp_clear(&a); 402 mp_init(&a); 403 break; 404 case 1: 405 mp_clear(&b); 406 mp_init(&b); 407 break; 408 case 2: 409 mp_clear(&c); 410 mp_init(&c); 411 break; 412 case 3: 413 mp_clear(&d); 414 mp_init(&d); 415 break; 416 case 4: 417 mp_clear(&e); 418 mp_init(&e); 419 break; 420 case 5: 421 mp_clear(&f); 422 mp_init(&f); 423 break; 424 case 6: 425 break; /* don't clear any */ 426 } 427 428 429 printf 430 ("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu ", 431 add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, 432 expt_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n); 433 fgets(cmd, 4095, stdin); 434 cmd[strlen(cmd) - 1] = 0; 435 printf("%s ]\r", cmd); 436 fflush(stdout); 437 if (!strcmp(cmd, "mul2d")) { 438 ++mul2d_n; 439 fgets(buf, 4095, stdin); 440 mp_read_radix(&a, buf, 64); 441 fgets(buf, 4095, stdin); 442 sscanf(buf, "%d", &rr); 443 fgets(buf, 4095, stdin); 444 mp_read_radix(&b, buf, 64); 445 446 mp_mul_2d(&a, rr, &a); 447 a.sign = b.sign; 448 if (mp_cmp(&a, &b) != MP_EQ) { 449 printf("mul2d failed, rr == %d\n", rr); 450 draw(&a); 451 draw(&b); 452 return 0; 453 } 454 } else if (!strcmp(cmd, "div2d")) { 455 ++div2d_n; 456 fgets(buf, 4095, stdin); 457 mp_read_radix(&a, buf, 64); 458 fgets(buf, 4095, stdin); 459 sscanf(buf, "%d", &rr); 460 fgets(buf, 4095, stdin); 461 mp_read_radix(&b, buf, 64); 462 463 mp_div_2d(&a, rr, &a, &e); 464 a.sign = b.sign; 465 if (a.used == b.used && a.used == 0) { 466 a.sign = b.sign = MP_ZPOS; 467 } 468 if (mp_cmp(&a, &b) != MP_EQ) { 469 printf("div2d failed, rr == %d\n", rr); 470 draw(&a); 471 draw(&b); 472 return 0; 473 } 474 } else if (!strcmp(cmd, "add")) { 475 ++add_n; 476 fgets(buf, 4095, stdin); 477 mp_read_radix(&a, buf, 64); 478 fgets(buf, 4095, stdin); 479 mp_read_radix(&b, buf, 64); 480 fgets(buf, 4095, stdin); 481 mp_read_radix(&c, buf, 64); 482 mp_copy(&a, &d); 483 mp_add(&d, &b, &d); 484 if (mp_cmp(&c, &d) != MP_EQ) { 485 printf("add %lu failure!\n", add_n); 486 draw(&a); 487 draw(&b); 488 draw(&c); 489 draw(&d); 490 return 0; 491 } 492 493 /* test the sign/unsigned storage functions */ 494 495 rr = mp_signed_bin_size(&c); 496 mp_to_signed_bin(&c, (unsigned char *) cmd); 497 memset(cmd + rr, rand() & 255, sizeof(cmd) - rr); 498 mp_read_signed_bin(&d, (unsigned char *) cmd, rr); 499 if (mp_cmp(&c, &d) != MP_EQ) { 500 printf("mp_signed_bin failure!\n"); 501 draw(&c); 502 draw(&d); 503 return 0; 504 } 505 506 507 rr = mp_unsigned_bin_size(&c); 508 mp_to_unsigned_bin(&c, (unsigned char *) cmd); 509 memset(cmd + rr, rand() & 255, sizeof(cmd) - rr); 510 mp_read_unsigned_bin(&d, (unsigned char *) cmd, rr); 511 if (mp_cmp_mag(&c, &d) != MP_EQ) { 512 printf("mp_unsigned_bin failure!\n"); 513 draw(&c); 514 draw(&d); 515 return 0; 516 } 517 518 } else if (!strcmp(cmd, "sub")) { 519 ++sub_n; 520 fgets(buf, 4095, stdin); 521 mp_read_radix(&a, buf, 64); 522 fgets(buf, 4095, stdin); 523 mp_read_radix(&b, buf, 64); 524 fgets(buf, 4095, stdin); 525 mp_read_radix(&c, buf, 64); 526 mp_copy(&a, &d); 527 mp_sub(&d, &b, &d); 528 if (mp_cmp(&c, &d) != MP_EQ) { 529 printf("sub %lu failure!\n", sub_n); 530 draw(&a); 531 draw(&b); 532 draw(&c); 533 draw(&d); 534 return 0; 535 } 536 } else if (!strcmp(cmd, "mul")) { 537 ++mul_n; 538 fgets(buf, 4095, stdin); 539 mp_read_radix(&a, buf, 64); 540 fgets(buf, 4095, stdin); 541 mp_read_radix(&b, buf, 64); 542 fgets(buf, 4095, stdin); 543 mp_read_radix(&c, buf, 64); 544 mp_copy(&a, &d); 545 mp_mul(&d, &b, &d); 546 if (mp_cmp(&c, &d) != MP_EQ) { 547 printf("mul %lu failure!\n", mul_n); 548 draw(&a); 549 draw(&b); 550 draw(&c); 551 draw(&d); 552 return 0; 553 } 554 } else if (!strcmp(cmd, "div")) { 555 ++div_n; 556 fgets(buf, 4095, stdin); 557 mp_read_radix(&a, buf, 64); 558 fgets(buf, 4095, stdin); 559 mp_read_radix(&b, buf, 64); 560 fgets(buf, 4095, stdin); 561 mp_read_radix(&c, buf, 64); 562 fgets(buf, 4095, stdin); 563 mp_read_radix(&d, buf, 64); 564 565 mp_div(&a, &b, &e, &f); 566 if (mp_cmp(&c, &e) != MP_EQ || mp_cmp(&d, &f) != MP_EQ) { 567 printf("div %lu %d, %d, failure!\n", div_n, mp_cmp(&c, &e), 568 mp_cmp(&d, &f)); 569 draw(&a); 570 draw(&b); 571 draw(&c); 572 draw(&d); 573 draw(&e); 574 draw(&f); 575 return 0; 576 } 577 578 } else if (!strcmp(cmd, "sqr")) { 579 ++sqr_n; 580 fgets(buf, 4095, stdin); 581 mp_read_radix(&a, buf, 64); 582 fgets(buf, 4095, stdin); 583 mp_read_radix(&b, buf, 64); 584 mp_copy(&a, &c); 585 mp_sqr(&c, &c); 586 if (mp_cmp(&b, &c) != MP_EQ) { 587 printf("sqr %lu failure!\n", sqr_n); 588 draw(&a); 589 draw(&b); 590 draw(&c); 591 return 0; 592 } 593 } else if (!strcmp(cmd, "gcd")) { 594 ++gcd_n; 595 fgets(buf, 4095, stdin); 596 mp_read_radix(&a, buf, 64); 597 fgets(buf, 4095, stdin); 598 mp_read_radix(&b, buf, 64); 599 fgets(buf, 4095, stdin); 600 mp_read_radix(&c, buf, 64); 601 mp_copy(&a, &d); 602 mp_gcd(&d, &b, &d); 603 d.sign = c.sign; 604 if (mp_cmp(&c, &d) != MP_EQ) { 605 printf("gcd %lu failure!\n", gcd_n); 606 draw(&a); 607 draw(&b); 608 draw(&c); 609 draw(&d); 610 return 0; 611 } 612 } else if (!strcmp(cmd, "lcm")) { 613 ++lcm_n; 614 fgets(buf, 4095, stdin); 615 mp_read_radix(&a, buf, 64); 616 fgets(buf, 4095, stdin); 617 mp_read_radix(&b, buf, 64); 618 fgets(buf, 4095, stdin); 619 mp_read_radix(&c, buf, 64); 620 mp_copy(&a, &d); 621 mp_lcm(&d, &b, &d); 622 d.sign = c.sign; 623 if (mp_cmp(&c, &d) != MP_EQ) { 624 printf("lcm %lu failure!\n", lcm_n); 625 draw(&a); 626 draw(&b); 627 draw(&c); 628 draw(&d); 629 return 0; 630 } 631 } else if (!strcmp(cmd, "expt")) { 632 ++expt_n; 633 fgets(buf, 4095, stdin); 634 mp_read_radix(&a, buf, 64); 635 fgets(buf, 4095, stdin); 636 mp_read_radix(&b, buf, 64); 637 fgets(buf, 4095, stdin); 638 mp_read_radix(&c, buf, 64); 639 fgets(buf, 4095, stdin); 640 mp_read_radix(&d, buf, 64); 641 mp_copy(&a, &e); 642 mp_exptmod(&e, &b, &c, &e); 643 if (mp_cmp(&d, &e) != MP_EQ) { 644 printf("expt %lu failure!\n", expt_n); 645 draw(&a); 646 draw(&b); 647 draw(&c); 648 draw(&d); 649 draw(&e); 650 return 0; 651 } 652 } else if (!strcmp(cmd, "invmod")) { 653 ++inv_n; 654 fgets(buf, 4095, stdin); 655 mp_read_radix(&a, buf, 64); 656 fgets(buf, 4095, stdin); 657 mp_read_radix(&b, buf, 64); 658 fgets(buf, 4095, stdin); 659 mp_read_radix(&c, buf, 64); 660 mp_invmod(&a, &b, &d); 661 mp_mulmod(&d, &a, &b, &e); 662 if (mp_cmp_d(&e, 1) != MP_EQ) { 663 printf("inv [wrong value from MPI?!] failure\n"); 664 draw(&a); 665 draw(&b); 666 draw(&c); 667 draw(&d); 668 mp_gcd(&a, &b, &e); 669 draw(&e); 670 return 0; 671 } 672 673 } else if (!strcmp(cmd, "div2")) { 674 ++div2_n; 675 fgets(buf, 4095, stdin); 676 mp_read_radix(&a, buf, 64); 677 fgets(buf, 4095, stdin); 678 mp_read_radix(&b, buf, 64); 679 mp_div_2(&a, &c); 680 if (mp_cmp(&c, &b) != MP_EQ) { 681 printf("div_2 %lu failure\n", div2_n); 682 draw(&a); 683 draw(&b); 684 draw(&c); 685 return 0; 686 } 687 } else if (!strcmp(cmd, "mul2")) { 688 ++mul2_n; 689 fgets(buf, 4095, stdin); 690 mp_read_radix(&a, buf, 64); 691 fgets(buf, 4095, stdin); 692 mp_read_radix(&b, buf, 64); 693 mp_mul_2(&a, &c); 694 if (mp_cmp(&c, &b) != MP_EQ) { 695 printf("mul_2 %lu failure\n", mul2_n); 696 draw(&a); 697 draw(&b); 698 draw(&c); 699 return 0; 700 } 701 } else if (!strcmp(cmd, "add_d")) { 702 ++add_d_n; 703 fgets(buf, 4095, stdin); 704 mp_read_radix(&a, buf, 64); 705 fgets(buf, 4095, stdin); 706 sscanf(buf, "%d", &ix); 707 fgets(buf, 4095, stdin); 708 mp_read_radix(&b, buf, 64); 709 mp_add_d(&a, ix, &c); 710 if (mp_cmp(&b, &c) != MP_EQ) { 711 printf("add_d %lu failure\n", add_d_n); 712 draw(&a); 713 draw(&b); 714 draw(&c); 715 printf("d == %d\n", ix); 716 return 0; 717 } 718 } else if (!strcmp(cmd, "sub_d")) { 719 ++sub_d_n; 720 fgets(buf, 4095, stdin); 721 mp_read_radix(&a, buf, 64); 722 fgets(buf, 4095, stdin); 723 sscanf(buf, "%d", &ix); 724 fgets(buf, 4095, stdin); 725 mp_read_radix(&b, buf, 64); 726 mp_sub_d(&a, ix, &c); 727 if (mp_cmp(&b, &c) != MP_EQ) { 728 printf("sub_d %lu failure\n", sub_d_n); 729 draw(&a); 730 draw(&b); 731 draw(&c); 732 printf("d == %d\n", ix); 733 return 0; 734 } 735 } 736 } 737 return 0; 738 } 739 740 /* Source: /cvs/libtom/libtommath/demo/demo.c,v */ 741 /* Revision: 1.3 */ 742 /* Date: 2005/06/24 11:32:07 */ 743