From 56cc88a796b058be92c255c6540e1f5ac9c5903e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 11 May 2015 18:40:45 +0200 Subject: [PATCH] Rm ecp_add() and add ecp_muladd() --- ChangeLog | 3 ++- include/mbedtls/ecp.h | 61 ++++++++++++++++++++++++------------------- library/ecdsa.c | 10 +++---- library/ecp.c | 44 ++++++++++++++++++------------- 4 files changed, 66 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index 28a3ef24a..b6278a5dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -61,7 +61,8 @@ API Changes Removals * Removed mbedtls_ecp_group_read_string(). Only named groups are supported. - * Removed mbedtls_ecp_sub(). + * Removed mbedtls_ecp_sub() and mbedtls_ecp_add(), use + mbedtls_ecp_muladd(). * Removed individual mdX_hmac and shaX_hmac functions (use generic md_hmac functions from md.h) * Removed the PBKDF2 module (use PKCS5). diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 901c23ed5..224e13579 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -481,27 +481,20 @@ int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **bu int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen, unsigned char *buf, size_t blen ); -/** - * \brief Addition: R = P + Q - * - * \param grp ECP group - * \param R Destination point - * \param P Left-hand point - * \param Q Right-hand point - * - * \return 0 if successful, - * MBEDTLS_ERR_MPI_MALLOC_FAILED if memory allocation failed - * - * \note This function does not support Montgomery curves, such as - * Curve25519. - */ -int mbedtls_ecp_add( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ); - /** * \brief Multiplication by an integer: R = m * P * (Not thread-safe to use same group in multiple threads) * + * \note In order to prevent timing attacks, this function + * executes the exact same sequence of (base field) + * operations for any valid m. It avoids any if-branch or + * array index depending on the value of m. + * + * \note If f_rng is not NULL, it is used to randomize intermediate + * results in order to prevent potential timing attacks + * targeting these results. It is recommended to always + * provide a non-NULL f_rng (the overhead is negligible). + * * \param grp ECP group * \param R Destination point * \param m Integer by which to multiply @@ -513,21 +506,35 @@ int mbedtls_ecp_add( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, * MBEDTLS_ERR_ECP_INVALID_KEY if m is not a valid privkey * or P is not a valid pubkey, * MBEDTLS_ERR_MPI_MALLOC_FAILED if memory allocation failed - * - * \note In order to prevent timing attacks, this function - * executes the exact same sequence of (base field) - * operations for any valid m. It avoids any if-branch or - * array index depending on the value of m. - * - * \note If f_rng is not NULL, it is used to randomize intermediate - * results in order to prevent potential timing attacks - * targeting these results. It is recommended to always - * provide a non-NULL f_rng (the overhead is negligible). */ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); +/** + * \brief Multiplication and addition of two points by integers: + * R = m * P + n * Q + * (Not thread-safe to use same group in multiple threads) + * + * \note In contrast to ecp_mul(), this function does not guarantee + * a constant execution flow and timing. + * + * \param grp ECP group + * \param R Destination point + * \param m Integer by which to multiply P + * \param P Point to multiply by m + * \param n Integer by which to multiply Q + * \param Q Point to be multiplied by n + * + * \return 0 if successful, + * MBEDTLS_ERR_ECP_INVALID_KEY if m or n is not a valid privkey + * or P or Q is not a valid pubkey, + * MBEDTLS_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + const mbedtls_mpi *n, const mbedtls_ecp_point *Q ); + /** * \brief Check that a point is a valid public key on this curve * diff --git a/library/ecdsa.c b/library/ecdsa.c index a7dcddb9a..babc588ac 100644 --- a/library/ecdsa.c +++ b/library/ecdsa.c @@ -203,9 +203,9 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, { int ret; mbedtls_mpi e, s_inv, u1, u2; - mbedtls_ecp_point R, P; + mbedtls_ecp_point R; - mbedtls_ecp_point_init( &R ); mbedtls_ecp_point_init( &P ); + mbedtls_ecp_point_init( &R ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv ); mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 ); /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ @@ -249,9 +249,7 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, * Since we're not using any secret data, no need to pass a RNG to * mbedtls_ecp_mul() for countermesures. */ - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &R, &u1, &grp->G, NULL, NULL ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &P, &u2, Q, NULL, NULL ) ); - MBEDTLS_MPI_CHK( mbedtls_ecp_add( grp, &R, &R, &P ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, &R, &u1, &grp->G, &u2, Q ) ); if( mbedtls_ecp_is_zero( &R ) ) { @@ -275,7 +273,7 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, } cleanup: - mbedtls_ecp_point_free( &R ); mbedtls_ecp_point_free( &P ); + mbedtls_ecp_point_free( &R ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &s_inv ); mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 ); return( ret ); diff --git a/library/ecp.c b/library/ecp.c index f0fcc1f46..52cedd383 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -1048,24 +1048,6 @@ cleanup: return( ret ); } -/* - * Addition: R = P + Q, result's coordinates normalized - */ -int mbedtls_ecp_add( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, - const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ) -{ - int ret; - - if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS ) - return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); - - MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, P, Q ) ); - MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) ); - -cleanup: - return( ret ); -} - /* * Randomize jacobian coordinates: * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l @@ -1684,6 +1666,32 @@ cleanup: } #endif /* ECP_SHORTWEIERSTRASS */ +/* + * Linear combination + */ +int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + const mbedtls_mpi *n, const mbedtls_ecp_point *Q ) +{ + int ret; + mbedtls_ecp_point mP; + + if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS ) + return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); + + mbedtls_ecp_point_init( &mP ); + + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &mP, m, P, NULL, NULL ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, n, Q, NULL, NULL ) ); + MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, &mP, R ) ); + MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) ); + +cleanup: + mbedtls_ecp_point_free( &mP ); + + return( ret ); +} + #if defined(ECP_MONTGOMERY) /*