diff --git a/library/bignum_core.c b/library/bignum_core.c index c6d92fb06..26aff15f1 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -353,6 +353,54 @@ void mbedtls_mpi_core_shift_r(mbedtls_mpi_uint *X, size_t limbs, } } +int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t i, v0, t1; + mbedtls_mpi_uint r0 = 0, r1; + MPI_VALIDATE_RET( X != NULL ); + + v0 = count / (biL ); + t1 = count & (biL - 1); + + i = mbedtls_mpi_bitlen( X ) + count; + + if( X->n * biL < i ) + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, BITS_TO_LIMBS( i ) ) ); + + ret = 0; + + /* + * shift by count / limb_size + */ + if( v0 > 0 ) + { + for( i = X->n; i > v0; i-- ) + X->p[i - 1] = X->p[i - v0 - 1]; + + for( ; i > 0; i-- ) + X->p[i - 1] = 0; + } + + /* + * shift by count % limb_size + */ + if( t1 > 0 ) + { + for( i = v0; i < X->n; i++ ) + { + r1 = X->p[i] >> (biL - t1); + X->p[i] <<= t1; + X->p[i] |= r0; + r0 = r1; + } + } + +cleanup: + + return( ret ); +} + mbedtls_mpi_uint mbedtls_mpi_core_add(mbedtls_mpi_uint *X, const mbedtls_mpi_uint *A, const mbedtls_mpi_uint *B, diff --git a/library/bignum_core.h b/library/bignum_core.h index b3d05a34e..25e7e1a6b 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -293,6 +293,18 @@ int mbedtls_mpi_core_write_be(const mbedtls_mpi_uint *A, void mbedtls_mpi_core_shift_r(mbedtls_mpi_uint *X, size_t limbs, size_t count); +/** + * \brief Perform a left-shift on an MPI: X <<= count + * + * \param X The MPI to shift. This must point to an initialized MPI. + * \param count The number of bits to shift by. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count ); + /** * \brief Add two fixed-size large unsigned integers, returning the carry. *