Added slot for fast modp, with mod_p521

This commit is contained in:
Manuel Pégourié-Gonnard 2012-11-10 00:27:12 +01:00 committed by Paul Bakker
parent 84d1aea1ac
commit 62aad14139
2 changed files with 87 additions and 3 deletions

View File

@ -54,6 +54,8 @@ ecp_point;
*
* The curves we consider are defined by y^2 = x^3 - 3x + b mod p,
* and a generator for a large subgroup is fixed.
*
* modp may be NULL; pbits will not be used in this case.
*/
typedef struct
{
@ -61,6 +63,8 @@ typedef struct
mpi B; /*!< constant term in the equation */
ecp_point G; /*!< generator of the subgroup used */
mpi N; /*!< the order of G */
int (*modp)(mpi *); /*!< function for fast reduction mod P */
unsigned pbits; /*!< number of bits in P */
}
ecp_group;
@ -244,7 +248,7 @@ int ecp_use_known_dp( ecp_group *grp, size_t index );
* \param Q Right-hand point
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int ecp_add( const ecp_group *grp, ecp_point *R,
const ecp_point *P, const ecp_point *Q );
@ -258,7 +262,7 @@ int ecp_add( const ecp_group *grp, ecp_point *R,
* \param P Point to multiply
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int ecp_mul( const ecp_group *grp, ecp_point *R,
const mpi *m, const ecp_point *P );

View File

@ -28,6 +28,7 @@
*
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg
* GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
* FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
*/
#include "polarssl/config.h"
@ -61,6 +62,9 @@ void ecp_group_init( ecp_group *grp )
mpi_init( &grp->B );
ecp_point_init( &grp->G );
mpi_init( &grp->N );
grp->modp = NULL;
grp->pbits = 0;
}
/*
@ -154,6 +158,80 @@ cleanup:
return( ret );
}
/*
* Wrapper around fast quasi-modp functions, with fallback to mpi_mod_mpi
*
* The quasi-modp functions expect an mpi N such that 0 <= N < 2^(2*pbits)
* and change it in-place so that it can easily be brought in the 0..P-1
* range by a few additions or substractions.
*/
static int ecp_modp( mpi *N, const ecp_group *grp )
{
int ret = 0;
if( grp->modp == NULL )
return( mpi_mod_mpi( N, N, &grp->P ) );
if( mpi_cmp_int( N, 0 ) < 0 || mpi_msb( N ) > 2 * grp->pbits )
return( POLARSSL_ERR_ECP_GENERIC );
MPI_CHK( grp->modp( N ) );
while( mpi_cmp_int( N, 0 ) < 0 )
MPI_CHK( mpi_add_mpi( N, N, &grp->P ) );
while( mpi_cmp_mpi( N, &grp->P ) >= 0 )
MPI_CHK( mpi_sub_mpi( N, N, &grp->P ) );
cleanup:
return( ret );
}
/*
* Size of p521 in terms of t_uint
*/
#define P521_SIZE_INT ( 521 / (sizeof( t_uint ) << 3) + 1 )
/*
* Bits to keep in the most significant t_uint
*/
#if defined(POLARSS_HAVE_INT8)
#define P521_MASK 0x01
#else
#define P521_MASK 0x01FF
#endif
/*
* Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
*
* It is required that 0 <= N < 2^(2*521) on entry.
* On exit, it is only guaranteed that 0 <= N < 2^(521+1).
*/
static int ecp_mod_p521( mpi *N )
{
int ret = 0;
t_uint Mp[P521_SIZE_INT];
mpi M;
if( N->n < P521_SIZE_INT )
return( 0 );
memset( Mp, 0, P521_SIZE_INT * sizeof( t_uint ) );
memcpy( Mp, N->p, P521_SIZE_INT * sizeof( t_uint ) );
Mp[P521_SIZE_INT - 1] &= P521_MASK;
M.s = 1;
M.n = P521_SIZE_INT;
M.p = Mp;
MPI_CHK( mpi_shift_r( N, 521 ) );
MPI_CHK( mpi_add_abs( N, N, &M ) );
cleanup:
return( ret );
}
/*
* Set a group using well-known domain parameters
*/
@ -194,6 +272,8 @@ int ecp_use_known_dp( ecp_group *grp, size_t index )
POLARSSL_ECP_SECP384R1_N )
);
case POLARSSL_ECP_DP_SECP521R1:
grp->modp = ecp_mod_p521;
grp->pbits = 521;
return( ecp_group_read_string( grp, 16,
POLARSSL_ECP_SECP521R1_P,
POLARSSL_ECP_SECP521R1_B,
@ -209,7 +289,7 @@ int ecp_use_known_dp( ecp_group *grp, size_t index )
/*
* Reduce a mpi mod p in-place, general case, to use after mpi_mul_mpi
*/
#define MOD_MUL( N ) MPI_CHK( mpi_mod_mpi( &N, &N, &grp->P ) )
#define MOD_MUL( N ) MPI_CHK( ecp_modp( &N, grp ) )
/*
* Reduce a mpi mod p in-place, to use after mpi_sub_mpi