Commit b8527e92f8401a79b86e779caaaf00dca83f73c7

Steffen Jaeckel 2016-10-10T00:48:15

Merge branch 'fix/56' into develop This closes #56 and #57

diff --git a/bn_mp_rand.c b/bn_mp_rand.c
index 4c9610d..fc98e52 100644
--- a/bn_mp_rand.c
+++ b/bn_mp_rand.c
@@ -15,7 +15,32 @@
  * Tom St Denis, tstdenis82@gmail.com, http://libtom.org
  */
 
+#if MP_GEN_RANDOM_MAX == 0xffffffff
+  #define MP_GEN_RANDOM_SHIFT  32
+#elif MP_GEN_RANDOM_MAX == 32767
+  /* SHRT_MAX */
+  #define MP_GEN_RANDOM_SHIFT  15
+#elif MP_GEN_RANDOM_MAX == 2147483647
+  /* INT_MAX */
+  #define MP_GEN_RANDOM_SHIFT  31
+#elif !defined(MP_GEN_RANDOM_SHIFT)
+#error Thou shalt define their own valid MP_GEN_RANDOM_SHIFT
+#endif
+
 /* makes a pseudo-random int of a given size */
+static mp_digit mp_gen_random(void)
+{
+  mp_digit d = 0, msk = 0;
+  do {
+    d <<= MP_GEN_RANDOM_SHIFT;
+    d |= ((mp_digit) MP_GEN_RANDOM());
+    msk <<= MP_GEN_RANDOM_SHIFT;
+    msk |= MP_GEN_RANDOM_MAX;
+  } while ((MP_MASK & msk) != MP_MASK);
+  d &= MP_MASK;
+  return d;
+}
+
 int
 mp_rand (mp_int * a, int digits)
 {
@@ -29,7 +54,7 @@ mp_rand (mp_int * a, int digits)
 
   /* first place a random non-zero digit */
   do {
-    d = ((mp_digit) abs (MP_GEN_RANDOM())) & MP_MASK;
+    d = mp_gen_random();
   } while (d == 0);
 
   if ((res = mp_add_d (a, d, a)) != MP_OKAY) {
@@ -41,7 +66,7 @@ mp_rand (mp_int * a, int digits)
       return res;
     }
 
-    if ((res = mp_add_d (a, ((mp_digit) abs (MP_GEN_RANDOM())), a)) != MP_OKAY) {
+    if ((res = mp_add_d (a, mp_gen_random(), a)) != MP_OKAY) {
       return res;
     }
   }
diff --git a/tommath.h b/tommath.h
index cec3722..b1a97af 100644
--- a/tommath.h
+++ b/tommath.h
@@ -102,8 +102,10 @@ extern "C" {
 /* use arc4random on platforms that support it */
 #ifdef MP_USE_ALT_RAND
     #define MP_GEN_RANDOM()    arc4random()
+    #define MP_GEN_RANDOM_MAX  0xffffffff
 #else
     #define MP_GEN_RANDOM()    rand()
+    #define MP_GEN_RANDOM_MAX  RAND_MAX
 #endif
 
 #define MP_DIGIT_BIT     DIGIT_BIT