Perform mbedtls_mpi_mul_int in place if possible

Rewrite mbedtls_mpi_mul_int to call mpi_mul_hlp directly rather than
create a temporary mpi object. This has the benefit of not performing
an allocation when the multiplication is in place (mpi operand aliased
with the result) and the result mpi is large enough.

This saves about 40% of the calloc() calls in test_suite_ecp. There is
no measurable performance difference on my Linux PC.

The cost is a few bytes in bignum.o.

When there is no aliasing, or when there is aliasing but the mpi
object needs to be enlarged, the performance difference is negligible.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
Gilles Peskine 2020-07-23 21:58:50 +02:00
parent a5d8d89cca
commit 8fd95c6757

View file

@ -1658,17 +1658,30 @@ cleanup:
*/ */
int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b ) int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b )
{ {
mbedtls_mpi _B;
mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET( X != NULL ); MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL ); MPI_VALIDATE_RET( A != NULL );
_B.s = 1; /* mpi_mul_hlp can't deal with a leading 0. */
_B.n = 1; size_t n = A->n;
_B.p = p; while( n > 0 && A->p[n - 1] == 0 )
p[0] = b; --n;
return( mbedtls_mpi_mul_mpi( X, A, &_B ) ); /* The general method below doesn't work if n==0 or b==0. By chance
* calculating the result is trivial in those cases. */
if( b == 0 || n == 0 )
{
mbedtls_mpi_lset( X, 0 );
return( 0 );
}
/* Calculate X*b as A + A*(b-1) to take advantage of mpi_mul_hlp */
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n + 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
mpi_mul_hlp( n, A->p, X->p, b - 1 );
cleanup:
return( ret );
} }
/* /*