/* TFM demo program */ #include void draw(fp_int *a) { int x; printf("%d, %d, ", a->used, a->sign); for (x = a->used - 1; x >= 0; x--) { printf("%08lx ", a->dp[x]); } printf("\n"); } int myrng(unsigned char *dst, int len, void *dat) { int x; for (x = 0; x < len; x++) dst[x] = rand() & 0xFF; return len; } /* RDTSC from Scott Duplichan */ static ulong64 TIMFUNC (void) { #if defined __GNUC__ #if defined(INTEL_CC) ulong64 a; asm ("rdtsc":"=A"(a)); return a; #elif defined(__i386__) || defined(__x86_64__) ulong64 a; __asm__ __volatile__ ("rdtsc\nmovl %%eax,%0\nmovl %%edx,4+%0\n"::"m"(a):"%eax","%edx"); return a; #elif defined(TFM_PPC32) unsigned long a, b; __asm__ __volatile__ ("mftbu %1 \nmftb %0\n":"=r"(a), "=r"(b)); return (((ulong64)b) << 32ULL) | ((ulong64)a); #elif defined(TFM_AVR32) FILE *in; char buf[20]; in = fopen("/sys/devices/system/cpu/cpu0/pccycles", "r"); fgets(buf, 20, in); fclose(in); return strtoul(buf, NULL, 10); #else /* gcc-IA64 version */ unsigned long result; __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); while (__builtin_expect ((int) result == -1, 0)) __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); return result; #endif // Microsoft and Intel Windows compilers #elif defined _M_IX86 __asm rdtsc #elif defined _M_AMD64 return __rdtsc (); #elif defined _M_IA64 #if defined __INTEL_COMPILER #include #endif return __getReg (3116); #else #error need rdtsc function for this build #endif } char cmd[4096], buf[4096]; int main(void) { fp_int a,b,c,d,e,f; fp_digit fp; int n, err; 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, mul_d_n, t, cnt, rr, ix; ulong64 t1, t2; srand(time(NULL)); printf("TFM Ident string:\n%s\n\n", fp_ident()); fp_zero(&b); fp_zero(&c); fp_zero(&d); fp_zero(&e); fp_zero(&f); fp_zero(&a); draw(&a); /* test set and simple shifts */ printf("Testing mul/div 2\n"); fp_set(&a, 1); draw(&a); for (n = 0; n <= DIGIT_BIT; n++) { fp_mul_2(&a, &a); printf("(%d) ", fp_count_bits(&a)); draw(&a); } for (n = 0; n <= (DIGIT_BIT + 1); n++) { fp_div_2(&a, &a); draw(&a); } fp_set(&a, 1); /* test lshd/rshd */ printf("testing lshd/rshd\n"); fp_lshd(&a, 3); draw(&a); fp_rshd(&a, 3); draw(&a); /* test more complicated shifts */ printf("Testing mul/div 2d\n"); fp_mul_2d(&a, DIGIT_BIT/2, &a); draw(&a); fp_div_2d(&a, DIGIT_BIT/2, &a, NULL); draw(&a); fp_mul_2d(&a, DIGIT_BIT + DIGIT_BIT/2, &a); draw(&a); fp_div_2d(&a, DIGIT_BIT + DIGIT_BIT/2, &a, NULL); draw(&a); /* test neg/abs */ printf("testing neg/abs\n"); fp_neg(&a, &a); draw(&a); fp_neg(&a, &a); draw(&a); fp_neg(&a, &a); draw(&a); fp_abs(&a, &a); draw(&a); /* test comparisons */ fp_set(&b, 3); fp_set(&c, 4); fp_neg(&c, &c); fp_set(&d, 1); printf("Testing compares\n%d, %d, %d, %d\n", fp_cmp(&a, &b), fp_cmp(&a, &c), fp_cmp(&a, &d), fp_cmp(&b, &c)); /* test add/sub */ printf("Testing add/sub \n"); fp_set(&a, ((fp_digit)1)<<(DIGIT_BIT-1)); draw(&a); fp_set(&b, ((fp_digit)1)<<(DIGIT_BIT-2)); fp_add(&a, &b, &a); draw(&a); fp_add(&a, &b, &a); draw(&a); fp_add(&a, &b, &a); draw(&a); printf("sub...\n"); printf("cmp returns: %d, ", fp_cmp(&a, &b)); fp_sub(&a, &b, &a); draw(&a); printf("cmp returns: %d, ", fp_cmp(&a, &b)); fp_sub(&a, &b, &a); draw(&a); printf("cmp returns: %d, ", fp_cmp(&a, &b)); fp_sub(&a, &b, &a); draw(&a); printf("cmp returns: %d, ", fp_cmp(&a, &b)); fp_sub(&a, &b, &a); draw(&a); printf("cmp returns: %d, ", fp_cmp(&a, &b)); fp_sub(&a, &b, &a); draw(&a); printf("cmp returns: %d, ", fp_cmp(&a, &b)); fp_sub(&a, &b, &a); draw(&a); /* test mul_d */ printf("Testing mul_d and div_d\n"); fp_set(&a, 1); fp_mul_d(&a, ((fp_digit)1)<<(DIGIT_BIT/2), &a); draw(&a); fp_mul_d(&a, ((fp_digit)1)<<(DIGIT_BIT/2), &a); draw(&a); fp_mul_d(&a, ((fp_digit)1)<<(DIGIT_BIT/2), &a); draw(&a); printf("div_d\n"); fp_div_d(&a, ((fp_digit)1)<<(DIGIT_BIT/2), &a, NULL); draw(&a); fp_div_d(&a, ((fp_digit)1)<<(DIGIT_BIT/2), &a, NULL); draw(&a); fp_div_d(&a, ((fp_digit)1)<<(DIGIT_BIT/2), &a, NULL); draw(&a); /* testing read radix */ printf("Testing read_radix\n"); fp_read_radix(&a, "123456789012345678901234567890", 16); draw(&a); #if 0 /* test mont */ printf("Montgomery test #1\n"); fp_set(&a, 0x1234567ULL); fp_montgomery_setup(&a, &fp); fp_montgomery_calc_normalization(&b, &a); fp_read_radix(&d, "123456789123", 16); for (n = 0; n < 1000000; n++) { fp_add_d(&d, 1, &d); fp_sqrmod(&d, &a, &d); fp_mul(&d, &b, &c); fp_montgomery_reduce(&c, &a, fp); if (fp_cmp(&c, &d) != FP_EQ) { printf("Failed mont %d\n", n); draw(&a); draw(&d); draw(&c); return EXIT_FAILURE; } } printf("Passed.\n"); printf("Montgomery test #2\n"); fp_set(&a, 0x1234567ULL); fp_lshd(&a, 4); fp_add_d(&a, 1, &a); fp_montgomery_setup(&a, &fp); fp_montgomery_calc_normalization(&b, &a); fp_read_radix(&d, "123456789123", 16); for (n = 0; n < 1000000; n++) { fp_add_d(&d, 1, &d); fp_sqrmod(&d, &a, &d); fp_mul(&d, &b, &c); fp_montgomery_reduce(&c, &a, fp); if (fp_cmp(&c, &d) != FP_EQ) { printf("Failed mont %d\n", n); draw(&a); draw(&d); draw(&c); return EXIT_FAILURE; } } printf("Passed.\n"); /* test for size */ for (ix = 8*DIGIT_BIT; ix < 10*DIGIT_BIT; ix++) { printf("Testing (not safe-prime): %9lu bits \r", ix); fflush(stdout); err = fp_prime_random_ex(&a, 8, ix, (rand()&1)?TFM_PRIME_2MSB_OFF:TFM_PRIME_2MSB_ON, myrng, NULL); if (err != FP_OKAY) { printf("failed with err code %d\n", err); return EXIT_FAILURE; } if ((unsigned long)fp_count_bits(&a) != ix) { printf("Prime is %d not %lu bits!!!\n", fp_count_bits(&a), ix); return EXIT_FAILURE; } } printf("\n\n"); #endif #ifdef TESTING goto testing; #endif #if 1 t1 = TIMFUNC(); sleep(1); printf("Ticks per second: %llu\n", TIMFUNC() - t1); goto multtime; /* do some timings... */ printf("Addition:\n"); for (t = 2; t <= FP_SIZE/2; t += 2) { fp_zero(&a); fp_zero(&b); fp_zero(&c); for (ix = 0; ix < t; ix++) { a.dp[ix] = ix; b.dp[ix] = ix; } a.used = t; b.used = t; t2 = -1; for (ix = 0; ix < 25000; ++ix) { t1 = TIMFUNC(); fp_add(&a, &b, &c); fp_add(&a, &b, &c); fp_add(&a, &b, &c); fp_add(&a, &b, &c); fp_add(&a, &b, &c); fp_add(&a, &b, &c); fp_add(&a, &b, &c); fp_add(&a, &b, &c); t2 = (TIMFUNC() - t1)>>3; if (t1>7; if (t1>7; if (t1>6; if (t1>6; fp_copy(&b, &c); fp_copy(&b, &d); if (t1>1; fp_copy(&b, &c); fp_copy(&b, &d); if (t1