diff --git a/src/headers/tfm.h b/src/headers/tfm.h index f406388..d36caaa 100644 --- a/src/headers/tfm.h +++ b/src/headers/tfm.h @@ -252,6 +252,19 @@ #endif #endif +/* platforms that can use a better rand function */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) + #define FP_USE_ALT_RAND 1 +#endif + +/* use arc4random on platforms that support it */ +#ifdef FP_USE_ALT_RAND + #define FP_GEN_RANDOM() arc4random() + #define FP_GEN_RANDOM_MAX 0xffffffff +#else + #define FP_GEN_RANDOM() rand() + #define FP_GEN_RANDOM_MAX RAND_MAX +#endif /* some default configurations. */ diff --git a/src/misc/fp_rand.c b/src/misc/fp_rand.c index c1dd766..01198c5 100644 --- a/src/misc/fp_rand.c +++ b/src/misc/fp_rand.c @@ -9,7 +9,31 @@ */ #include +#if FP_GEN_RANDOM_MAX == 0xffffffff + #define FP_GEN_RANDOM_SHIFT 32 +#elif FP_GEN_RANDOM_MAX == 32767 + /* SHRT_MAX */ + #define FP_GEN_RANDOM_SHIFT 15 +#elif FP_GEN_RANDOM_MAX == 2147483647 + /* INT_MAX */ + #define FP_GEN_RANDOM_SHIFT 31 +#elif !defined(FP_GEN_RANDOM_SHIFT) +#error Thou shalt define their own valid FP_GEN_RANDOM_SHIFT +#endif + /* makes a pseudo-random int of a given size */ +static fp_digit fp_gen_random(void) +{ + fp_digit d = 0, msk = 0; + do { + d <<= FP_GEN_RANDOM_SHIFT; + d |= ((fp_digit) FP_GEN_RANDOM()); + msk <<= FP_GEN_RANDOM_SHIFT; + msk |= FP_GEN_RANDOM_MAX; + } while ((FP_MASK & msk) != FP_MASK); + d &= FP_MASK; + return d; +} void fp_rand(fp_int *a, int digits) { @@ -22,14 +46,14 @@ void fp_rand(fp_int *a, int digits) /* first place a random non-zero digit */ do { - d = ((fp_digit) abs (rand ())) & FP_MASK; + d = fp_gen_random(); } while (d == 0); fp_add_d (a, d, a); while (--digits > 0) { fp_lshd (a, 1); - fp_add_d (a, ((fp_digit) abs (rand ())), a); + fp_add_d (a, fp_gen_random(), a); } return;