Commit d5b0f1e993f3a9ed915ec875bfa5c47b380162b4

Steffen Jaeckel 2016-04-10T13:55:42

loop&shift until enough random data has been read

diff --git a/bn_mp_rand.c b/bn_mp_rand.c
index 6f300c0..fc98e52 100644
--- a/bn_mp_rand.c
+++ b/bn_mp_rand.c
@@ -15,15 +15,28 @@
  * 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;
-  d = ((mp_digit) abs (MP_GEN_RANDOM()));
-#if MP_DIGIT_BIT > 32
-  d <<= 32;
-  d |= ((mp_digit) abs (MP_GEN_RANDOM()));
-#endif
+  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;
 }
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