Use pseudo random generator for primality test

This commit is contained in:
NIIBE Yutaka
2013-10-01 11:53:00 +09:00
parent 4a78181c10
commit 093917927b
3 changed files with 107 additions and 9 deletions

View File

@@ -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> 2013-09-30 Niibe Yutaka <gniibe@fsij.org>
* polarssl/library/bignum.c (mpi_is_prime): Enable trial divisions * polarssl/library/bignum.c (mpi_is_prime): Enable trial divisions

View File

@@ -1759,6 +1759,7 @@ cleanup:
static const int small_prime[] = static const int small_prime[] =
{ {
#if 0
3, 5, 7, 11, 13, 17, 19, 23, 3, 5, 7, 11, 13, 17, 19, 23,
29, 31, 37, 41, 43, 47, 53, 59, 29, 31, 37, 41, 43, 47, 53, 59,
61, 67, 71, 73, 79, 83, 89, 97, 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, 521, 523, 541, 547, 557, 563, 569, 571,
577, 587, 593, 599, 601, 607, 613, 617, 577, 587, 593, 599, 601, 607, 613, 617,
619, 631, 641, 643, 647, 653, 659, 661, 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, 733, 739, 743, 751, 757, 761, 769, 773,
787, 797, 809, 811, 821, 823, 827, 829, 787, 797, 809, 811, 821, 823, 827, 829,
839, 853, 857, 859, 863, 877, 881, 883, 839, 853, 857, 859, 863, 877, 881, 883,
887, 907, 911, 919, 929, 937, 941, 947, 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) * Miller-Rabin primality test (HAC 4.24)
*/ */
static static
int mpi_is_prime( mpi *X, int mpi_is_prime( mpi *X)
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{ {
int ret, xs; int ret, xs;
size_t i, j, n, s; size_t i, j, n, s;
@@ -1815,8 +1901,7 @@ int mpi_is_prime( mpi *X,
return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
#endif #endif
#define SMALL_PRIME_START 124 for( i = 0; small_prime[i] > 0; i++ )
for( i = SMALL_PRIME_START; small_prime[i] > 0; i++ )
{ {
t_uint r; t_uint r;
@@ -1861,7 +1946,7 @@ int mpi_is_prime( mpi *X,
/* /*
* pick a random A, 1 < A < |X| - 1 * 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 ) 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) if (X->n <= 31 || (X->p[31] & 0xc0000000) == 0)
continue; continue;
ret = mpi_is_prime ( X, f_rng, p_rng ); ret = mpi_is_prime ( X );
if (ret == 0 || ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE) if (ret == 0 || ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE)
break; break;
} }

View File

@@ -216,10 +216,16 @@ rsa_genkey (void)
uint8_t *p = p_q_modulus; uint8_t *p = p_q_modulus;
uint8_t *q = p_q_modulus + KEY_CONTENT_LEN/2; uint8_t *q = p_q_modulus + KEY_CONTENT_LEN/2;
uint8_t *modulus = p_q_modulus + KEY_CONTENT_LEN; 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) if (p_q_modulus == NULL)
return NULL; return NULL;
neug_flush ();
prng_seed (random_gen, &index);
rsa_init (&rsa_ctx, RSA_PKCS_V15, 0); rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
r = rsa_gen_key (&rsa_ctx, random_gen, &index, r = rsa_gen_key (&rsa_ctx, random_gen, &index,
KEY_CONTENT_LEN * 8, RSA_EXPONENT); KEY_CONTENT_LEN * 8, RSA_EXPONENT);