mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2026-11-09 14:50:17 +08:00
ecp: 2nd pass over mbedtls_ecp_mod_p448_raw()
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
This commit is contained in:
parent
a4ec1e3e10
commit
a540f097d8
@ -5537,12 +5537,15 @@ int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs)
|
||||
/* Size of p448 in terms of mbedtls_mpi_uint */
|
||||
#define P448_WIDTH (448 / 8 / sizeof(mbedtls_mpi_uint))
|
||||
|
||||
/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
|
||||
#define DIV_ROUND_UP(X, Y) (((X) + (Y) -1) / (Y))
|
||||
/* Number of bytes for a 224-bit value */
|
||||
#define P224_SIZE (224 / 8)
|
||||
|
||||
/* Number of limbs fully used to store a 224-bit value */
|
||||
#define P224_WIDTH_MIN (P224_SIZE / sizeof(mbedtls_mpi_uint))
|
||||
/* Number or limbs partially used to store a 224-bit value.
|
||||
* With 32-bit limbs we have MAX == MIN, but with 64-bit limbs MAX == MIN + 1 */
|
||||
#define DIV_ROUND_UP(X, Y) (((X) + (Y) -1) / (Y))
|
||||
#define P224_WIDTH_MAX DIV_ROUND_UP(P224_SIZE, sizeof(mbedtls_mpi_uint))
|
||||
#define P224_UNUSED_BITS ((P224_WIDTH_MAX * sizeof(mbedtls_mpi_uint) * 8) - 224)
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction module p448
|
||||
@ -5589,6 +5592,23 @@ static void ecp_shift_l_224(mbedtls_mpi_uint *X)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* In-place truncated to 224-bits: X %= 2^224
|
||||
* X must be P448_WIDTH + 1 limbs */
|
||||
static void ecp_trunc_224(mbedtls_mpi_uint *X)
|
||||
{
|
||||
#if defined(MBEDTLS_HAVE_INT64) && defined(MBEDTLS_IS_BIG_ENDIAN)
|
||||
/* Since 224 is only a multiple of 32 but not of 64, the 224-bit
|
||||
* limit falls in the middle of a limb. Clear the top 32 bits of that limb,
|
||||
* (that is, keep only its low 32 bits). Higher limbs can be fully cleared.
|
||||
*/
|
||||
X[P224_WIDTH_MIN] &= (mbedtls_mpi_uint) 0xffffffff;
|
||||
memset(X + P224_WIDTH_MAX, 0, ((P448_WIDTH + 1 - P224_WIDTH_MAX) * ciL));
|
||||
#else
|
||||
/* Shortcut for 32-bit and little-endian 64-bit. */
|
||||
memset((char *) X + P224_SIZE, 0, P224_SIZE + ciL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Raw fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
|
||||
*
|
||||
@ -5617,49 +5637,41 @@ int mbedtls_ecp_mod_p448_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
/* Both M and Q require an extra limb to catch carries. */
|
||||
mbedtls_mpi_uint M[P448_WIDTH + 1];
|
||||
mbedtls_mpi_uint Q[P448_WIDTH + 1];
|
||||
const size_t M_limbs = P448_WIDTH + 1;
|
||||
const size_t Q_limbs = P448_WIDTH + 1;
|
||||
|
||||
/* M = A1 */
|
||||
memset(M, 0, (M_limbs * ciL));
|
||||
/* Do not copy into the overflow limb, as this would read past the end of
|
||||
* X. */
|
||||
memcpy(M, X + P448_WIDTH, ((M_limbs - 1) * ciL));
|
||||
memcpy(M, X + P448_WIDTH, P448_WIDTH * ciL);
|
||||
M[P448_WIDTH] = 0;
|
||||
|
||||
/* X = A0 */
|
||||
memset(X + P448_WIDTH, 0, ((M_limbs - 1) * ciL));
|
||||
memset(X + P448_WIDTH, 0, P448_WIDTH * ciL);
|
||||
|
||||
/* X = X + M = A0 + A1 */
|
||||
/* Carry here fits in oversize X. Oversize M means it will get
|
||||
* added in, not returned as carry. */
|
||||
(void) mbedtls_mpi_core_add(X, X, M, M_limbs);
|
||||
/* The result is at most 449 bits, so it fits in P448_WIDTH + 1 limbs.
|
||||
* and we know the final carry returned by the function will be 0. */
|
||||
(void) mbedtls_mpi_core_add(X, X, M, P448_WIDTH + 1);
|
||||
|
||||
/* Q = B1 = M >> 224 */
|
||||
ecp_copy_shift_r_224(Q, M);
|
||||
|
||||
/* X = X + Q = (A0 + A1) + B1
|
||||
* Oversize Q catches potential carry here when X is already max 448 bits.
|
||||
*/
|
||||
(void) mbedtls_mpi_core_add(X, X, Q, Q_limbs);
|
||||
/* X = X + Q = (A0 + A1) + B1 */
|
||||
/* Inputs are at most 449 bits and 224 bits, so the result fits. */
|
||||
(void) mbedtls_mpi_core_add(X, X, Q, P448_WIDTH + 1);
|
||||
|
||||
/* M = B0 */
|
||||
#ifdef MBEDTLS_HAVE_INT64
|
||||
M[P224_WIDTH_MIN] &= ((mbedtls_mpi_uint)-1) >> (P224_UNUSED_BITS);
|
||||
#endif
|
||||
memset(M + P224_WIDTH_MAX, 0, ((M_limbs - P224_WIDTH_MAX) * ciL));
|
||||
ecp_trunc_224(M);
|
||||
|
||||
/* M = M + Q = B0 + B1 */
|
||||
(void) mbedtls_mpi_core_add(M, M, Q, Q_limbs);
|
||||
(void) mbedtls_mpi_core_add(M, M, Q, P448_WIDTH + 1);
|
||||
|
||||
/* M = (B0 + B1) * 2^224 */
|
||||
/* Shifted carry bit from the addition fits in oversize M. */
|
||||
ecp_shift_l_224(M);
|
||||
|
||||
/* X = X + M = (A0 + A1 + B1) + (B0 + B1) * 2^224 */
|
||||
(void) mbedtls_mpi_core_add(X, X, M, M_limbs);
|
||||
(void) mbedtls_mpi_core_add(X, X, M, P448_WIDTH + 1);
|
||||
|
||||
/* Clear M once before the loop */
|
||||
memset(M, 0, (M_limbs * ciL));
|
||||
memset(M, 0, ((P448_WIDTH + 1) * ciL));
|
||||
|
||||
/* Now X < 2^448 + 2^448 + 2^224 + (2^224 + 2^224) * 2^224,
|
||||
* so X is at most 451 bits. So, in subsequent rounds,
|
||||
@ -5676,17 +5688,17 @@ int mbedtls_ecp_mod_p448_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
*/
|
||||
for (size_t round = 0; round < 2; ++round) {
|
||||
/* M = A1 + A1 * 2^224
|
||||
* Since A1 has only one non-zero limb, we can directly write
|
||||
* A1 << 224 to the right place, shifted up if needed.
|
||||
* Since A1 is only a few bits, we can directly write A1 << 224 to the
|
||||
* right place (which might not be on a limb boundary).
|
||||
* (Note: other limbs of M were cleared before the loop.) */
|
||||
M[0] = X[P448_WIDTH];
|
||||
M[P224_WIDTH_MIN] = X[P448_WIDTH] << (224 & (biL - 1));
|
||||
M[224 / biL] = X[P448_WIDTH] << (224 % biL);
|
||||
|
||||
/* X = A0 (only 1 limb to clear) */
|
||||
X[P448_WIDTH] = 0;
|
||||
|
||||
/* X = A0 + (A1 + B0 * 2^224) */
|
||||
(void) mbedtls_mpi_core_add(X, X, M, M_limbs);
|
||||
/* X = A0 + (A1 + A1 * 2^224) */
|
||||
(void) mbedtls_mpi_core_add(X, X, M, P448_WIDTH + 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user