Change ecp_mul to handle Curve25519 too

This commit is contained in:
Manuel Pégourié-Gonnard 2013-12-04 11:49:20 +01:00
parent 312d2e8ea2
commit a0179b8c4a
3 changed files with 98 additions and 27 deletions

View file

@ -1227,11 +1227,13 @@ cleanup:
} }
/* /*
* Multiplication using the comb method * Multiplication using the comb method,
* for curves in short Weierstrass form
*/ */
int ecp_mul( ecp_group *grp, ecp_point *R, static int ecp_mul_comb( ecp_group *grp, ecp_point *R,
const mpi *m, const ecp_point *P, const mpi *m, const ecp_point *P,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{ {
int ret; int ret;
unsigned char w, m_is_odd, p_eq_g, pre_len, i; unsigned char w, m_is_odd, p_eq_g, pre_len, i;
@ -1240,28 +1242,13 @@ int ecp_mul( ecp_group *grp, ecp_point *R,
ecp_point *T; ecp_point *T;
mpi M, mm; mpi M, mm;
/*
* Sanity checks (before we even initialize anything)
*/
if( mpi_cmp_int( &P->Z, 1 ) != 0 ||
mpi_get_bit( &grp->N, 0 ) != 1 )
{
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
}
if( ( ret = ecp_check_privkey( grp, m ) ) != 0 )
return( ret );
/* We'll need this later, but do it now to possibly avoid checking P */
p_eq_g = ( mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 &&
mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 );
if( ! p_eq_g && ( ret = ecp_check_pubkey( grp, P ) ) != 0 )
return( ret );
mpi_init( &M ); mpi_init( &M );
mpi_init( &mm ); mpi_init( &mm );
/* we need N to be odd to trnaform m in an odd number, check now */
if( mpi_get_bit( &grp->N, 0 ) != 1 )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
/* /*
* Minimize the number of multiplications, that is minimize * Minimize the number of multiplications, that is minimize
* 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w ) * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w )
@ -1273,6 +1260,8 @@ int ecp_mul( ecp_group *grp, ecp_point *R,
* If P == G, pre-compute a bit more, since this may be re-used later. * If P == G, pre-compute a bit more, since this may be re-used later.
* Just adding one ups the cost of the first mul by at most 3%. * Just adding one ups the cost of the first mul by at most 3%.
*/ */
p_eq_g = ( mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 &&
mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 );
if( p_eq_g ) if( p_eq_g )
w++; w++;
@ -1466,11 +1455,13 @@ cleanup:
} }
/* /*
* Multiplication with Montgomery ladder in x/z coordinates * Multiplication with Montgomery ladder in x/z coordinates,
* for curves in Montgomery form
*/ */
int ecp_mul_mxz( ecp_group *grp, ecp_point *R, static int ecp_mul_mxz( ecp_group *grp, ecp_point *R,
const mpi *m, const ecp_point *P, const mpi *m, const ecp_point *P,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{ {
int ret; int ret;
size_t i; size_t i;
@ -1505,6 +1496,30 @@ cleanup:
return( ret ); return( ret );
} }
/*
* Multiplication R = m * P
*/
int ecp_mul( ecp_group *grp, ecp_point *R,
const mpi *m, const ecp_point *P,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
int ret;
/* Common sanity checks */
if( mpi_cmp_int( &P->Z, 1 ) != 0 )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = ecp_check_privkey( grp, m ) ) != 0 ||
( ret = ecp_check_pubkey( grp, P ) ) != 0 )
return( ret );
/* Actual multiplication aglorithm depending of curve type */
if( ecp_is_montgomery( grp ) )
return( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) );
else
return( ecp_mul_comb( grp, R, m, P, f_rng, p_rng ) );
}
/* /*
* Check that a point is valid as a public key * Check that a point is valid as a public key
*/ */

View file

@ -413,5 +413,9 @@ ECP test vectors brainpoolP512r1 rfc 7027
depends_on:POLARSSL_ECP_DP_BP512R1_ENABLED depends_on:POLARSSL_ECP_DP_BP512R1_ENABLED
ecp_test_vect:POLARSSL_ECP_DP_BP512R1:"16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD87BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764CAD57665422":"0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF04436D11640FD09FD":"72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD472A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5E82A6AD147FDE7":"230E18E1BCC88A362FA54E4EA3902009292F7F8033624FD471B5D8ACE49D12CFABBC19963DAB8E2F1EBA00BFFB29E4D72D13F2224562F405CB80503666B25429":"9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871DEDA55A5473199F":"2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194512B71876285FA":"A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F":"7DB71C3DEF63212841C463E881BDCF055523BD368240E6C3143BD8DEF8B3B3223B95E0F53082FF5E412F4222537A43DF1C6D25729DDB51620A832BE6A26680A2" ecp_test_vect:POLARSSL_ECP_DP_BP512R1:"16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD87BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764CAD57665422":"0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF04436D11640FD09FD":"72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD472A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5E82A6AD147FDE7":"230E18E1BCC88A362FA54E4EA3902009292F7F8033624FD471B5D8ACE49D12CFABBC19963DAB8E2F1EBA00BFFB29E4D72D13F2224562F405CB80503666B25429":"9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871DEDA55A5473199F":"2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194512B71876285FA":"A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F":"7DB71C3DEF63212841C463E881BDCF055523BD368240E6C3143BD8DEF8B3B3223B95E0F53082FF5E412F4222537A43DF1C6D25729DDB51620A832BE6A26680A2"
ECP test vectors M255 aka Curve25519
depends_on:POLARSSL_ECP_DP_M255_ENABLED
ecp_test_vec_x:POLARSSL_ECP_DP_M255:"5AC99F33632E5A768DE7E81BF854C27C46E3FBF2ABBACD29EC4AFF517369C660":"057E23EA9F1CBE8A27168F6E696A791DE61DD3AF7ACD4EEACC6E7BA514FDA863":"47DC3D214174820E1154B49BC6CDB2ABD45EE95817055D255AA35831B70D3260":"6EB89DA91989AE37C7EAC7618D9E5C4951DBA1D73C285AE1CD26A855020EEF04":"61450CD98E36016B58776A897A9F0AEF738B99F09468B8D6B8511184D53494AB"
ECP selftest ECP selftest
ecp_selftest: ecp_selftest:

View file

@ -263,6 +263,58 @@ void ecp_test_vect( int id, char *dA_str, char *xA_str, char *yA_str,
} }
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE */
void ecp_test_vec_x( int id, char *dA_hex, char *xA_hex,
char *dB_hex, char *xB_hex, char *xS_hex )
{
ecp_group grp;
ecp_point R;
mpi dA, xA, dB, xB, xS;
rnd_pseudo_info rnd_info;
ecp_group_init( &grp ); ecp_point_init( &R );
mpi_init( &dA ); mpi_init( &xA );
mpi_init( &dB ); mpi_init( &xB );
mpi_init( &xS );
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
TEST_ASSERT( ecp_use_known_dp( &grp, id ) == 0 );
TEST_ASSERT( ecp_check_pubkey( &grp, &grp.G ) == 0 );
TEST_ASSERT( mpi_read_string( &dA, 16, dA_hex ) == 0 );
TEST_ASSERT( mpi_read_string( &dB, 16, dB_hex ) == 0 );
TEST_ASSERT( mpi_read_string( &xA, 16, xA_hex ) == 0 );
TEST_ASSERT( mpi_read_string( &xB, 16, xB_hex ) == 0 );
TEST_ASSERT( mpi_read_string( &xS, 16, xS_hex ) == 0 );
TEST_ASSERT( ecp_mul( &grp, &R, &dA, &grp.G,
&rnd_pseudo_rand, &rnd_info ) == 0 );
TEST_ASSERT( ecp_check_pubkey( &grp, &R ) == 0 );
TEST_ASSERT( mpi_cmp_mpi( &R.X, &xA ) == 0 );
TEST_ASSERT( ecp_mul( &grp, &R, &dB, &R,
&rnd_pseudo_rand, &rnd_info ) == 0 );
TEST_ASSERT( ecp_check_pubkey( &grp, &R ) == 0 );
TEST_ASSERT( mpi_cmp_mpi( &R.X, &xS ) == 0 );
TEST_ASSERT( ecp_mul( &grp, &R, &dB, &grp.G,
&rnd_pseudo_rand, &rnd_info ) == 0 );
TEST_ASSERT( ecp_check_pubkey( &grp, &R ) == 0 );
TEST_ASSERT( mpi_cmp_mpi( &R.X, &xB ) == 0 );
TEST_ASSERT( ecp_mul( &grp, &R, &dA, &R,
&rnd_pseudo_rand, &rnd_info ) == 0 );
TEST_ASSERT( ecp_check_pubkey( &grp, &R ) == 0 );
TEST_ASSERT( mpi_cmp_mpi( &R.X, &xS ) == 0 );
ecp_group_free( &grp ); ecp_point_free( &R );
mpi_free( &dA ); mpi_free( &xA );
mpi_free( &dB ); mpi_free( &xB );
mpi_free( &xS );
}
/* END_CASE */
/* BEGIN_CASE */ /* BEGIN_CASE */
void ecp_fast_mod( int id, char *N_str ) void ecp_fast_mod( int id, char *N_str )
{ {