From 093917927bbcd0e9afd1ab165f96c3faf99cd76d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 1 Oct 2013 11:53:00 +0900 Subject: [PATCH] Use pseudo random generator for primality test --- ChangeLog | 7 +++ polarssl/library/bignum.c | 103 ++++++++++++++++++++++++++++++++++---- src/call-rsa.c | 6 +++ 3 files changed, 107 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index f34eb7f..d0a0d4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-10-01 Niibe Yutaka + + * 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 * polarssl/library/bignum.c (mpi_is_prime): Enable trial divisions diff --git a/polarssl/library/bignum.c b/polarssl/library/bignum.c index 9507e41..9a756d1 100644 --- a/polarssl/library/bignum.c +++ b/polarssl/library/bignum.c @@ -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; } diff --git a/src/call-rsa.c b/src/call-rsa.c index 2322091..1648705 100644 --- a/src/call-rsa.c +++ b/src/call-rsa.c @@ -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);