From 378fb4b70ac26945f770c2a148d8aaf6f4ea1575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 22 Nov 2013 18:39:18 +0100 Subject: [PATCH] Split mpi_is_prime() and make its first arg const --- include/polarssl/bignum.h | 2 +- library/bignum.c | 86 +++++++++++++++++++++----------- tests/suites/test_suite_mpi.data | 12 ++++- 3 files changed, 69 insertions(+), 31 deletions(-) diff --git a/include/polarssl/bignum.h b/include/polarssl/bignum.h index b63a24242..4e6cc8a95 100644 --- a/include/polarssl/bignum.h +++ b/include/polarssl/bignum.h @@ -653,7 +653,7 @@ int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N ); * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime */ -int mpi_is_prime( mpi *X, +int mpi_is_prime( const mpi *X, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); diff --git a/library/bignum.c b/library/bignum.c index c81ee5bf9..1fea9b6d0 100644 --- a/library/bignum.c +++ b/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, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) +static int mpi_check_small_factors( const mpi *X ) { - int ret, xs; - size_t i, j, n, s; - mpi W, R, T, A, RR; + int ret = 0; + size_t i; + 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 ) return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); for( i = 0; small_prime[i] > 0; i++ ) { - t_uint r; - if( mpi_cmp_int( X, small_prime[i] ) <= 0 ) - return( 0 ); + return( 1 ); 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 ); } +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 * R = W >> lsb( W ) @@ -1905,15 +1910,40 @@ int mpi_is_prime( mpi *X, } cleanup: - - X->s = xs; - mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A ); mpi_free( &RR ); return( ret ); } +/* + * Pseudo-primality test: small factors, then Miller-Rabin + */ +int mpi_is_prime( const 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 */ diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data index 924f364d9..859a38e22 100644 --- a/tests/suites/test_suite_mpi.data +++ b/tests/suites/test_suite_mpi.data @@ -504,11 +504,19 @@ Base test mpi_is_prime #8 depends_on:POLARSSL_GENPRIME 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 mpi_is_prime:10:"827131507221654563937832686696200995595835694437983658840870036586124168186967796809117749047430768825822857042432722828096779098498192459819306321073968735177531164565305635281198148032612029767584644305912099":0 -Test mpi_is_prime #2 +Test mpi_is_prime #2b depends_on:POLARSSL_GENPRIME mpi_is_prime:10:"827131507221654563937832686696200995595835694437983658840870036586124168186967796809117749047430768825822857042432722828096779098498192459819306321073968735177531164565305635281198148032612029767584644305912001":POLARSSL_ERR_MPI_NOT_ACCEPTABLE