Use pseudo random generator for primality test
authorNIIBE Yutaka <gniibe@fsij.org>
Tue, 1 Oct 2013 02:53:00 +0000 (11:53 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Tue, 1 Oct 2013 02:53:00 +0000 (11:53 +0900)
ChangeLog
polarssl/library/bignum.c
src/call-rsa.c

index f34eb7f..d0a0d4c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2013-10-01  Niibe Yutaka  <gniibe@fsij.org>
+
+       * src/call-rsa.c (rsa_genkey): Call neug_flush and prng_seed.
+       * polarssl/library/bignum.c (small_prime): More constants.
+       (prng_seed, jkiss, mpi_fill_pseudo_random): New.
+       (mpi_is_prime): Use mpi_fill_pseudo_random.
+
 2013-09-30  Niibe Yutaka  <gniibe@fsij.org>
 
        * polarssl/library/bignum.c (mpi_is_prime): Enable trial divisions
index 9507e41..9a756d1 100644 (file)
@@ -1759,6 +1759,7 @@ cleanup:
 
 static const int small_prime[] =
 {
+#if 0
         3,    5,    7,   11,   13,   17,   19,   23,
        29,   31,   37,   41,   43,   47,   53,   59,
        61,   67,   71,   73,   79,   83,   89,   97,
@@ -1774,21 +1775,106 @@ static const int small_prime[] =
       521,  523,  541,  547,  557,  563,  569,  571,
       577,  587,  593,  599,  601,  607,  613,  617,
       619,  631,  641,  643,  647,  653,  659,  661,
-      673,  677,  683,  691,  701,  709,  719,  727,
+      673,  677,  683,  691,
+#endif
+                             701,  709,  719,  727,
       733,  739,  743,  751,  757,  761,  769,  773,
       787,  797,  809,  811,  821,  823,  827,  829,
       839,  853,  857,  859,  863,  877,  881,  883,
       887,  907,  911,  919,  929,  937,  941,  947,
-      953,  967,  971,  977,  983,  991,  997, -103
+      953,  967,  971,  977,  983,  991,  997, 
+                                               1009, 
+     1013, 1019, 1021, 
+
+#if 1
+                       1031, 1033, 1039, 1049, 1051,
+     1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103,
+     1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171,
+     1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229,
+     1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289,
+     1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327,
+     1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427,
+     1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471,
+     1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523,
+     1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579,
+     1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621,
+     1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697,
+     1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753,
+     1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823,
+     1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879,
+     1889,
+#endif
+
+     -103
 };
 
+/*
+ * From Public domain code of JKISS RNG.
+ *
+ * Reference: David Jones, UCL Bioinformatics Group
+ * Good Practice in (Pseudo) Random Number Generation for
+ * Bioinformatics Applications
+ *
+ */
+struct jkiss_state { uint32_t x, y, z, c; };
+static struct jkiss_state jkiss_state_v;
+
+int prng_seed (int (*f_rng)(void *, unsigned char *, size_t),
+              void *p_rng)
+{
+  int ret;
+
+  struct jkiss_state *s = &jkiss_state_v;
+
+  MPI_CHK ( f_rng (p_rng, (unsigned char *)s, sizeof (struct jkiss_state)) );
+  while (s->y == 0)
+    MPI_CHK ( f_rng (p_rng, (unsigned char *)&s->y, sizeof (uint32_t)) );
+  s->z |= 1;                   /* avoiding z=c=0 */
+
+cleanup:
+  return ret;
+}
+
+static uint32_t
+jkiss (struct jkiss_state *s)
+{
+  uint64_t t;
+
+  s->x = 314527869 * s->x + 1234567;
+  s->y ^= s->y << 5;
+  s->y ^= s->y >> 7;
+  s->y ^= s->y << 22;
+  t = 4294584393ULL * s->z + s->c;
+  s->c = (uint32_t)(t >> 32);
+  s->z = (uint32_t)t;
+
+  return s->x + s->y + s->z;
+}
+
+static int mpi_fill_pseudo_random ( mpi *X, size_t size)
+{
+  int ret;
+  uint32_t *p;
+
+  MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) );
+  MPI_CHK( mpi_lset( X, 0 ) );
+
+  /* Assume little endian.  */
+  p = X->p;
+  while (p < X->p + (size/ciL))
+    *p++ = jkiss (&jkiss_state_v);
+  if ((size % ciL))
+    *p = jkiss (&jkiss_state_v) & ((1 << (8*(size % ciL))) - 1);
+
+cleanup:
+  return ret;
+}
+
 /*
  * Miller-Rabin primality test  (HAC 4.24)
  */
 static
-int mpi_is_prime( mpi *X,
-                  int (*f_rng)(void *, unsigned char *, size_t),
-                  void *p_rng )
+int mpi_is_prime( mpi *X)
 {
     int ret, xs;
     size_t i, j, n, s;
@@ -1815,8 +1901,7 @@ int mpi_is_prime( mpi *X,
         return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
 #endif
 
-#define SMALL_PRIME_START 124
-    for( i = SMALL_PRIME_START; small_prime[i] > 0; i++ )
+    for( i = 0; small_prime[i] > 0; i++ )
     {
         t_uint r;
 
@@ -1861,7 +1946,7 @@ int mpi_is_prime( mpi *X,
         /*
          * pick a random A, 1 < A < |X| - 1
          */
-        MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
+        MPI_CHK( mpi_fill_pseudo_random( &A, X->n * ciL ) );
 
         if( mpi_cmp_mpi( &A, &W ) >= 0 )
         {
@@ -1995,7 +2080,7 @@ int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
       if (X->n <= 31 || (X->p[31] & 0xc0000000) == 0)
        continue;
 
-      ret = mpi_is_prime ( X, f_rng, p_rng );
+      ret = mpi_is_prime ( X );
       if (ret == 0 || ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE)
        break;
     }
index 2322091..1648705 100644 (file)
@@ -216,10 +216,16 @@ rsa_genkey (void)
   uint8_t *p = p_q_modulus;
   uint8_t *q = p_q_modulus + KEY_CONTENT_LEN/2;
   uint8_t *modulus = p_q_modulus + KEY_CONTENT_LEN;
+  extern int prng_seed (int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng);
+  extern void neug_flush (void);
 
   if (p_q_modulus == NULL)
     return NULL;
 
+  neug_flush ();
+  prng_seed (random_gen, &index);
+
   rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
   r = rsa_gen_key (&rsa_ctx, random_gen, &index,
                   KEY_CONTENT_LEN * 8, RSA_EXPONENT);