Generate primes according to FIPS 186-4

The specification requires that numbers are the raw entropy (except for odd/
even) and at least 2^(nbits-0.5). If not, new random bits need to be used for
the next number. Similarly, if the number is not prime new random bits need to
be used.
This commit is contained in:
Jethro Beekman 2018-02-14 19:24:10 -08:00
parent 97f95c9ef3
commit 666892792d
2 changed files with 74 additions and 54 deletions

View file

@ -2194,12 +2194,23 @@ int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
/* /*
* Prime number generation * Prime number generation
*
* If dh_flag is 0 and nbits is at least 1024, then the procedure
* follows the RSA probably-prime generation method of FIPS 186-4.
* NB. FIPS 186-4 only allows the specific bit lengths of 1024 and 1536.
*/ */
int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag, int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
int (*f_rng)(void *, unsigned char *, size_t), int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng ) void *p_rng )
{ {
int ret; #ifdef MBEDTLS_HAVE_INT64
// ceil(2^63.5)
#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
#else
// ceil(2^31.5)
#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
#endif
int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
size_t k, n; size_t k, n;
mbedtls_mpi_uint r; mbedtls_mpi_uint r;
mbedtls_mpi Y; mbedtls_mpi Y;
@ -2211,24 +2222,22 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
n = BITS_TO_LIMBS( nbits ); n = BITS_TO_LIMBS( nbits );
while( 1 )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
/* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue;
k = mbedtls_mpi_bitlen( X ); k = n * biL;
if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits + 1 ) ); if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) );
mbedtls_mpi_set_bit( X, nbits-1, 1 );
X->p[0] |= 1; X->p[0] |= 1;
if( dh_flag == 0 ) if( dh_flag == 0 )
{ {
while( ( ret = mbedtls_mpi_is_prime( X, f_rng, p_rng ) ) != 0 ) ret = mbedtls_mpi_is_prime( X, f_rng, p_rng );
{
if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
goto cleanup; goto cleanup;
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 2 ) );
}
} }
else else
{ {
@ -2260,9 +2269,7 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
( ret = mpi_check_small_factors( &Y ) ) == 0 && ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 && ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 ) ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
{ goto cleanup;
break;
}
if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
goto cleanup; goto cleanup;
@ -2276,6 +2283,7 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) );
} }
} }
}
cleanup: cleanup:

View file

@ -688,6 +688,18 @@ Test mbedtls_mpi_gen_prime (OK, minimum size)
depends_on:MBEDTLS_GENPRIME depends_on:MBEDTLS_GENPRIME
mbedtls_mpi_gen_prime:3:0:0 mbedtls_mpi_gen_prime:3:0:0
Test mbedtls_mpi_gen_prime (corner case limb size -1 bits)
depends_on:MBEDTLS_GENPRIME
mbedtls_mpi_gen_prime:63:0:0
Test mbedtls_mpi_gen_prime (corner case limb size)
depends_on:MBEDTLS_GENPRIME
mbedtls_mpi_gen_prime:64:0:0
Test mbedtls_mpi_gen_prime (corner case limb size +1 bits)
depends_on:MBEDTLS_GENPRIME
mbedtls_mpi_gen_prime:65:0:0
Test mbedtls_mpi_gen_prime (Larger) Test mbedtls_mpi_gen_prime (Larger)
depends_on:MBEDTLS_GENPRIME depends_on:MBEDTLS_GENPRIME
mbedtls_mpi_gen_prime:128:0:0 mbedtls_mpi_gen_prime:128:0:0