#include #ifdef IOWNANATHLON #include #define SLEEP sleep(4) #else #define SLEEP #endif #include "tommath.h" void ndraw(mp_int *a, char *name) { char buf[4096]; printf("%s: ", name); mp_toradix(a, buf, 64); printf("%s\n", buf); } static void draw(mp_int *a) { ndraw(a, ""); } unsigned long lfsr = 0xAAAAAAAAUL; int lbit(void) { if (lfsr & 0x80000000UL) { lfsr = ((lfsr << 1) ^ 0x8000001BUL) & 0xFFFFFFFFUL; return 1; } else { lfsr <<= 1; return 0; } } int myrng(unsigned char *dst, int len, void *dat) { int x; for (x = 0; x < len; x++) dst[x] = rand() & 0xFF; return len; } char cmd[4096], buf[4096]; int main(void) { mp_int a, b, c, d, e, f; unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n, t; unsigned rr; int i, n, err, cnt, ix, old_kara_m, old_kara_s; mp_init(&a); mp_init(&b); mp_init(&c); mp_init(&d); mp_init(&e); mp_init(&f); srand(time(NULL)); // test mp_get_int printf("Testing: mp_get_int\n"); for(i=0;i<1000;++i) { t = ((unsigned long)rand()*rand()+1)&0xFFFFFFFF; mp_set_int(&a,t); if (t!=mp_get_int(&a)) { printf("mp_get_int() bad result!\n"); return 1; } } mp_set_int(&a,0); if (mp_get_int(&a)!=0) { printf("mp_get_int() bad result!\n"); return 1; } mp_set_int(&a,0xffffffff); if (mp_get_int(&a)!=0xffffffff) { printf("mp_get_int() bad result!\n"); return 1; } // test mp_sqrt printf("Testing: mp_sqrt\n"); for (i=0;i<1000;++i) { printf("%6d\r", i); fflush(stdout); n = (rand()&15)+1; mp_rand(&a,n); if (mp_sqrt(&a,&b) != MP_OKAY) { printf("mp_sqrt() error!\n"); return 1; } mp_n_root(&a,2,&a); if (mp_cmp_mag(&b,&a) != MP_EQ) { printf("mp_sqrt() bad result!\n"); return 1; } } printf("\nTesting: mp_is_square\n"); for (i=0;i<1000;++i) { printf("%6d\r", i); fflush(stdout); /* test mp_is_square false negatives */ n = (rand()&7)+1; mp_rand(&a,n); mp_sqr(&a,&a); if (mp_is_square(&a,&n)!=MP_OKAY) { printf("fn:mp_is_square() error!\n"); return 1; } if (n==0) { printf("fn:mp_is_square() bad result!\n"); return 1; } /* test for false positives */ mp_add_d(&a, 1, &a); if (mp_is_square(&a,&n)!=MP_OKAY) { printf("fp:mp_is_square() error!\n"); return 1; } if (n==1) { printf("fp:mp_is_square() bad result!\n"); return 1; } } printf("\n\n"); /* test for size */ for (ix = 10; ix < 256; ix++) { printf("Testing (not safe-prime): %9d bits \r", ix); fflush(stdout); err = mp_prime_random_ex(&a, 8, ix, (rand()&1)?LTM_PRIME_2MSB_OFF:LTM_PRIME_2MSB_ON, myrng, NULL); if (err != MP_OKAY) { printf("failed with err code %d\n", err); return EXIT_FAILURE; } if (mp_count_bits(&a) != ix) { printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix); return EXIT_FAILURE; } } for (ix = 16; ix < 256; ix++) { printf("Testing ( safe-prime): %9d bits \r", ix); fflush(stdout); err = mp_prime_random_ex(&a, 8, ix, ((rand()&1)?LTM_PRIME_2MSB_OFF:LTM_PRIME_2MSB_ON)|LTM_PRIME_SAFE, myrng, NULL); if (err != MP_OKAY) { printf("failed with err code %d\n", err); return EXIT_FAILURE; } if (mp_count_bits(&a) != ix) { printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix); return EXIT_FAILURE; } /* let's see if it's really a safe prime */ mp_sub_d(&a, 1, &a); mp_div_2(&a, &a); mp_prime_is_prime(&a, 8, &cnt); if (cnt != MP_YES) { printf("sub is not prime!\n"); return EXIT_FAILURE; } } printf("\n\n"); mp_read_radix(&a, "123456", 10); mp_toradix_n(&a, buf, 10, 3); printf("a == %s\n", buf); mp_toradix_n(&a, buf, 10, 4); printf("a == %s\n", buf); mp_toradix_n(&a, buf, 10, 30); printf("a == %s\n", buf); #if 0 for (;;) { fgets(buf, sizeof(buf), stdin); mp_read_radix(&a, buf, 10); mp_prime_next_prime(&a, 5, 1); mp_toradix(&a, buf, 10); printf("%s, %lu\n", buf, a.dp[0] & 3); } #endif /* test mp_cnt_lsb */ printf("testing mp_cnt_lsb...\n"); mp_set(&a, 1); for (ix = 0; ix < 1024; ix++) { if (mp_cnt_lsb(&a) != ix) { printf("Failed at %d, %d\n", ix, mp_cnt_lsb(&a)); return 0; } mp_mul_2(&a, &a); } /* test mp_reduce_2k */ printf("Testing mp_reduce_2k...\n"); for (cnt = 3; cnt <= 128; ++cnt) { mp_digit tmp; mp_2expt(&a, cnt); mp_sub_d(&a, 2, &a); /* a = 2**cnt - 2 */ printf("\nTesting %4d bits", cnt); printf("(%d)", mp_reduce_is_2k(&a)); mp_reduce_2k_setup(&a, &tmp); printf("(%d)", tmp); for (ix = 0; ix < 1000; ix++) { if (!(ix & 127)) {printf("."); fflush(stdout); } mp_rand(&b, (cnt/DIGIT_BIT + 1) * 2); mp_copy(&c, &b); mp_mod(&c, &a, &c); mp_reduce_2k(&b, &a, 1); if (mp_cmp(&c, &b)) { printf("FAILED\n"); exit(0); } } } /* test mp_div_3 */ printf("Testing mp_div_3...\n"); mp_set(&d, 3); for (cnt = 0; cnt < 10000; ) { mp_digit r1, r2; if (!(++cnt & 127)) printf("%9d\r", cnt); mp_rand(&a, abs(rand()) % 128 + 1); mp_div(&a, &d, &b, &e); mp_div_3(&a, &c, &r2); if (mp_cmp(&b, &c) || mp_cmp_d(&e, r2)) { printf("\n\nmp_div_3 => Failure\n"); } } printf("\n\nPassed div_3 testing\n"); /* test the DR reduction */ printf("testing mp_dr_reduce...\n"); for (cnt = 2; cnt < 32; cnt++) { printf("%d digit modulus\n", cnt); mp_grow(&a, cnt); mp_zero(&a); for (ix = 1; ix < cnt; ix++) { a.dp[ix] = MP_MASK; } a.used = cnt; a.dp[0] = 3; mp_rand(&b, cnt - 1); mp_copy(&b, &c); rr = 0; do { if (!(rr & 127)) { printf("%9lu\r", rr); fflush(stdout); } mp_sqr(&b, &b); mp_add_d(&b, 1, &b); mp_copy(&b, &c); mp_mod(&b, &a, &b); mp_dr_reduce(&c, &a, (((mp_digit)1)<