From 6bb413fd72ebd0d283ea24c48effb0f9afe032c1 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Sun, 19 Sep 2004 01:31:44 +0000 Subject: [PATCH] added tomsfastmath-0.02 --- changes.txt | 21 +- comba_mult_gen.c | 1 - comba_sqr_gen.c | 1 - delme.c | 24 ++ demo/test.c | 58 +++-- doc/tfm.pdf | Bin 119610 -> 123313 bytes fp_exptmod.c | 25 +- fp_ident.c | 66 ++++++ fp_mod.c | 14 +- fp_montgomery_calc_normalization.c | 2 +- fp_montgomery_reduce.c | 31 +-- fp_mul.c | 4 +- fp_mul_comba.c | 39 ++-- fp_radix_size.c | 35 +++ fp_sqr.c | 4 +- fp_sqr_comba.c | 62 ++--- gen.pl | 4 +- makefile | 9 +- mtest/makefile | 2 +- mtest/mtest.c | 3 +- pre_gen/mpi.c | 362 +++++++++++++++++++++++------ tfm.h | 81 ++++++- tfm.tex | 25 +- 23 files changed, 689 insertions(+), 184 deletions(-) create mode 100644 delme.c create mode 100644 fp_ident.c diff --git a/changes.txt b/changes.txt index 41322cd..809fc76 100644 --- a/changes.txt +++ b/changes.txt @@ -1,2 +1,21 @@ +September 18th, 2004 +0.02 -- Added TFM_LARGE to turn on/off 16x combas to save even more space. + This also helps prevent killing the cache on smaller cpus. + -- Cast memset to void in fp_init() to catch people who misuse the function (e.g. expect return) + Thanks to Johan Lindh + -- Cleaned up x86-64 support [faster montgomery reductions] + -- Autodetects x86-32 and x86-64 and enables it's asm now + -- Made test demo build cleaner in multilib platforms [e.g. mixed 32/64 bits] + -- Fix to fp_mod to ensure that remainder is of the same sign as the modulus. + -- Fixed bug in fp_montgomery_calc_normalization for single digit moduli + -- cleaned up ISO C macros in comba/mont to avoid branches [works best with GCC 3.4.x branch] + -- Added more testing to tfm.h to help detect misconfigured builds + -- Added TFM_NO_ASM which forces ASM off [even if it was autodetected]. + -- Added fp_radix_size() to API + -- Cleaned up demo/test.c to build with far fewer warnings (mostly %d => %lu fixes) + -- fp_exptmod() now supports negative exponent and base>modulus cases + -- Added fp_ident() which gives a string showing how TFM was configured. Useful for debuging... + -- fix gen.pl script so it includes the whole source tree now + August 25th, 2004 -TFM 0.01 -- Initial Release +0.01 -- Initial Release diff --git a/comba_mult_gen.c b/comba_mult_gen.c index 0dcc8b5..b43471d 100644 --- a/comba_mult_gen.c +++ b/comba_mult_gen.c @@ -10,7 +10,6 @@ int main(int argc, char **argv) printf( "void fp_mul_comba%d(fp_int *A, fp_int *B, fp_int *C)\n" "{\n" -" fp_word t;\n" " fp_digit c0, c1, c2, at[%d];\n" "\n" " memcpy(at, A->dp, %d * sizeof(fp_digit));\n" diff --git a/comba_sqr_gen.c b/comba_sqr_gen.c index 8c34f13..eb5949c 100644 --- a/comba_sqr_gen.c +++ b/comba_sqr_gen.c @@ -9,7 +9,6 @@ int main(int argc, char **argv) printf( "void fp_sqr_comba%d(fp_int *A, fp_int *B)\n" "{\n" -" fp_word t;\n" " fp_digit *a, b[%d], c0, c1, c2;\n" "\n" " a = A->dp;\n" diff --git a/delme.c b/delme.c new file mode 100644 index 0000000..7fb0ad5 --- /dev/null +++ b/delme.c @@ -0,0 +1,24 @@ +#include "tfm.h" + +int main(void) +{ + fp_int a; + char buf[4096]; + + fp_init(&a); + fp_read_radix( &a, + "///////////93zgY8MZ2DCJ6Oek0t1pHAG9E28fdp7G22xwcEnER8b5A27cED0JT" + "xvKPiyqwGnimAmfjybyKDq/XDMrjKS95v8MrTc9UViRqJ4BffZVjQml/NBRq1hVj" + "xZXh+rg9dwMkdoGHV4iVvaaePb7iv5izmW1ykA5ZlmMOsaWs75NJccaMFwZz9CzV" + "WsLT8zoZhPOSOlDM88LIkvxLAGTmbfPjPmmrJagyc0JnT6m8oXWXV3AGNaOkDiux" + "uvvtB1WEXWER9uEYx0UYZxN5NV1lJ5B9tYlBzfLO5nWvbKbywfLgvHNI9XYO+WKG" + "5NAEMeggn2sjCnSD151wCwXL8QlV7BfaxFk515ZRxmgAwd5NNGOCVREN3uMcuUJ7" + "g/MkZDi9CzSUZ9JWIYLXdSxZqYOQqkvhyI/w1jcA26JOTW9pFiXgP58VAnWNUo0C" + "k+4NLtfXNMnt2OZ0kjb6uWZYJw1qvQinGzjR/E3z48vBWj4WgJhIol//////////", + 64 ); + + if( fp_isprime( &a ) ) printf("It's prime.\n"); + else printf( "Not prime.\n"); + + return 0; +} diff --git a/demo/test.c b/demo/test.c index 486bb03..947aeb6 100644 --- a/demo/test.c +++ b/demo/test.c @@ -60,6 +60,8 @@ int main(void) div2_n, mul2_n, add_d_n, sub_d_n, mul_d_n, t, cnt, rr, ix; ulong64 t1, t2; + + 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); @@ -133,9 +135,30 @@ int main(void) printf("Testing read_radix\n"); fp_read_radix(&a, "123456789012345678901234567890", 16); draw(&a); +#if 1 /* test mont */ - printf("Montgomery test\n"); - fp_set(&a, 1); + 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 < 100000; 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); @@ -158,19 +181,19 @@ int main(void) /* test for size */ for (ix = 8*DIGIT_BIT; ix < 10*DIGIT_BIT; ix++) { - printf("Testing (not safe-prime): %9d bits \r", ix); fflush(stdout); + 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 (fp_count_bits(&a) != ix) { - printf("Prime is %d not %d bits!!!\n", fp_count_bits(&a), ix); + 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 #if 0 /* do some timings... */ @@ -280,7 +303,7 @@ int main(void) c.used = t; t2 = -1; - for (ix = 0; ix < 50; ++ix) { + for (ix = 0; ix < 1024; ++ix) { t1 = TIMFUNC(); fp_exptmod(&c, &b, &a, &d); fp_exptmod(&c, &b, &a, &d); @@ -293,7 +316,6 @@ int main(void) } #endif - div2_n = mul2_n = inv_n = expt_n = lcm_n = gcd_n = add_n = sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = add_d_n = sub_d_n= mul_d_n = 0; @@ -304,27 +326,27 @@ int main(void) printf("%s ]\r",cmd); fflush(stdout); if (!strcmp(cmd, "mul2d")) { ++mul2d_n; fgets(buf, 4095, stdin); fp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); sscanf(buf, "%d", &rr); + fgets(buf, 4095, stdin); sscanf(buf, "%lu", &rr); fgets(buf, 4095, stdin); fp_read_radix(&b, buf, 64); fp_mul_2d(&a, rr, &a); a.sign = b.sign; if (fp_cmp(&a, &b) != FP_EQ) { - printf("mul2d failed, rr == %d\n",rr); + printf("mul2d failed, rr == %lu\n",rr); draw(&a); draw(&b); return 0; } } else if (!strcmp(cmd, "div2d")) { ++div2d_n; fgets(buf, 4095, stdin); fp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); sscanf(buf, "%d", &rr); + fgets(buf, 4095, stdin); sscanf(buf, "%lu", &rr); fgets(buf, 4095, stdin); fp_read_radix(&b, buf, 64); fp_div_2d(&a, rr, &a, &e); a.sign = b.sign; if (a.used == b.used && a.used == 0) { a.sign = b.sign = FP_ZPOS; } if (fp_cmp(&a, &b) != FP_EQ) { - printf("div2d failed, rr == %d\n",rr); + printf("div2d failed, rr == %lu\n",rr); draw(&a); draw(&b); return 0; @@ -492,7 +514,7 @@ draw(&a);draw(&b);draw(&c);draw(&d); } } else if (!strcmp(cmd, "add_d")) { ++add_d_n; fgets(buf, 4095, stdin); fp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); sscanf(buf, "%d", &ix); + fgets(buf, 4095, stdin); sscanf(buf, "%lu", &ix); fgets(buf, 4095, stdin); fp_read_radix(&b, buf, 64); fp_add_d(&a, ix, &c); if (fp_cmp(&b, &c) != FP_EQ) { @@ -500,12 +522,12 @@ draw(&a);draw(&b);draw(&c);draw(&d); draw(&a); draw(&b); draw(&c); - printf("d == %d\n", ix); + printf("d == %lu\n", ix); return 0; } } else if (!strcmp(cmd, "sub_d")) { ++sub_d_n; fgets(buf, 4095, stdin); fp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); sscanf(buf, "%d", &ix); + fgets(buf, 4095, stdin); sscanf(buf, "%lu", &ix); fgets(buf, 4095, stdin); fp_read_radix(&b, buf, 64); fp_sub_d(&a, ix, &c); if (fp_cmp(&b, &c) != FP_EQ) { @@ -513,12 +535,12 @@ draw(&a);draw(&b);draw(&c);draw(&d); draw(&a); draw(&b); draw(&c); - printf("d == %d\n", ix); + printf("d == %lu\n", ix); return 0; } } else if (!strcmp(cmd, "mul_d")) { ++mul_d_n; fgets(buf, 4095, stdin); fp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); sscanf(buf, "%d", &ix); + fgets(buf, 4095, stdin); sscanf(buf, "%lu", &ix); fgets(buf, 4095, stdin); fp_read_radix(&b, buf, 64); fp_mul_d(&a, ix, &c); if (fp_cmp(&b, &c) != FP_EQ) { @@ -526,7 +548,7 @@ draw(&a);draw(&b);draw(&c);draw(&d); draw(&a); draw(&b); draw(&c); - printf("d == %d\n", ix); + printf("d == %lu\n", ix); return 0; } } diff --git a/doc/tfm.pdf b/doc/tfm.pdf index 60e869c53ede1d700f7cd18ec610ae623b5fb61f..38c2f39f5b460b46ab311a538a4317bfccf772b7 100644 GIT binary patch delta 69568 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 E1MDJVn*aa+ delta 66193 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 == FP_NEG) { + /* yes, copy G and invmod it */ + fp_copy(G, &tmp); + if ((err = fp_invmod(&tmp, P, &tmp)) != FP_OKAY) { + return err; + } + /* _fp_exptmod doesn't care about the sign of X */ + return _fp_exptmod(&tmp, X, P, Y); + } else { + /* Positive exponent so just exptmod */ + return _fp_exptmod(G, X, P, Y); + } +} + diff --git a/fp_ident.c b/fp_ident.c new file mode 100644 index 0000000..105e3d2 --- /dev/null +++ b/fp_ident.c @@ -0,0 +1,66 @@ +#include "tfm.h" + +const char *fp_ident(void) +{ + static char buf[1024]; + + memset(buf, 0, sizeof(buf)); + snprintf(buf, sizeof(buf)-1, +"TomsFastMath (%s)\n" +"\n" +"Sizeofs\n" +"\tfp_digit = %u\n" +"\tfp_word = %u\n" +"\n" +"FP_MAX_SIZE = %u\n" +"\n" +"Defines: \n" +#ifdef __i386__ +" __i386__ " +#endif +#ifdef __x86_64__ +" __x86_64__ " +#endif +#ifdef TFM_X86 +" TFM_X86 " +#endif +#ifdef TFM_X86_64 +" TFM_X86_64 " +#endif +#ifdef TFM_SSE2 +" TFM_SSE2 " +#endif +#ifdef TFM_ARM +" TFM_ARM " +#endif +#ifdef TFM_NO_ASM +" TFM_NO_ASM " +#endif +#ifdef FP_64BIT +" FP_64BIT " +#endif +#ifdef TFM_LARGE +" TFM_LARGE " +#endif +#ifdef TFM_HUGE +" TFM_HUGE " +#endif +"\n", __DATE__, sizeof(fp_digit), sizeof(fp_word), FP_MAX_SIZE); + + if (sizeof(fp_digit) == sizeof(fp_word)) { + strncat(buf, "WARNING: sizeof(fp_digit) == sizeof(fp_word), this build is likely to not work properly.\n", + sizeof(buf)-1); + } + return buf; +} + +#ifdef STANDALONE + +int main(void) +{ + printf("%s\n", fp_ident()); + return 0; +} + +#endif + diff --git a/fp_mod.c b/fp_mod.c index bec0593..8fb027b 100644 --- a/fp_mod.c +++ b/fp_mod.c @@ -12,7 +12,19 @@ /* c = a mod b, 0 <= c < b */ int fp_mod(fp_int *a, fp_int *b, fp_int *c) { - return fp_div(a, b, NULL, c); + fp_int t; + int err; + + fp_zero(&t); + if ((err = fp_div(a, b, NULL, &t)) != FP_OKAY) { + return err; + } + if (t.sign != b->sign) { + fp_add(&t, b, c); + } else { + fp_copy(&t, c); + } + return FP_OKAY; } diff --git a/fp_montgomery_calc_normalization.c b/fp_montgomery_calc_normalization.c index 3f3331d..f6791af 100644 --- a/fp_montgomery_calc_normalization.c +++ b/fp_montgomery_calc_normalization.c @@ -24,7 +24,7 @@ void fp_montgomery_calc_normalization(fp_int *a, fp_int *b) fp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1); } else { fp_set(a, 1); - ++bits; + bits = 1; } /* now compute C = A * B mod b */ diff --git a/fp_montgomery_reduce.c b/fp_montgomery_reduce.c index 2f4fbe7..778a433 100644 --- a/fp_montgomery_reduce.c +++ b/fp_montgomery_reduce.c @@ -66,13 +66,13 @@ asm( #define PROPCARRY \ asm( \ "movq %1,%%rax \n\t" \ +"movq %2,%%rbx \n\t" \ "addq %%rax,%6 \n\t" \ -"movq %2,%%rax \n\t" \ -"adcq %%rax,%7 \n\t" \ +"adcq %%rbx,%7 \n\t" \ "adcq $0,%8 \n\t" \ :"=g"(_c[OFF0]), "=g"(_c[OFF1]), "=g"(_c[OFF2]):"0"(_c[OFF0]), "1"(_c[OFF1]), "2"(_c[OFF2]), \ "m"(_c[OFF0+1]), "m"(_c[OFF1+1]), "m"(_c[OFF2+1]) \ -: "%rax", "%cc"); +: "%rax", "%rbx", "%cc"); #elif defined(TFM_SSE2) @@ -88,7 +88,7 @@ asm("emms"); asm(\ "movd %0,%%mm1 \n\t" \ "pmuludq %%mm2,%%mm1 \n\t" \ -:: "g"(c[x]), "g"(mp)); +:: "g"(c[x])); #define INNERMUL \ asm( \ @@ -112,7 +112,7 @@ asm( "adcl %%eax,%7 \n\t" \ "adcl $0,%8 \n\t" \ :"=g"(_c[OFF0]), "=g"(_c[OFF1]), "=g"(_c[OFF2]):"0"(_c[OFF0]), "1"(_c[OFF1]), "2"(_c[OFF2]), \ - "m"(_c[OFF0+1]), "m"(_c[OFF1+1]), "m"(_c[OFF2+1]) \ + "g"(_c[OFF0+1]), "g"(_c[OFF1+1]), "g"(_c[OFF2+1]) \ : "%eax", "%cc"); #elif defined(TFM_ARM) @@ -166,14 +166,18 @@ asm( \ mu = c[x] * mp; #define INNERMUL \ - t = ((fp_word)mu) * ((fp_word)*tmpm++); \ - _c[OFF0] += t; if (_c[OFF0] < (fp_digit)t) ++_c[OFF1]; \ - _c[OFF1] += (t>>DIGIT_BIT); if (_c[OFF1] < (fp_digit)(t>>DIGIT_BIT)) ++_c[OFF2]; \ + do { fp_word t; \ + t = (fp_word)_c[OFF0] + ((fp_word)mu) * ((fp_word)*tmpm++); _c[OFF0] = t; \ + t = (fp_word)_c[OFF1] + (t >> DIGIT_BIT); _c[OFF1] = t; \ + _c[OFF2] += (t >> DIGIT_BIT); \ + } while (0); #define PROPCARRY \ - _c[OFF0+1] += _c[OFF1]; if (_c[OFF0+1] < _c[OFF1]) ++_c[OFF1+1]; \ - _c[OFF1+1] += _c[OFF2]; if (_c[OFF1+1] < _c[OFF2]) ++_c[OFF2+1]; - + do { fp_word t; \ + t = (fp_word)_c[OFF0+1] + (fp_word)_c[OFF1]; _c[OFF0+1] = t; \ + t = (fp_word)_c[OFF1+1] + (t >> DIGIT_BIT) + (fp_word)_c[OFF2]; _c[OFF1+1] = t; \ + _c[OFF2+1] += (t >> DIGIT_BIT); \ + } while (0); #endif @@ -187,7 +191,6 @@ void fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp) { fp_digit c[3*FP_SIZE], *_c, *tmpm, mu; int oldused, x, y, pa; - fp_word t; /* now zero the buff */ pa = m->used; @@ -221,13 +224,13 @@ void fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp) /* fix the rest of the carries */ _c = c + pa; - for (; x < pa * 2 + 2; x++) { + for (x = pa; x < pa * 2 + 2; x++) { PROPCARRY; ++_c; } /* now copy out */ - _c = c + pa; + _c = c + pa; tmpm = a->dp; for (x = 0; x < pa+1; x++) { *tmpm++ = *_c++; diff --git a/fp_mul.c b/fp_mul.c index 06459b5..70174d5 100644 --- a/fp_mul.c +++ b/fp_mul.c @@ -28,9 +28,11 @@ void fp_mul(fp_int *A, fp_int *B, fp_int *C) fp_mul_comba4(A,B,C); } else if (y <= 8) { fp_mul_comba8(A,B,C); +#if defined(TFM_LARGE) } else if (y <= 16 && y >= 12) { fp_mul_comba16(A,B,C); -#ifdef TFM_HUGE +#endif +#if defined(TFM_HUGE) } else if (y <= 32 && y >= 28) { fp_mul_comba32(A,B,C); #endif diff --git a/fp_mul_comba.c b/fp_mul_comba.c index a6146cf..ddd0cb3 100644 --- a/fp_mul_comba.c +++ b/fp_mul_comba.c @@ -27,7 +27,7 @@ /* forward the carry to the next digit */ #define COMBA_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); /* store the first sum */ #define COMBA_STORE(x) \ @@ -42,7 +42,7 @@ /* this should multiply i and j */ #define MULADD(i, j) \ -asm volatile ( \ +asm ( \ "movl %6,%%eax \n\t" \ "mull %7 \n\t" \ "addl %%eax,%0 \n\t" \ @@ -62,7 +62,7 @@ asm volatile ( \ /* forward the carry to the next digit */ #define COMBA_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); /* store the first sum */ #define COMBA_STORE(x) \ @@ -77,13 +77,13 @@ asm volatile ( \ /* this should multiply i and j */ #define MULADD(i, j) \ -asm volatile ( \ +asm ( \ "movq %6,%%rax \n\t" \ "mulq %7 \n\t" \ "addq %%rax,%0 \n\t" \ "adcq %%rdx,%1 \n\t" \ "adcq $0,%2 \n\t" \ - :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%rax","%rdx","%cc"); + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","%cc"); #elif defined(TFM_SSE2) /* use SSE2 optimizations */ @@ -97,7 +97,7 @@ asm volatile ( \ /* forward the carry to the next digit */ #define COMBA_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); /* store the first sum */ #define COMBA_STORE(x) \ @@ -134,7 +134,7 @@ asm volatile ( \ c0 = c1 = c2 = 0; #define COMBA_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); #define COMBA_STORE(x) \ x = c0; @@ -155,13 +155,13 @@ asm( \ #else /* ISO C code */ -#define COMBA_START +#define COMBA_START #define COMBA_CLEAR \ c0 = c1 = c2 = 0; #define COMBA_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); #define COMBA_STORE(x) \ x = c0; @@ -169,12 +169,13 @@ asm( \ #define COMBA_STORE2(x) \ x = c1; -#define COMBA_FINI - -#define MULADD(i, j) \ - t = ((fp_word)i) * ((fp_word)j); \ - c0 = (c0 + t); if (c0 < ((fp_digit)t)) ++c1; \ - c1 = (c1 + (t>>DIGIT_BIT)); if (c1 < (t>>DIGIT_BIT)) ++c2; +#define COMBA_FINI + +#define MULADD(i, j) \ + do { fp_word t; \ + t = (fp_word)c0 + ((fp_word)i) * ((fp_word)j); c0 = t; \ + t = (fp_word)c1 + (t >> DIGIT_BIT); c1 = t; c2 += t >> DIGIT_BIT; \ + } while (0); #endif @@ -184,7 +185,6 @@ void fp_mul_comba(fp_int *A, fp_int *B, fp_int *C) { int ix, iy, iz, tx, ty, pa; fp_digit c0, c1, c2, *tmpx, *tmpy; - fp_word t; fp_int tmp, *dst; COMBA_START; @@ -239,7 +239,6 @@ void fp_mul_comba(fp_int *A, fp_int *B, fp_int *C) void fp_mul_comba4(fp_int *A, fp_int *B, fp_int *C) { - fp_word t; fp_digit c0, c1, c2, at[8]; memcpy(at, A->dp, 4 * sizeof(fp_digit)); @@ -284,7 +283,6 @@ void fp_mul_comba4(fp_int *A, fp_int *B, fp_int *C) void fp_mul_comba8(fp_int *A, fp_int *B, fp_int *C) { - fp_word t; fp_digit c0, c1, c2, at[16]; memcpy(at, A->dp, 8 * sizeof(fp_digit)); @@ -358,10 +356,10 @@ void fp_mul_comba8(fp_int *A, fp_int *B, fp_int *C) COMBA_FINI; } +#if defined(TFM_LARGE) void fp_mul_comba16(fp_int *A, fp_int *B, fp_int *C) { - fp_word t; fp_digit c0, c1, c2, at[32]; memcpy(at, A->dp, 16 * sizeof(fp_digit)); @@ -499,11 +497,12 @@ void fp_mul_comba16(fp_int *A, fp_int *B, fp_int *C) COMBA_FINI; } +#endif /* TFM_LARGE */ + #ifdef TFM_HUGE void fp_mul_comba32(fp_int *A, fp_int *B, fp_int *C) { - fp_word t; fp_digit c0, c1, c2, at[64]; memcpy(at, A->dp, 32 * sizeof(fp_digit)); diff --git a/fp_radix_size.c b/fp_radix_size.c index c163fec..d632e97 100644 --- a/fp_radix_size.c +++ b/fp_radix_size.c @@ -11,4 +11,39 @@ int fp_radix_size(fp_int *a, int radix, int *size) { + int digs; + fp_int t; + fp_digit d; + + *size = 0; + + /* check range of the radix */ + if (radix < 2 || radix > 64) { + return FP_VAL; + } + + /* quick out if its zero */ + if (fp_iszero(a) == 1) { + *size = 2; + return FP_OKAY; + } + + fp_init_copy(&t, a); + + /* if it is negative output a - */ + if (t.sign == FP_NEG) { + *size++; + t.sign = FP_ZPOS; + } + + digs = 0; + while (fp_iszero (&t) == FP_NO) { + fp_div_d (&t, (fp_digit) radix, &t, &d); + *size++; + } + + /* append a NULL so the string is properly terminated */ + *size++; + return FP_OKAY; + } diff --git a/fp_sqr.c b/fp_sqr.c index 663c444..b7c7f64 100644 --- a/fp_sqr.c +++ b/fp_sqr.c @@ -21,9 +21,11 @@ void fp_sqr(fp_int *A, fp_int *B) fp_sqr_comba4(A,B); } else if (y <= 8) { fp_sqr_comba8(A,B); +#if defined(TFM_LARGE) } else if (y <= 16 && y >= 12) { fp_sqr_comba16(A,B); -#ifdef TFM_HUGE +#endif +#if defined(TFM_HUGE) } else if (y <= 32 && y >= 28) { fp_sqr_comba32(A,B); #endif diff --git a/fp_sqr_comba.c b/fp_sqr_comba.c index 84de74f..4a73e2a 100644 --- a/fp_sqr_comba.c +++ b/fp_sqr_comba.c @@ -28,7 +28,7 @@ x = c1; #define CARRY_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); #define COMBA_FINI @@ -68,21 +68,21 @@ asm volatile ( \ x = c1; #define CARRY_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); #define COMBA_FINI #define SQRADD(i, j) \ -asm volatile ( \ +asm ( \ "movq %6,%%rax \n\t" \ "mulq %%rax \n\t" \ "addq %%rax,%0 \n\t" \ "adcq %%rdx,%1 \n\t" \ "adcq $0,%2 \n\t" \ - :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%rax","%rdx","%cc"); + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i) :"%rax","%rdx","%cc"); #define SQRADD2(i, j) \ -asm volatile ( \ +asm ( \ "movq %6,%%rax \n\t" \ "mulq %7 \n\t" \ "addq %%rax,%0 \n\t" \ @@ -91,7 +91,7 @@ asm volatile ( \ "addq %%rax,%0 \n\t" \ "adcq %%rdx,%1 \n\t" \ "adcq $0,%2 \n\t" \ - :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%rax","%rdx","%cc"); + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","%cc"); #elif defined(TFM_SSE2) @@ -109,7 +109,7 @@ asm volatile ( \ x = c1; #define CARRY_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); #define COMBA_FINI \ asm("emms"); @@ -120,11 +120,11 @@ asm volatile ( \ "pmuludq %%mm0,%%mm0\n\t" \ "movd %%mm0,%%eax \n\t" \ "psrlq $32,%%mm0 \n\t" \ - "movd %%mm0,%%edx \n\t" \ "addl %%eax,%0 \n\t" \ - "adcl %%edx,%1 \n\t" \ + "movd %%mm0,%%eax \n\t" \ + "adcl %%eax,%1 \n\t" \ "adcl $0,%2 \n\t" \ - :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%edx","%cc"); + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%cc"); #define SQRADD2(i, j) \ asm volatile ( \ @@ -158,7 +158,7 @@ asm volatile ( \ x = c1; #define CARRY_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); #define COMBA_FINI @@ -187,7 +187,8 @@ asm( \ /* ISO C portable code */ -#define COMBA_START +#define COMBA_START \ + { fp_word tt; #define CLEAR_CARRY \ c0 = c1 = c2 = 0; @@ -199,23 +200,28 @@ asm( \ x = c1; #define CARRY_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); -#define COMBA_FINI +#define COMBA_FINI \ + } /* multiplies point i and j, updates carry "c1" and digit c2 */ -#define SQRADD(i, j) \ - t = ((fp_word)i) * ((fp_word)j); \ - c0 = (c0 + t); if (c0 < ((fp_digit)t)) ++c1; \ - c1 = (c1 + (t>>DIGIT_BIT)); if (c1 < (t>>DIGIT_BIT)) ++c2; +#define SQRADD(i, j) \ + do { fp_word t; \ + t = c0 + ((fp_word)i) * ((fp_word)j); c0 = t; \ + t = c1 + (t >> DIGIT_BIT); c1 = t; c2 += t >> DIGIT_BIT; \ + } while (0); + /* for squaring some of the terms are doubled... */ -#define SQRADD2(i, j) \ - t = ((fp_word)i) * ((fp_word)j); \ - c0 = (c0 + t); if (c0 < ((fp_digit)t)) ++c1; \ - c1 = (c1 + (t>>DIGIT_BIT)); if (c1 < (t>>DIGIT_BIT)) ++c2; \ - c0 = (c0 + t); if (c0 < ((fp_digit)t)) ++c1; \ - c1 = (c1 + (t>>DIGIT_BIT)); if (c1 < (t>>DIGIT_BIT)) ++c2; +#define SQRADD2(i, j) \ + do { fp_word t; \ + t = ((fp_word)i) * ((fp_word)j); \ + tt = (fp_word)c0 + t; c0 = tt; \ + tt = (fp_word)c1 + (tt >> DIGIT_BIT); c1 = tt; c2 += tt >> DIGIT_BIT; \ + tt = (fp_word)c0 + t; c0 = tt; \ + tt = (fp_word)c1 + (tt >> DIGIT_BIT); c1 = tt; c2 += tt >> DIGIT_BIT; \ + } while (0); #endif @@ -225,7 +231,6 @@ void fp_sqr_comba(fp_int *A, fp_int *B) int pa, ix, iz; fp_digit c0, c1, c2; fp_int tmp, *dst; - fp_word t; /* get size of output and trim */ pa = A->used + A->used; @@ -298,7 +303,6 @@ void fp_sqr_comba(fp_int *A, fp_int *B) void fp_sqr_comba4(fp_int *A, fp_int *B) { - fp_word t; fp_digit *a, b[8], c0, c1, c2; a = A->dp; @@ -352,7 +356,6 @@ void fp_sqr_comba4(fp_int *A, fp_int *B) void fp_sqr_comba8(fp_int *A, fp_int *B) { - fp_word t; fp_digit *a, b[16], c0, c1, c2; a = A->dp; @@ -443,10 +446,10 @@ void fp_sqr_comba8(fp_int *A, fp_int *B) fp_clamp(B); } +#if defined(TFM_LARGE) void fp_sqr_comba16(fp_int *A, fp_int *B) { - fp_word t; fp_digit *a, b[32], c0, c1, c2; a = A->dp; @@ -617,11 +620,12 @@ void fp_sqr_comba16(fp_int *A, fp_int *B) fp_clamp(B); } +#endif /* TFM_LARGE */ + #ifdef TFM_HUGE void fp_sqr_comba32(fp_int *A, fp_int *B) { - fp_word t; fp_digit *a, b[64], c0, c1, c2; a = A->dp; diff --git a/gen.pl b/gen.pl index 127ec6f..c48dbab 100644 --- a/gen.pl +++ b/gen.pl @@ -6,7 +6,7 @@ use strict; open( OUT, ">mpi.c" ) or die "Couldn't open mpi.c for writing: $!"; -foreach my $filename (glob "fp_*.c") { +foreach my $filename (glob "*fp_*.c") { open( SRC, "<$filename" ) or die "Couldn't open $filename for reading: $!"; print OUT "/* Start: $filename */\n"; print OUT while ; @@ -14,4 +14,4 @@ foreach my $filename (glob "fp_*.c") { close SRC or die "Error closing $filename after reading: $!"; } print OUT "\n/* EOF */\n"; -close OUT or die "Error closing mpi.c after writing: $!"; \ No newline at end of file +close OUT or die "Error closing mpi.c after writing: $!"; diff --git a/makefile b/makefile index 967fa57..353f69a 100644 --- a/makefile +++ b/makefile @@ -10,7 +10,7 @@ CFLAGS += -Wall -W -Wshadow -I./ -O3 -funroll-all-loops #speed CFLAGS += -fomit-frame-pointer -VERSION=0.01 +VERSION=0.02 default: libtfm.a @@ -38,8 +38,9 @@ fp_cmp.o fp_cmp_mag.o \ \ fp_unsigned_bin_size.o fp_read_unsigned_bin.o fp_to_unsigned_bin.o \ fp_signed_bin_size.o fp_read_signed_bin.o fp_to_signed_bin.o \ -fp_read_radix.o fp_toradix.o fp_count_bits.o fp_reverse.o fp_s_rmap.o \ +fp_read_radix.o fp_toradix.o fp_radix_size.o fp_count_bits.o fp_reverse.o fp_s_rmap.o \ \ +fp_ident.o libtfm.a: $(OBJECTS) $(AR) $(ARFLAGS) libtfm.a $(OBJECTS) @@ -49,7 +50,7 @@ mtest/mtest: mtest/mtest.c cd mtest ; make mtest test: libtfm.a demo/test.o mtest/mtest - $(CC) demo/test.o libtfm.a $(PROF) -o test + $(CC) $(CFLAGS) demo/test.o libtfm.a $(PROF) -o test stest: libtfm.a demo/stest.o $(CC) demo/stest.o libtfm.a -o stest @@ -67,7 +68,7 @@ docs: docdvi mv -f tfm.pdf doc clean: - rm -f $(OBJECTS) *.a demo/*.o test tfm.aux tfm.dvi tfm.idx tfm.ilg tfm.ind tfm.lof tfm.log tfm.toc stest + rm -f $(OBJECTS) *.a demo/*.o test tfm.aux tfm.dvi tfm.idx tfm.ilg tfm.ind tfm.lof tfm.log tfm.toc stest *~ cd mtest ; make clean zipup: docs clean diff --git a/mtest/makefile b/mtest/makefile index a0cdf72..8e42029 100644 --- a/mtest/makefile +++ b/mtest/makefile @@ -6,4 +6,4 @@ mtest: mtest.o $(CC) mtest.o -ltommath -o mtest clean: - rm -f *.o mtest + rm -f *.o mtest *~ diff --git a/mtest/mtest.c b/mtest/mtest.c index be85362..3747406 100644 --- a/mtest/mtest.c +++ b/mtest/mtest.c @@ -235,10 +235,9 @@ int main(void) rand_num2(&a); rand_num2(&b); rand_num2(&c); -// if (c.dp[0]&1) mp_add_d(&c, 1, &c); a.sign = b.sign = c.sign = 0; c.dp[0] |= 1; - if (c.used <= 2) continue; +// if (c.used <= 4) continue; // if (mp_cmp(&a, &c) != MP_LT) continue; // if (mp_cmp(&b, &c) != MP_LT) continue; mp_exptmod(&a, &b, &c, &d); diff --git a/pre_gen/mpi.c b/pre_gen/mpi.c index 3ac1f64..14ea49c 100644 --- a/pre_gen/mpi.c +++ b/pre_gen/mpi.c @@ -709,7 +709,7 @@ int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d) * Some restrictions... x must be positive and < b */ -int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) +static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) { fp_int M[64], res; fp_digit buf, mp; @@ -730,7 +730,7 @@ int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) } /* init M array */ - memset(M, 0, sizeof(fp_int)*(1<sign == FP_NEG) { + /* yes, copy G and invmod it */ + fp_copy(G, &tmp); + if ((err = fp_invmod(&tmp, P, &tmp)) != FP_OKAY) { + return err; + } + /* _fp_exptmod doesn't care about the sign of X */ + return _fp_exptmod(&tmp, X, P, Y); + } else { + /* Positive exponent so just exptmod */ + return _fp_exptmod(G, X, P, Y); + } +} + + /* End: fp_exptmod.c */ /* Start: fp_gcd.c */ @@ -922,6 +943,76 @@ void fp_gcd(fp_int *a, fp_int *b, fp_int *c) /* End: fp_gcd.c */ +/* Start: fp_ident.c */ +#include "tfm.h" + +const char *fp_ident(void) +{ + static char buf[1024]; + + memset(buf, 0, sizeof(buf)); + snprintf(buf, sizeof(buf)-1, +"TomsFastMath (%s)\n" +"\n" +"Sizeofs\n" +"\tfp_digit = %u\n" +"\tfp_word = %u\n" +"\n" +"FP_MAX_SIZE = %u\n" +"\n" +"Defines: \n" +#ifdef __i386__ +" __i386__ " +#endif +#ifdef __x86_64__ +" __x86_64__ " +#endif +#ifdef TFM_X86 +" TFM_X86 " +#endif +#ifdef TFM_X86_64 +" TFM_X86_64 " +#endif +#ifdef TFM_SSE2 +" TFM_SSE2 " +#endif +#ifdef TFM_ARM +" TFM_ARM " +#endif +#ifdef TFM_NO_ASM +" TFM_NO_ASM " +#endif +#ifdef FP_64BIT +" FP_64BIT " +#endif +#ifdef TFM_LARGE +" TFM_LARGE " +#endif +#ifdef TFM_HUGE +" TFM_HUGE " +#endif +"\n", __DATE__, sizeof(fp_digit), sizeof(fp_word), FP_MAX_SIZE); + + if (sizeof(fp_digit) == sizeof(fp_word)) { + strncat(buf, "WARNING: sizeof(fp_digit) == sizeof(fp_word), this build is likely to not work properly.\n", + sizeof(buf)-1); + } + return buf; +} + +#ifdef STANDALONE + +int main(void) +{ + printf("%s\n", fp_ident()); + return 0; +} + +#endif + + +/* End: fp_ident.c */ + /* Start: fp_invmod.c */ /* TomsFastMath, a fast ISO C bignum library. * @@ -1186,7 +1277,19 @@ void fp_lshd(fp_int *a, int x) /* c = a mod b, 0 <= c < b */ int fp_mod(fp_int *a, fp_int *b, fp_int *c) { - return fp_div(a, b, NULL, c); + fp_int t; + int err; + + fp_zero(&t); + if ((err = fp_div(a, b, NULL, &t)) != FP_OKAY) { + return err; + } + if (t.sign != b->sign) { + fp_add(&t, b, c); + } else { + fp_copy(&t, c); + } + return FP_OKAY; } @@ -1282,7 +1385,7 @@ void fp_montgomery_calc_normalization(fp_int *a, fp_int *b) fp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1); } else { fp_set(a, 1); - ++bits; + bits = 1; } /* now compute C = A * B mod b */ @@ -1366,13 +1469,13 @@ asm( #define PROPCARRY \ asm( \ "movq %1,%%rax \n\t" \ +"movq %2,%%rbx \n\t" \ "addq %%rax,%6 \n\t" \ -"movq %2,%%rax \n\t" \ -"adcq %%rax,%7 \n\t" \ +"adcq %%rbx,%7 \n\t" \ "adcq $0,%8 \n\t" \ :"=g"(_c[OFF0]), "=g"(_c[OFF1]), "=g"(_c[OFF2]):"0"(_c[OFF0]), "1"(_c[OFF1]), "2"(_c[OFF2]), \ "m"(_c[OFF0+1]), "m"(_c[OFF1+1]), "m"(_c[OFF2+1]) \ -: "%rax", "%cc"); +: "%rax", "%rbx", "%cc"); #elif defined(TFM_SSE2) @@ -1388,7 +1491,7 @@ asm("emms"); asm(\ "movd %0,%%mm1 \n\t" \ "pmuludq %%mm2,%%mm1 \n\t" \ -:: "g"(c[x]), "g"(mp)); +:: "g"(c[x])); #define INNERMUL \ asm( \ @@ -1412,7 +1515,7 @@ asm( "adcl %%eax,%7 \n\t" \ "adcl $0,%8 \n\t" \ :"=g"(_c[OFF0]), "=g"(_c[OFF1]), "=g"(_c[OFF2]):"0"(_c[OFF0]), "1"(_c[OFF1]), "2"(_c[OFF2]), \ - "m"(_c[OFF0+1]), "m"(_c[OFF1+1]), "m"(_c[OFF2+1]) \ + "g"(_c[OFF0+1]), "g"(_c[OFF1+1]), "g"(_c[OFF2+1]) \ : "%eax", "%cc"); #elif defined(TFM_ARM) @@ -1466,14 +1569,18 @@ asm( \ mu = c[x] * mp; #define INNERMUL \ - t = ((fp_word)mu) * ((fp_word)*tmpm++); \ - _c[OFF0] += t; if (_c[OFF0] < (fp_digit)t) ++_c[OFF1]; \ - _c[OFF1] += (t>>DIGIT_BIT); if (_c[OFF1] < (fp_digit)(t>>DIGIT_BIT)) ++_c[OFF2]; \ + do { fp_word t; \ + t = (fp_word)_c[OFF0] + ((fp_word)mu) * ((fp_word)*tmpm++); _c[OFF0] = t; \ + t = (fp_word)_c[OFF1] + (t >> DIGIT_BIT); _c[OFF1] = t; \ + _c[OFF2] += (t >> DIGIT_BIT); \ + } while (0); #define PROPCARRY \ - _c[OFF0+1] += _c[OFF1]; if (_c[OFF0+1] < _c[OFF1]) ++_c[OFF1+1]; \ - _c[OFF1+1] += _c[OFF2]; if (_c[OFF1+1] < _c[OFF2]) ++_c[OFF2+1]; - + do { fp_word t; \ + t = (fp_word)_c[OFF0+1] + (fp_word)_c[OFF1]; _c[OFF0+1] = t; \ + t = (fp_word)_c[OFF1+1] + (t >> DIGIT_BIT) + (fp_word)_c[OFF2]; _c[OFF1+1] = t; \ + _c[OFF2+1] += (t >> DIGIT_BIT); \ + } while (0); #endif @@ -1487,7 +1594,6 @@ void fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp) { fp_digit c[3*FP_SIZE], *_c, *tmpm, mu; int oldused, x, y, pa; - fp_word t; /* now zero the buff */ pa = m->used; @@ -1521,13 +1627,13 @@ void fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp) /* fix the rest of the carries */ _c = c + pa; - for (; x < pa * 2 + 2; x++) { + for (x = pa; x < pa * 2 + 2; x++) { PROPCARRY; ++_c; } /* now copy out */ - _c = c + pa; + _c = c + pa; tmpm = a->dp; for (x = 0; x < pa+1; x++) { *tmpm++ = *_c++; @@ -1629,9 +1735,11 @@ void fp_mul(fp_int *A, fp_int *B, fp_int *C) fp_mul_comba4(A,B,C); } else if (y <= 8) { fp_mul_comba8(A,B,C); +#if defined(TFM_LARGE) } else if (y <= 16 && y >= 12) { fp_mul_comba16(A,B,C); -#ifdef TFM_HUGE +#endif +#if defined(TFM_HUGE) } else if (y <= 32 && y >= 28) { fp_mul_comba32(A,B,C); #endif @@ -1880,7 +1988,7 @@ void fp_mul_2d(fp_int *a, int b, fp_int *c) /* forward the carry to the next digit */ #define COMBA_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); /* store the first sum */ #define COMBA_STORE(x) \ @@ -1895,7 +2003,7 @@ void fp_mul_2d(fp_int *a, int b, fp_int *c) /* this should multiply i and j */ #define MULADD(i, j) \ -asm volatile ( \ +asm ( \ "movl %6,%%eax \n\t" \ "mull %7 \n\t" \ "addl %%eax,%0 \n\t" \ @@ -1915,7 +2023,7 @@ asm volatile ( \ /* forward the carry to the next digit */ #define COMBA_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); /* store the first sum */ #define COMBA_STORE(x) \ @@ -1930,13 +2038,13 @@ asm volatile ( \ /* this should multiply i and j */ #define MULADD(i, j) \ -asm volatile ( \ +asm ( \ "movq %6,%%rax \n\t" \ "mulq %7 \n\t" \ "addq %%rax,%0 \n\t" \ "adcq %%rdx,%1 \n\t" \ "adcq $0,%2 \n\t" \ - :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%rax","%rdx","%cc"); + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","%cc"); #elif defined(TFM_SSE2) /* use SSE2 optimizations */ @@ -1950,7 +2058,7 @@ asm volatile ( \ /* forward the carry to the next digit */ #define COMBA_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); /* store the first sum */ #define COMBA_STORE(x) \ @@ -1987,7 +2095,7 @@ asm volatile ( \ c0 = c1 = c2 = 0; #define COMBA_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); #define COMBA_STORE(x) \ x = c0; @@ -2008,13 +2116,13 @@ asm( \ #else /* ISO C code */ -#define COMBA_START +#define COMBA_START #define COMBA_CLEAR \ c0 = c1 = c2 = 0; #define COMBA_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); #define COMBA_STORE(x) \ x = c0; @@ -2022,12 +2130,13 @@ asm( \ #define COMBA_STORE2(x) \ x = c1; -#define COMBA_FINI - -#define MULADD(i, j) \ - t = ((fp_word)i) * ((fp_word)j); \ - c0 = (c0 + t); if (c0 < ((fp_digit)t)) ++c1; \ - c1 = (c1 + (t>>DIGIT_BIT)); if (c1 < (t>>DIGIT_BIT)) ++c2; +#define COMBA_FINI + +#define MULADD(i, j) \ + do { fp_word t; \ + t = (fp_word)c0 + ((fp_word)i) * ((fp_word)j); c0 = t; \ + t = (fp_word)c1 + (t >> DIGIT_BIT); c1 = t; c2 += t >> DIGIT_BIT; \ + } while (0); #endif @@ -2037,7 +2146,6 @@ void fp_mul_comba(fp_int *A, fp_int *B, fp_int *C) { int ix, iy, iz, tx, ty, pa; fp_digit c0, c1, c2, *tmpx, *tmpy; - fp_word t; fp_int tmp, *dst; COMBA_START; @@ -2092,7 +2200,6 @@ void fp_mul_comba(fp_int *A, fp_int *B, fp_int *C) void fp_mul_comba4(fp_int *A, fp_int *B, fp_int *C) { - fp_word t; fp_digit c0, c1, c2, at[8]; memcpy(at, A->dp, 4 * sizeof(fp_digit)); @@ -2137,7 +2244,6 @@ void fp_mul_comba4(fp_int *A, fp_int *B, fp_int *C) void fp_mul_comba8(fp_int *A, fp_int *B, fp_int *C) { - fp_word t; fp_digit c0, c1, c2, at[16]; memcpy(at, A->dp, 8 * sizeof(fp_digit)); @@ -2211,10 +2317,10 @@ void fp_mul_comba8(fp_int *A, fp_int *B, fp_int *C) COMBA_FINI; } +#if defined(TFM_LARGE) void fp_mul_comba16(fp_int *A, fp_int *B, fp_int *C) { - fp_word t; fp_digit c0, c1, c2, at[32]; memcpy(at, A->dp, 16 * sizeof(fp_digit)); @@ -2352,11 +2458,12 @@ void fp_mul_comba16(fp_int *A, fp_int *B, fp_int *C) COMBA_FINI; } +#endif /* TFM_LARGE */ + #ifdef TFM_HUGE void fp_mul_comba32(fp_int *A, fp_int *B, fp_int *C) { - fp_word t; fp_digit c0, c1, c2, at[64]; memcpy(at, A->dp, 32 * sizeof(fp_digit)); @@ -2880,6 +2987,41 @@ error: int fp_radix_size(fp_int *a, int radix, int *size) { + int digs; + fp_int t; + fp_digit d; + + *size = 0; + + /* check range of the radix */ + if (radix < 2 || radix > 64) { + return FP_VAL; + } + + /* quick out if its zero */ + if (fp_iszero(a) == 1) { + *size = 2; + return FP_OKAY; + } + + fp_init_copy(&t, a); + + /* if it is negative output a - */ + if (t.sign == FP_NEG) { + *size++; + t.sign = FP_ZPOS; + } + + digs = 0; + while (fp_iszero (&t) == FP_NO) { + fp_div_d (&t, (fp_digit) radix, &t, &d); + *size++; + } + + /* append a NULL so the string is properly terminated */ + *size++; + return FP_OKAY; + } /* End: fp_radix_size.c */ @@ -3161,9 +3303,11 @@ void fp_sqr(fp_int *A, fp_int *B) fp_sqr_comba4(A,B); } else if (y <= 8) { fp_sqr_comba8(A,B); +#if defined(TFM_LARGE) } else if (y <= 16 && y >= 12) { fp_sqr_comba16(A,B); -#ifdef TFM_HUGE +#endif +#if defined(TFM_HUGE) } else if (y <= 32 && y >= 28) { fp_sqr_comba32(A,B); #endif @@ -3279,7 +3423,7 @@ Obvious points of optimization x = c1; #define CARRY_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); #define COMBA_FINI @@ -3319,21 +3463,21 @@ asm volatile ( \ x = c1; #define CARRY_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); #define COMBA_FINI #define SQRADD(i, j) \ -asm volatile ( \ +asm ( \ "movq %6,%%rax \n\t" \ "mulq %%rax \n\t" \ "addq %%rax,%0 \n\t" \ "adcq %%rdx,%1 \n\t" \ "adcq $0,%2 \n\t" \ - :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%rax","%rdx","%cc"); + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i) :"%rax","%rdx","%cc"); #define SQRADD2(i, j) \ -asm volatile ( \ +asm ( \ "movq %6,%%rax \n\t" \ "mulq %7 \n\t" \ "addq %%rax,%0 \n\t" \ @@ -3342,7 +3486,7 @@ asm volatile ( \ "addq %%rax,%0 \n\t" \ "adcq %%rdx,%1 \n\t" \ "adcq $0,%2 \n\t" \ - :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%rax","%rdx","%cc"); + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","%cc"); #elif defined(TFM_SSE2) @@ -3360,7 +3504,7 @@ asm volatile ( \ x = c1; #define CARRY_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); #define COMBA_FINI \ asm("emms"); @@ -3371,11 +3515,11 @@ asm volatile ( \ "pmuludq %%mm0,%%mm0\n\t" \ "movd %%mm0,%%eax \n\t" \ "psrlq $32,%%mm0 \n\t" \ - "movd %%mm0,%%edx \n\t" \ "addl %%eax,%0 \n\t" \ - "adcl %%edx,%1 \n\t" \ + "movd %%mm0,%%eax \n\t" \ + "adcl %%eax,%1 \n\t" \ "adcl $0,%2 \n\t" \ - :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%edx","%cc"); + :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%cc"); #define SQRADD2(i, j) \ asm volatile ( \ @@ -3409,7 +3553,7 @@ asm volatile ( \ x = c1; #define CARRY_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); #define COMBA_FINI @@ -3438,7 +3582,8 @@ asm( \ /* ISO C portable code */ -#define COMBA_START +#define COMBA_START \ + { fp_word tt; #define CLEAR_CARRY \ c0 = c1 = c2 = 0; @@ -3450,23 +3595,28 @@ asm( \ x = c1; #define CARRY_FORWARD \ - c0 = c1; c1 = c2; c2 = 0; + do { c0 = c1; c1 = c2; c2 = 0; } while (0); -#define COMBA_FINI +#define COMBA_FINI \ + } /* multiplies point i and j, updates carry "c1" and digit c2 */ -#define SQRADD(i, j) \ - t = ((fp_word)i) * ((fp_word)j); \ - c0 = (c0 + t); if (c0 < ((fp_digit)t)) ++c1; \ - c1 = (c1 + (t>>DIGIT_BIT)); if (c1 < (t>>DIGIT_BIT)) ++c2; +#define SQRADD(i, j) \ + do { fp_word t; \ + t = c0 + ((fp_word)i) * ((fp_word)j); c0 = t; \ + t = c1 + (t >> DIGIT_BIT); c1 = t; c2 += t >> DIGIT_BIT; \ + } while (0); + /* for squaring some of the terms are doubled... */ -#define SQRADD2(i, j) \ - t = ((fp_word)i) * ((fp_word)j); \ - c0 = (c0 + t); if (c0 < ((fp_digit)t)) ++c1; \ - c1 = (c1 + (t>>DIGIT_BIT)); if (c1 < (t>>DIGIT_BIT)) ++c2; \ - c0 = (c0 + t); if (c0 < ((fp_digit)t)) ++c1; \ - c1 = (c1 + (t>>DIGIT_BIT)); if (c1 < (t>>DIGIT_BIT)) ++c2; +#define SQRADD2(i, j) \ + do { fp_word t; \ + t = ((fp_word)i) * ((fp_word)j); \ + tt = (fp_word)c0 + t; c0 = tt; \ + tt = (fp_word)c1 + (tt >> DIGIT_BIT); c1 = tt; c2 += tt >> DIGIT_BIT; \ + tt = (fp_word)c0 + t; c0 = tt; \ + tt = (fp_word)c1 + (tt >> DIGIT_BIT); c1 = tt; c2 += tt >> DIGIT_BIT; \ + } while (0); #endif @@ -3476,7 +3626,6 @@ void fp_sqr_comba(fp_int *A, fp_int *B) int pa, ix, iz; fp_digit c0, c1, c2; fp_int tmp, *dst; - fp_word t; /* get size of output and trim */ pa = A->used + A->used; @@ -3549,7 +3698,6 @@ void fp_sqr_comba(fp_int *A, fp_int *B) void fp_sqr_comba4(fp_int *A, fp_int *B) { - fp_word t; fp_digit *a, b[8], c0, c1, c2; a = A->dp; @@ -3603,7 +3751,6 @@ void fp_sqr_comba4(fp_int *A, fp_int *B) void fp_sqr_comba8(fp_int *A, fp_int *B) { - fp_word t; fp_digit *a, b[16], c0, c1, c2; a = A->dp; @@ -3694,10 +3841,10 @@ void fp_sqr_comba8(fp_int *A, fp_int *B) fp_clamp(B); } +#if defined(TFM_LARGE) void fp_sqr_comba16(fp_int *A, fp_int *B) { - fp_word t; fp_digit *a, b[32], c0, c1, c2; a = A->dp; @@ -3868,11 +4015,12 @@ void fp_sqr_comba16(fp_int *A, fp_int *B) fp_clamp(B); } +#endif /* TFM_LARGE */ + #ifdef TFM_HUGE void fp_sqr_comba32(fp_int *A, fp_int *B) { - fp_word t; fp_digit *a, b[64], c0, c1, c2; a = A->dp; @@ -4455,5 +4603,81 @@ int fp_unsigned_bin_size(fp_int *a) /* End: fp_unsigned_bin_size.c */ +/* Start: s_fp_add.c */ +/* TomsFastMath, a fast ISO C bignum library. + * + * This project is meant to fill in where LibTomMath + * falls short. That is speed ;-) + * + * This project is public domain and free for all purposes. + * + * Tom St Denis, tomstdenis@iahu.ca + */ +#include + +/* unsigned addition */ +void s_fp_add(fp_int *a, fp_int *b, fp_int *c) +{ + int x, y, oldused; + fp_word t; + + y = MAX(a->used, b->used); + oldused = c->used; + c->used = y; + + t = 0; + for (x = 0; x < y; x++) { + t += ((fp_word)a->dp[x]) + ((fp_word)b->dp[x]); + c->dp[x] = (fp_digit)t; + t >>= DIGIT_BIT; + } + if (t != 0 && x != FP_SIZE) { + c->dp[c->used++] = (fp_digit)t; + ++x; + } + + for (; x < oldused; x++) { + c->dp[x] = 0; + } + fp_clamp(c); +} + +/* End: s_fp_add.c */ + +/* Start: s_fp_sub.c */ +/* TomsFastMath, a fast ISO C bignum library. + * + * This project is meant to fill in where LibTomMath + * falls short. That is speed ;-) + * + * This project is public domain and free for all purposes. + * + * Tom St Denis, tomstdenis@iahu.ca + */ +#include + +/* unsigned subtraction ||a|| >= ||b|| ALWAYS! */ +void s_fp_sub(fp_int *a, fp_int *b, fp_int *c) +{ + int x, oldused; + fp_word t; + + oldused = c->used; + c->used = a->used; + t = 0; + for (x = 0; x < a->used; x++) { + t = ((fp_word)a->dp[x]) - (((fp_word)b->dp[x]) + t); + c->dp[x] = (fp_digit)t; + t = (t >> DIGIT_BIT) & 1; + } + + for (; x < oldused; x++) { + c->dp[x] = 0; + } + fp_clamp(c); +} + +/* End: s_fp_sub.c */ + /* EOF */ diff --git a/tfm.h b/tfm.h index 9b12946..c927bae 100644 --- a/tfm.h +++ b/tfm.h @@ -21,9 +21,19 @@ #undef MAX #define MAX(x,y) ((x)>(y)?(x):(y)) -/* do we want huge code? The answer is, yes. */ +/* do we want large code? */ +#define TFM_LARGE + +/* do we want huge code (implies large)? The answer is, yes. */ #define TFM_HUGE +/* imply TFM_LARGE as required */ +#if defined(TFM_HUGE) + #if !defined(TFM_LARGE) + #define TFM_LARGE + #endif +#endif + /* Max size of any number in bits. Basically the largest size you will be multiplying * should be half [or smaller] of FP_MAX_SIZE-four_digit * @@ -41,19 +51,69 @@ #error FP_MAX_SIZE must be a multiple of CHAR_BIT #endif -/* make sure we are using 64-bit digits with x86-64 asm */ +/* autodetect x86-64 and make sure we are using 64-bit digits with x86-64 asm */ +#if defined(__x86_64__) + #if defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM) + #error x86-64 detected, x86-32/SSE2/ARM optimizations are not valid! + #endif + #if !defined(TFM_X86_64) && !defined(TFM_NO_ASM) + #define TFM_X86_64 + #endif +#endif #if defined(TFM_X86_64) - #ifndef FP_64BIT + #if !defined(FP_64BIT) #define FP_64BIT #endif #endif +/* try to detect x86-32 */ +#if defined(__i386__) && !defined(TFM_SSE2) + #if defined(TFM_X86_64) || defined(TFM_ARM) + #error x86-32 detected, x86-64/ARM optimizations are not valid! + #endif + #if !defined(TFM_X86) && !defined(TFM_NO_ASM) + #define TFM_X86 + #endif +#endif + /* make sure we're 32-bit for x86-32/sse/arm */ #if (defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM)) && defined(FP_64BIT) #warning x86-32, SSE2 and ARM optimizations require 32-bit digits (undefining) #undef FP_64BIT #endif +/* multi asms? */ +#ifdef TFM_X86 + #define TFM_ASM +#endif +#ifdef TFM_X86_64 + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif +#ifdef TFM_SSE2 + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif +#ifdef TFM_ARM + #ifdef TFM_ASM + #error TFM_ASM already defined! + #endif + #define TFM_ASM +#endif + +/* we want no asm? */ +#ifdef TFM_NO_ASM + #undef TFM_X86 + #undef TFM_X86_64 + #undef TFM_SSE2 + #undef TFM_ARM + #undef TFM_ASM +#endif + /* some default configurations. */ #if defined(FP_64BIT) @@ -110,8 +170,11 @@ typedef struct { /* functions */ +/* returns a TFM ident string useful for debugging... */ +const char *fp_ident(void); + /* initialize [or zero] an fp int */ -#define fp_init(a) memset((a), 0, sizeof(fp_int)) +#define fp_init(a) (void)memset((a), 0, sizeof(fp_int)) #define fp_zero(a) fp_init(a) /* zero/even/odd ? */ @@ -123,7 +186,7 @@ typedef struct { void fp_set(fp_int *a, fp_digit b); /* copy from a to b */ -#define fp_copy(a, b) (((a) != (b)) && memcpy((b), (a), sizeof(fp_int))) +#define fp_copy(a, b) (void)(((a) != (b)) && memcpy((b), (a), sizeof(fp_int))) #define fp_init_copy(a, b) fp_copy(b, a) /* negate and absolute */ @@ -139,10 +202,10 @@ void fp_rshd(fp_int *a, int x); /* left shift x digits */ void fp_lshd(fp_int *a, int x); -/* signed comparisonm */ +/* signed comparison */ int fp_cmp(fp_int *a, fp_int *b); -/* unsigned comparisonm */ +/* unsigned comparison */ int fp_cmp_mag(fp_int *a, fp_int *b); /* power of 2 operations */ @@ -273,14 +336,18 @@ void fp_mul_comba(fp_int *A, fp_int *B, fp_int *C); #ifdef TFM_HUGE void fp_mul_comba32(fp_int *A, fp_int *B, fp_int *C); #endif +#ifdef TFM_LARGE void fp_mul_comba16(fp_int *A, fp_int *B, fp_int *C); +#endif void fp_mul_comba8(fp_int *A, fp_int *B, fp_int *C); void fp_mul_comba4(fp_int *A, fp_int *B, fp_int *C); void fp_sqr_comba(fp_int *A, fp_int *B); void fp_sqr_comba4(fp_int *A, fp_int *B); void fp_sqr_comba8(fp_int *A, fp_int *B); +#ifdef TFM_LARGE void fp_sqr_comba16(fp_int *A, fp_int *B); +#endif #ifdef TFM_HUGE void fp_sqr_comba32(fp_int *A, fp_int *B); #endif diff --git a/tfm.tex b/tfm.tex index 914208c..db09a6e 100644 --- a/tfm.tex +++ b/tfm.tex @@ -49,7 +49,7 @@ \begin{document} \frontmatter \pagestyle{empty} -\title{TomsFastMath User Manual \\ v0.01} +\title{TomsFastMath User Manual \\ v0.02} \author{Tom St Denis \\ tomstdenis@iahu.ca} \maketitle This text and library are all hereby placed in the public domain. This book has been formatted for B5 @@ -128,23 +128,27 @@ several ``CFLAGS'' defines. For example, to build with with SSE2 optimizations type \begin{verbatim} -export CFLAGS=-DTFM_SSE2 -make clean libtfm.a +CFLAGS=-DTFM_SSE2 make clean libtfm.a \end{verbatim} \subsubsection{x86--32} The ``x86--32'' mode is defined by ``TFM\_X86'' and covers all i386 and beyond processors. It requires GCC to build and only works with 32--bit digits. In this -mode fp\_digit is 32--bits and fp\_word is 64--bits. +mode fp\_digit is 32--bits and fp\_word is 64--bits. This mode will be autodetected when building +with GCC to an ``i386'' target. You can override this behaviour by defining TFM\_NO\_ASM or +another optimization mode (such as SSE2). \subsubsection{SSE2} The ``SSE2'' mode is defined by ``TFM\_SSE2'' and requires a Pentium 4, Pentium M or Athlon64 processor. It requires GCC to build. Note that you shouldn't define both TFM\_X86 and TFM\_SSE2 at the same time. This mode only works with 32--bit digits. In this -mode fp\_digit is 32--bits and fp\_word is 64--bits. +mode fp\_digit is 32--bits and fp\_word is 64--bits. While this mode will work on the AMD Athlon64 +series of processors it is less efficient than the native ``x86--64'' mode and not recommended. \subsubsection{x86--64} The ``x86--64'' mode is defined by ``TFM\_X86\_64'' and requires a ``x86--64'' capable processor (Athlon64 and future Pentium processors). It requires GCC to build and only works with 64--bit digits. Note that by enabling this mode it will automatically -enable 64--bit digits. In this mode fp\_digit is 64--bits and fp\_word is 128--bits. +enable 64--bit digits. In this mode fp\_digit is 64--bits and fp\_word is 128--bits. This mode will +be autodetected when building with GCC to an ``x86--64'' target. You can override this behaviour by defining +TFM\_NO\_ASM. \subsubsection{ARM} The ``ARM'' mode is defined by ``TFM\_ARM'' and requires a ARMv4 or higher processor. It requires GCC and works with 32--bit digits. In this mode fp\_digit is 32--bits and @@ -163,6 +167,8 @@ Developers of MIPS and PPC platforms are encouraged to submit GCC asm inline pat \hline Pentium 4 & TFM\_SSE2 \\ \hline Athlon64 & TFM\_X86\_64 \\ \hline ARMv4 or higher & TFM\_ARM \\ +\hline &\\ +\hline x86--32 or x86--64 (with GCC) & Leave blank and let autodetect work \\ \hline \end{tabular} \caption{Recommended Build Modes} @@ -339,9 +345,10 @@ To compute a modular exponentiation use the following function. \begin{verbatim} int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); \end{verbatim} -This computes $d \equiv a^b \mbox{ (mod }c)$ for any odd $c$ and positive $b$. The size of $c$ -must be half of the maximum precision used during the build of the library. For example, -by default $c$ must be less than $2^{2048}$. +This computes $d \equiv a^b \mbox{ (mod }c\mbox{)}$ for any odd $c$ and $b$. $b$ may be negative so long as +$a^{-1} \mbox{ (mod }c\mbox{)}$ exists. The initial value of $a$ may be larger than $c$. The size of $c$ must be +half of the maximum precision used during the build of the library. For example, by default $c$ must be less +than $2^{2048}$. \section{Number Theoretic}