Reduce number of local MPIs in ECP mixed point addition

`ecp_add_mixed()` and `ecp_double_jac()` are the core subroutines
for elliptic curve arithmetic, and as such crucial for the performance
of ECP primitives like ECDHE and ECDSA.

This commit provides a very slight simplification and performance and
memory usage improvement to `ecp_add_mixed()` by removing the use of
three temporary MPIs used for coordinate calculations.

Where those variables were used, the code now writes directly to the
coordinate MPIs of the target elliptic curve point.

This is a valid change even if there is aliasing between input and
output, since at the time any of the coordinate MPIs in question is
written, the corresponding coordinates of both inputs are no longer
read.

(The analogous change in `ecp_double_jac()` can not be made since
this property does not hold for `ecp_double_jac()`.)

Signed-off-by: Hanno Becker <hanno.becker@arm.com>
This commit is contained in:
Hanno Becker 2022-01-01 06:01:45 +00:00
parent acc74b8413
commit 5c8ea307b8

View file

@ -1464,7 +1464,10 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
#else
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi T1, T2, T3, T4, X, Y, Z;
mbedtls_mpi T1, T2, T3, T4;
mbedtls_mpi * const X = &R->X;
mbedtls_mpi * const Y = &R->Y;
mbedtls_mpi * const Z = &R->Z;
/*
* Trivial cases: P == 0 or Q == 0 (case 1)
@ -1482,7 +1485,6 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &T3 ); mbedtls_mpi_init( &T4 );
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T1, &P->Z, &P->Z ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T2, &T1, &P->Z ) );
@ -1506,28 +1508,23 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
}
}
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &Z, &P->Z, &T1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, Z, &P->Z, &T1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3, &T1, &T1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T4, &T3, &T1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3, &T3, &P->X ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &T3 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &T1, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &X, &T2, &T2 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &X, &X, &T1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &X, &X, &T4 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T3, &T3, &X ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, X, &T2, &T2 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, X, X, &T1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, X, X, &T4 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T3, &T3, X ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3, &T3, &T2 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T4, &T4, &P->Y ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &Y, &T3, &T4 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &X ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &Y ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &Z ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, Y, &T3, &T4 ) );
cleanup:
mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); mbedtls_mpi_free( &T3 ); mbedtls_mpi_free( &T4 );
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
return( ret );
#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_ADD_MIXED_ALT) */