mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2025-03-24 22:25:11 +00:00
Merged Prime generation improvements
This commit is contained in:
commit
e4c71f0e11
|
@ -58,7 +58,7 @@ typedef UINT64 uint64_t;
|
||||||
#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */
|
#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */
|
||||||
#define POLARSSL_ERR_MPI_MALLOC_FAILED -0x0010 /**< Memory allocation failed. */
|
#define POLARSSL_ERR_MPI_MALLOC_FAILED -0x0010 /**< Memory allocation failed. */
|
||||||
|
|
||||||
#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
|
#define MPI_CHK(f) do { if( ( ret = f ) != 0 ) goto cleanup; } while( 0 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maximum size MPIs are allowed to grow to in number of limbs.
|
* Maximum size MPIs are allowed to grow to in number of limbs.
|
||||||
|
|
126
library/bignum.c
126
library/bignum.c
|
@ -1797,40 +1797,27 @@ static const int small_prime[] =
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Miller-Rabin primality test (HAC 4.24)
|
* Small divisors test (X must be positive)
|
||||||
|
*
|
||||||
|
* Return values:
|
||||||
|
* 0: no small factor (possible prime, more tests needed)
|
||||||
|
* 1: certain prime
|
||||||
|
* POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
|
||||||
|
* other negative: error
|
||||||
*/
|
*/
|
||||||
int mpi_is_prime( mpi *X,
|
static int mpi_check_small_factors( const mpi *X )
|
||||||
int (*f_rng)(void *, unsigned char *, size_t),
|
|
||||||
void *p_rng )
|
|
||||||
{
|
{
|
||||||
int ret, xs;
|
int ret = 0;
|
||||||
size_t i, j, n, s;
|
size_t i;
|
||||||
mpi W, R, T, A, RR;
|
t_uint r;
|
||||||
|
|
||||||
if( mpi_cmp_int( X, 0 ) == 0 ||
|
|
||||||
mpi_cmp_int( X, 1 ) == 0 )
|
|
||||||
return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
|
|
||||||
|
|
||||||
if( mpi_cmp_int( X, 2 ) == 0 )
|
|
||||||
return( 0 );
|
|
||||||
|
|
||||||
mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
|
|
||||||
mpi_init( &RR );
|
|
||||||
|
|
||||||
xs = X->s; X->s = 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* test trivial factors first
|
|
||||||
*/
|
|
||||||
if( ( X->p[0] & 1 ) == 0 )
|
if( ( X->p[0] & 1 ) == 0 )
|
||||||
return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
|
return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
|
||||||
|
|
||||||
for( i = 0; small_prime[i] > 0; i++ )
|
for( i = 0; small_prime[i] > 0; i++ )
|
||||||
{
|
{
|
||||||
t_uint r;
|
|
||||||
|
|
||||||
if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
|
if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
|
||||||
return( 0 );
|
return( 1 );
|
||||||
|
|
||||||
MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
|
MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
|
||||||
|
|
||||||
|
@ -1838,6 +1825,24 @@ int mpi_is_prime( mpi *X,
|
||||||
return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
|
return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Miller-Rabin pseudo-primality test (HAC 4.24)
|
||||||
|
*/
|
||||||
|
static int mpi_miller_rabin( const mpi *X,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t i, j, n, s;
|
||||||
|
mpi W, R, T, A, RR;
|
||||||
|
|
||||||
|
mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
|
||||||
|
mpi_init( &RR );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* W = |X| - 1
|
* W = |X| - 1
|
||||||
* R = W >> lsb( W )
|
* R = W >> lsb( W )
|
||||||
|
@ -1905,15 +1910,40 @@ int mpi_is_prime( mpi *X,
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
||||||
X->s = xs;
|
|
||||||
|
|
||||||
mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
|
mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
|
||||||
mpi_free( &RR );
|
mpi_free( &RR );
|
||||||
|
|
||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pseudo-primality test: small factors, then Miller-Rabin
|
||||||
|
*/
|
||||||
|
int mpi_is_prime( mpi *X,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
const mpi XX = { 1, X->n, X->p }; /* Abs(X) */
|
||||||
|
|
||||||
|
if( mpi_cmp_int( &XX, 0 ) == 0 ||
|
||||||
|
mpi_cmp_int( &XX, 1 ) == 0 )
|
||||||
|
return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
|
||||||
|
|
||||||
|
if( mpi_cmp_int( &XX, 2 ) == 0 )
|
||||||
|
return( 0 );
|
||||||
|
|
||||||
|
if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
|
||||||
|
{
|
||||||
|
if( ret == 1 )
|
||||||
|
return( 0 );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prime number generation
|
* Prime number generation
|
||||||
*/
|
*/
|
||||||
|
@ -1923,6 +1953,7 @@ int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
size_t k, n;
|
size_t k, n;
|
||||||
|
t_uint r;
|
||||||
mpi Y;
|
mpi Y;
|
||||||
|
|
||||||
if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
|
if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
|
||||||
|
@ -1952,26 +1983,45 @@ int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MPI_CHK( mpi_sub_int( &Y, X, 1 ) );
|
/*
|
||||||
|
* An necessary condition for Y and X = 2Y + 1 to be prime
|
||||||
|
* is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
|
||||||
|
* Make sure it is satisfied, while keeping X = 3 mod 4
|
||||||
|
*/
|
||||||
|
MPI_CHK( mpi_mod_int( &r, X, 3 ) );
|
||||||
|
if( r == 0 )
|
||||||
|
MPI_CHK( mpi_add_int( X, X, 8 ) );
|
||||||
|
else if( r == 1 )
|
||||||
|
MPI_CHK( mpi_add_int( X, X, 4 ) );
|
||||||
|
|
||||||
|
/* Set Y = (X-1) / 2, which is X / 2 because X is odd */
|
||||||
|
MPI_CHK( mpi_copy( &Y, X ) );
|
||||||
MPI_CHK( mpi_shift_r( &Y, 1 ) );
|
MPI_CHK( mpi_shift_r( &Y, 1 ) );
|
||||||
|
|
||||||
while( 1 )
|
while( 1 )
|
||||||
{
|
{
|
||||||
if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )
|
/*
|
||||||
|
* First, check small factors for X and Y
|
||||||
|
* before doing Miller-Rabin on any of them
|
||||||
|
*/
|
||||||
|
if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
|
||||||
|
( ret = mpi_check_small_factors( &Y ) ) == 0 &&
|
||||||
|
( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
|
||||||
|
( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
|
||||||
{
|
{
|
||||||
if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
|
if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
MPI_CHK( mpi_add_int( &Y, X, 1 ) );
|
/*
|
||||||
MPI_CHK( mpi_add_int( X, X, 2 ) );
|
* Next candidates. We want to preserve Y = (X-1) / 2 and
|
||||||
MPI_CHK( mpi_shift_r( &Y, 1 ) );
|
* Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
|
||||||
|
* so up Y by 6 and X by 12.
|
||||||
|
*/
|
||||||
|
MPI_CHK( mpi_add_int( X, X, 12 ) );
|
||||||
|
MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,8 @@ int main( int argc, char *argv[] )
|
||||||
printf( " predefined DHM parameters from dhm.h instead!\n\n" );
|
printf( " predefined DHM parameters from dhm.h instead!\n\n" );
|
||||||
printf( "============================================================\n\n" );
|
printf( "============================================================\n\n" );
|
||||||
|
|
||||||
|
printf( " ! Generating large primes may take minutes!\n" );
|
||||||
|
|
||||||
printf( "\n . Seeding the random number generator..." );
|
printf( "\n . Seeding the random number generator..." );
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
|
|
||||||
|
|
|
@ -504,11 +504,19 @@ Base test mpi_is_prime #8
|
||||||
depends_on:POLARSSL_GENPRIME
|
depends_on:POLARSSL_GENPRIME
|
||||||
mpi_is_prime:10:"47":0
|
mpi_is_prime:10:"47":0
|
||||||
|
|
||||||
Test mpi_is_prime #1
|
Test mpi_is_prime #1a
|
||||||
|
depends_on:POLARSSL_GENPRIME
|
||||||
|
mpi_is_prime:10:"83726728883146151979668243326097049289208482987685965276439157162337476477581":POLARSSL_ERR_MPI_NOT_ACCEPTABLE
|
||||||
|
|
||||||
|
Test mpi_is_prime #1b
|
||||||
|
depends_on:POLARSSL_GENPRIME
|
||||||
|
mpi_is_prime:10:"81248637410584921454869308488899267096530643632730258201256092582281263244641":POLARSSL_ERR_MPI_NOT_ACCEPTABLE
|
||||||
|
|
||||||
|
Test mpi_is_prime #2a
|
||||||
depends_on:POLARSSL_GENPRIME
|
depends_on:POLARSSL_GENPRIME
|
||||||
mpi_is_prime:10:"827131507221654563937832686696200995595835694437983658840870036586124168186967796809117749047430768825822857042432722828096779098498192459819306321073968735177531164565305635281198148032612029767584644305912099":0
|
mpi_is_prime:10:"827131507221654563937832686696200995595835694437983658840870036586124168186967796809117749047430768825822857042432722828096779098498192459819306321073968735177531164565305635281198148032612029767584644305912099":0
|
||||||
|
|
||||||
Test mpi_is_prime #2
|
Test mpi_is_prime #2b
|
||||||
depends_on:POLARSSL_GENPRIME
|
depends_on:POLARSSL_GENPRIME
|
||||||
mpi_is_prime:10:"827131507221654563937832686696200995595835694437983658840870036586124168186967796809117749047430768825822857042432722828096779098498192459819306321073968735177531164565305635281198148032612029767584644305912001":POLARSSL_ERR_MPI_NOT_ACCEPTABLE
|
mpi_is_prime:10:"827131507221654563937832686696200995595835694437983658840870036586124168186967796809117749047430768825822857042432722828096779098498192459819306321073968735177531164565305635281198148032612029767584644305912001":POLARSSL_ERR_MPI_NOT_ACCEPTABLE
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue