mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2026-09-20 09:07:23 +00:00
Merge pull request #1621 from mpg/resricted-ecp-modp-polish-3.6
[3.6] Improve ECC optimized modp
This commit is contained in:
@@ -218,17 +218,6 @@ mbedtls_ecp_point;
|
||||
* non-zero limbs than P, so that it may be efficiently brought into the range
|
||||
* [0, P) by a single constant-time conditional subtraction.
|
||||
* It must return 0 on success and non-zero on failure.
|
||||
*
|
||||
* \note Alternative implementations of the ECP module must obey the
|
||||
* following constraints.
|
||||
* * Group IDs must be distinct: if two group structures have
|
||||
* the same ID, then they must be identical.
|
||||
* * The fields \c id, \c P, \c A, \c B, \c G, \c N,
|
||||
* \c pbits and \c nbits must have the same type and semantics
|
||||
* as in the built-in implementation.
|
||||
* They must be available for reading, but direct modification
|
||||
* of these fields does not need to be supported.
|
||||
* They do not need to be at the same offset in the structure.
|
||||
*/
|
||||
typedef struct mbedtls_ecp_group {
|
||||
mbedtls_ecp_group_id id; /*!< An internal group identifier. */
|
||||
|
||||
+319
-245
@@ -14,8 +14,6 @@
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "constant_time_internal.h"
|
||||
|
||||
#include "bn_mul.h"
|
||||
@@ -49,7 +47,7 @@
|
||||
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
|
||||
/* For these curves, we build the group parameters dynamically. */
|
||||
#define ECP_LOAD_GROUP
|
||||
static mbedtls_mpi_uint mpi_one[] = { 1 };
|
||||
static const mbedtls_mpi_uint mpi_one[] = { 1 };
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -4511,9 +4509,7 @@ static inline void ecp_mpi_load(mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_
|
||||
*/
|
||||
static inline void ecp_mpi_set1(mbedtls_mpi *X)
|
||||
{
|
||||
X->s = 1;
|
||||
X->n = 1;
|
||||
X->p = mpi_one;
|
||||
ecp_mpi_load(X, mpi_one, sizeof(mbedtls_mpi_uint));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4845,15 +4841,49 @@ int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FAST_QUASI_REDUCTION
|
||||
*
|
||||
* Fast quasi-reduction exploits the structure of the prime P to bring a number
|
||||
* from the range [0, P^2) (the result of a multiplication) into a range such
|
||||
* that a single constant-time conditional subtract is enough to get the result
|
||||
* in the range [0, P) (see ecp_modp() in ecp.c).
|
||||
*
|
||||
* There is one function per prime, with a common contract:
|
||||
* (a) the output is in [0, 2P) (so we need at most 1 subtraction);
|
||||
* (b) it has no more limbs than P (required by new bignum functions).
|
||||
*
|
||||
* Note that for primes whose bit length is a multiple of biL (32 or 64),
|
||||
* (b) implies (a); for other primes (p255, p521), (a) implies (b).
|
||||
*
|
||||
* The general strategy is that P is written as P = 2^n - R,
|
||||
* where n is the bit length of P and R a constant (see below).
|
||||
* Then modulo P we have 2^n = R.
|
||||
* So, we write X = X1 * 2^n + X0, and modulo P we have X = X0 + X1 * R.
|
||||
* This can be used repeatedly to bring X to the desired range.
|
||||
*
|
||||
* This is only efficient if R was well chosen. There are two cases:
|
||||
* 1. R is a small constant:
|
||||
* - for secp521r1 it's actually 1: P = 2^521 - 1
|
||||
* - for secp256k1 it's a 33-bit number
|
||||
* - for curve25519 it's 19: P = 2^255 - 19 (hence the name)
|
||||
* 2. R is a sum of +/-1 * powers of 2^32:
|
||||
* - for secp256r1, P = 2^256 - 2^224 + 2^192 + 2^96 - 1
|
||||
* - for secp384r1, P = 2^384 - 2^128 - 2^96 + 2^32 - 1
|
||||
* - for curve448, P = 2^448 - 2^224 - 1
|
||||
*
|
||||
* The details vary for each prime, see the comments in each function.
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_ECP_NIST_OPTIM)
|
||||
/*
|
||||
* Fast reduction modulo the primes used by the NIST curves.
|
||||
* NIST_QUASI_REDUCTION
|
||||
*
|
||||
* These functions are critical for speed, but not needed for correct
|
||||
* operations. So, we make the choice to heavily rely on the internals of our
|
||||
* bignum library, which creates a tight coupling between these functions and
|
||||
* our MPI implementation. However, the coupling between the ECP module and
|
||||
* MPI remains loose, since these functions can be deactivated at will.
|
||||
* Compared to the way things are presented in FIPS 186-3 D.2,
|
||||
* we proceed in columns, from right (least significant chunk) to left,
|
||||
* adding chunks to N in place, and keeping a carry for the next chunk.
|
||||
* This avoids moving things around in memory, and uselessly adding zeros,
|
||||
* compared to the more straightforward, line-oriented approach.
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
|
||||
@@ -4900,7 +4930,7 @@ static inline void carry64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry)
|
||||
#define ADD_LAST add64(p, last_carry, &c)
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
|
||||
* Fast quasi-reduction modulo p192
|
||||
*/
|
||||
static int ecp_mod_p192(mbedtls_mpi *N)
|
||||
{
|
||||
@@ -4913,6 +4943,12 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Raw fast quasi-reduction modulo p192
|
||||
*
|
||||
* See ecp_invasive.h and FAST_QUASI_REDUCTION above,
|
||||
* plus NIST_QUASI_REDUCTION above and FIPS 186-3 D.2.1.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn)
|
||||
{
|
||||
@@ -4929,24 +4965,21 @@ int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn)
|
||||
ADD(3); ADD(5); NEXT; // A0 += A3 + A5
|
||||
ADD(3); ADD(4); ADD(5); NEXT; // A1 += A3 + A4 + A5
|
||||
ADD(4); ADD(5); // A2 += A4 + A5
|
||||
/* Similarly to mbedtls_ecp_mod_p256_raw(), we have 0 <= c <= 3. */
|
||||
|
||||
RESET;
|
||||
|
||||
/* Use the reduction for the carry as well:
|
||||
* 2^192 * last_carry = 2^64 * last_carry + last_carry mod P192
|
||||
* It can generate a carry. */
|
||||
ADD_LAST; NEXT; // A0 += last_carry
|
||||
ADD_LAST; NEXT; // A1 += last_carry
|
||||
// A2 += carry
|
||||
|
||||
RESET;
|
||||
|
||||
/* Use the reduction for the carry as well:
|
||||
* 2^192 * last_carry = 2^64 * last_carry + last_carry mod P192
|
||||
/* The reduced value is 2^192 * c + X0, with X0 the low 3 chunks of X.
|
||||
* Set R = 2^64 + 1, and update with X_new = X0 + c * R.
|
||||
*
|
||||
* The rest of the reasoning is similar to mbedtls_ecp_mod_p256_raw(),
|
||||
* and we see that two rounds are enough to bring the result in range.
|
||||
*/
|
||||
ADD_LAST; NEXT; // A0 += last_carry
|
||||
ADD_LAST; NEXT; // A1 += last_carry
|
||||
// A2 += carry
|
||||
for (size_t round = 0; round < 2; ++round) {
|
||||
RESET;
|
||||
|
||||
ADD_LAST; NEXT; // A0 += last_carry
|
||||
ADD_LAST; NEXT; // A1 += last_carry
|
||||
// A2 += carry
|
||||
}
|
||||
|
||||
LAST;
|
||||
|
||||
@@ -4965,13 +4998,6 @@ int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn)
|
||||
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
|
||||
defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
|
||||
defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
|
||||
|
||||
/*
|
||||
* The reader is advised to first understand ecp_mod_p192() since the same
|
||||
* general structure is used here, but with additional complications:
|
||||
* (1) chunks of 32 bits, and (2) subtractions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For these primes, we need to handle data in chunks of 32 bits.
|
||||
* This makes it more complicated if we use 64 bits limbs in MPI,
|
||||
@@ -5069,7 +5095,7 @@ static inline int8_t extract_carry(int64_t cur)
|
||||
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
|
||||
* Fast quasi-reduction modulo p224
|
||||
*/
|
||||
static int ecp_mod_p224(mbedtls_mpi *N)
|
||||
{
|
||||
@@ -5081,6 +5107,12 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Raw fast quasi-reduction modulo p224
|
||||
*
|
||||
* See ecp_invasive.h and FAST_QUASI_REDUCTION above,
|
||||
* plus NIST_QUASI_REDUCTION above and FIPS 186-3 D.2.2.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p224_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
{
|
||||
@@ -5122,7 +5154,7 @@ int mbedtls_ecp_mod_p224_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
|
||||
* Fast quasi-reduction modulo p256
|
||||
*/
|
||||
static int ecp_mod_p256(mbedtls_mpi *N)
|
||||
{
|
||||
@@ -5134,6 +5166,12 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Raw fast quasi-reduction modulo p256
|
||||
*
|
||||
* See ecp_invasive.h and FAST_QUASI_REDUCTION above,
|
||||
* plus NIST_QUASI_REDUCTION above and FIPS 186-3 D.2.3.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
{
|
||||
@@ -5166,32 +5204,52 @@ int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
|
||||
ADD(15); ADD(15); ADD(15); ADD(8);
|
||||
SUB(10); SUB(11); SUB(12); SUB(13); // A7
|
||||
/* The carry is easily seen to be in the range -5 <= c <= +5,
|
||||
* because on the top chunk we do 4 explicit add (resp. sub), plus one
|
||||
* implicit (adding the carry from the previous limbs), and each can
|
||||
* increment (resp. decrement) the carry.
|
||||
* Tighter estimates can probably be obtained, but we don't need them. */
|
||||
|
||||
RESET;
|
||||
/* From now on, the reduced value is 2^256 * c + X0,
|
||||
* where X0 is A0 + 2^32 * A1 + ... + 2^224 * A7 (the low 8 chunks of X).
|
||||
* Note that c may be negative, but X0 is always in [0, 2^256).
|
||||
*
|
||||
* Set R = 2^224 - 2^192 - 2^96 + 1 and use 2^256 = R (mod p256),
|
||||
* so the update formula is X = X0 + c * R.
|
||||
*
|
||||
* Let's call X_ori the value before the loop,
|
||||
* X_1st the value after the first iteration,
|
||||
* X_2nd the value after the second iteration.
|
||||
*
|
||||
* First round:
|
||||
* We have 0 <= X_ori < 2^256 and -8 < -5 <= last_c <= 5 < 8,
|
||||
* so -2^227 < last_c * R < 2^227
|
||||
* and -2^227 < X_1st < 2^256 + 2^227.
|
||||
* Again X_1st is represented as 2^256 * c + X0, but now c is -1, 0 or 1.
|
||||
*
|
||||
* Second round:
|
||||
* - If c is 0, then X_2nd = X0 + 0 * R = X0 which is in range.
|
||||
* - If c is 1, then X_2nd = X0 + 1 * R is clearly non-negative.
|
||||
* Also, since X_1st < 2^256 + 2^227, we have X0 < 2^227,
|
||||
* so X_2nd = X0 + 1 * R < 2^227 + 2^224 < 2^256.
|
||||
* - If c is -1 then X_2nd = X0 - 1 * R is clearly < 2^256.
|
||||
* Also, since X_1st > -2^227 and X_1st = - 2^256 + X0,
|
||||
* we have X0 > 2^256 - 2^227
|
||||
* so X_2nd = X0 - 1 * R > 2^256 - 2^227 - 2^224 >= 0.
|
||||
* In all cases, 0 <= X_2nd < 2^256 as desired.
|
||||
*/
|
||||
for (size_t round = 0; round < 2; ++round) {
|
||||
RESET;
|
||||
|
||||
/* Use 2^224 * (2^32 - 1) + 2^192 + 2^96 - 1
|
||||
* to modulo reduce the final carry. */
|
||||
ADD_LAST; NEXT; // A0
|
||||
; NEXT; // A1
|
||||
; NEXT; // A2
|
||||
SUB_LAST; NEXT; // A3
|
||||
; NEXT; // A4
|
||||
; NEXT; // A5
|
||||
SUB_LAST; NEXT; // A6
|
||||
ADD_LAST; // A7
|
||||
|
||||
RESET;
|
||||
|
||||
/* Use 2^224 * (2^32 - 1) + 2^192 + 2^96 - 1
|
||||
* to modulo reduce the carry generated by the previous reduction. */
|
||||
ADD_LAST; NEXT; // A0
|
||||
; NEXT; // A1
|
||||
; NEXT; // A2
|
||||
SUB_LAST; NEXT; // A3
|
||||
; NEXT; // A4
|
||||
; NEXT; // A5
|
||||
SUB_LAST; NEXT; // A6
|
||||
ADD_LAST; // A7
|
||||
ADD_LAST; NEXT; // A0
|
||||
; NEXT; // A1
|
||||
; NEXT; // A2
|
||||
SUB_LAST; NEXT; // A3
|
||||
; NEXT; // A4
|
||||
; NEXT; // A5
|
||||
SUB_LAST; NEXT; // A6
|
||||
ADD_LAST; // A7
|
||||
}
|
||||
|
||||
LAST;
|
||||
|
||||
@@ -5202,7 +5260,7 @@ int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
|
||||
/*
|
||||
* Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
|
||||
* Fast quasi-reduction modulo p384
|
||||
*/
|
||||
static int ecp_mod_p384(mbedtls_mpi *N)
|
||||
{
|
||||
@@ -5214,6 +5272,12 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Raw fast quasi-reduction modulo p384
|
||||
*
|
||||
* See ecp_invasive.h and FAST_QUASI_REDUCTION above,
|
||||
* plus NIST_QUASI_REDUCTION above and FIPS 186-3 D.2.4.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
{
|
||||
@@ -5258,37 +5322,30 @@ int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
|
||||
ADD(23); ADD(20); ADD(19);
|
||||
SUB(22); // A11
|
||||
/* Similarly to mbedtls_ecp_mod_p256_raw(), we have -2 <= c <= 4. */
|
||||
|
||||
RESET;
|
||||
/* The reduced value is 2^384 * c + X0, with X0 the low 12 chunks of X.
|
||||
* Set R = 2^128 + 2^96 - 2^32 + 1, and update with X_new = X0 + c * R.
|
||||
*
|
||||
* The rest of the reasoning is similar to mbedtls_ecp_mod_p256_raw(),
|
||||
* and we see that two rounds are enough to bring the result in range.
|
||||
*/
|
||||
for (size_t round = 0; round < 2; ++round) {
|
||||
RESET;
|
||||
|
||||
/* Use 2^384 = P + 2^128 + 2^96 - 2^32 + 1 to modulo reduce the final carry */
|
||||
ADD_LAST; NEXT; // A0
|
||||
SUB_LAST; NEXT; // A1
|
||||
; NEXT; // A2
|
||||
ADD_LAST; NEXT; // A3
|
||||
ADD_LAST; NEXT; // A4
|
||||
; NEXT; // A5
|
||||
; NEXT; // A6
|
||||
; NEXT; // A7
|
||||
; NEXT; // A8
|
||||
; NEXT; // A9
|
||||
; NEXT; // A10
|
||||
// A11
|
||||
|
||||
RESET;
|
||||
|
||||
ADD_LAST; NEXT; // A0
|
||||
SUB_LAST; NEXT; // A1
|
||||
; NEXT; // A2
|
||||
ADD_LAST; NEXT; // A3
|
||||
ADD_LAST; NEXT; // A4
|
||||
; NEXT; // A5
|
||||
; NEXT; // A6
|
||||
; NEXT; // A7
|
||||
; NEXT; // A8
|
||||
; NEXT; // A9
|
||||
; NEXT; // A10
|
||||
ADD_LAST; NEXT; // A0
|
||||
SUB_LAST; NEXT; // A1
|
||||
; NEXT; // A2
|
||||
ADD_LAST; NEXT; // A3
|
||||
ADD_LAST; NEXT; // A4
|
||||
; NEXT; // A5
|
||||
; NEXT; // A6
|
||||
; NEXT; // A7
|
||||
; NEXT; // A8
|
||||
; NEXT; // A9
|
||||
; NEXT; // A10
|
||||
// A11
|
||||
}
|
||||
|
||||
LAST;
|
||||
|
||||
@@ -5318,13 +5375,13 @@ int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
|
||||
/* Size of p521 in terms of mbedtls_mpi_uint */
|
||||
#define P521_WIDTH (521 / 8 / sizeof(mbedtls_mpi_uint) + 1)
|
||||
#define P521_WIDTH BITS_TO_LIMBS(521)
|
||||
|
||||
/* Bits to keep in the most significant mbedtls_mpi_uint */
|
||||
#define P521_MASK 0x01FF
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5)
|
||||
* Fast quasi-reduction modulo p521
|
||||
*/
|
||||
static int ecp_mod_p521(mbedtls_mpi *N)
|
||||
{
|
||||
@@ -5336,6 +5393,14 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Raw fast quasi-reduction modulo p521 = 2^521 - 1
|
||||
*
|
||||
* See ecp_invasive.h and FAST_QUASI_REDUCTION above.
|
||||
*
|
||||
* First handle whole limbs above 521 bits,
|
||||
* then handle the carry as well as remaining bits in the top limb.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
{
|
||||
@@ -5346,21 +5411,21 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
}
|
||||
|
||||
/* Step 1: Reduction to P521_WIDTH limbs */
|
||||
/* Helper references for bottom part of X */
|
||||
/* Pointers to bottom/top part of X - note that they don't overlap,
|
||||
* as required for the call to mbedtls_mpi_core_mla() below. */
|
||||
mbedtls_mpi_uint *X0 = X;
|
||||
size_t X0_limbs = P521_WIDTH;
|
||||
/* Helper references for top part of X */
|
||||
mbedtls_mpi_uint *X1 = X + X0_limbs;
|
||||
size_t X1_limbs = X_limbs - X0_limbs;
|
||||
/* Split X as X0 + 2^P521_WIDTH X1 and compute X0 + 2^(biL - 9) X1.
|
||||
* (We are using that 2^P521_WIDTH = 2^(512 + biL) and that
|
||||
/* Split X as X0 + 2^(P521_WIDTH * biL) X1 and compute X0 + 2^(biL - 9) X1.
|
||||
* (We are using that 2^(P521_WIDTH * biL) = 2^(512 + biL) and that
|
||||
* 2^(512 + biL) X1 = 2^(biL - 9) X1 mod P521.)
|
||||
* The high order limb of the result will be held in carry and the rest
|
||||
* in X0 (that is the result will be represented as
|
||||
* 2^P521_WIDTH carry + X0).
|
||||
* 2^(P521_WIDTH * biL) * carry + X0).
|
||||
*
|
||||
* Also, note that the resulting carry is either 0 or 1:
|
||||
* X0 < 2^P521_WIDTH = 2^(512 + biL) and X1 < 2^(P521_WIDTH-biL) = 2^512
|
||||
* X0 < 2^(512 + biL) and X1 < 2^512
|
||||
* therefore
|
||||
* X0 + 2^(biL - 9) X1 < 2^(512 + biL) + 2^(512 + biL - 9)
|
||||
* which in turn is less than 2 * 2^(512 + biL).
|
||||
@@ -5375,7 +5440,7 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
* At this point X is reduced to P521_WIDTH limbs. What remains is to add
|
||||
* the carry (that is 2^P521_WIDTH carry) and to reduce mod P521. */
|
||||
|
||||
/* 2^P521_WIDTH carry = 2^(512 + biL) carry = 2^(biL - 9) carry mod P521.
|
||||
/* 2^(P521_WIDTH * biL) * carry = 2^(512 + biL) carry = 2^(biL - 9) carry mod P521.
|
||||
* Also, recall that carry is either 0 or 1. */
|
||||
mbedtls_mpi_uint addend = carry << (biL - 9);
|
||||
/* Keep the top 9 bits and reduce the rest, using 2^521 = 1 mod P521. */
|
||||
@@ -5406,11 +5471,10 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
|
||||
|
||||
/* Size of p255 in terms of mbedtls_mpi_uint */
|
||||
#define P255_WIDTH (255 / 8 / sizeof(mbedtls_mpi_uint) + 1)
|
||||
#define P255_WIDTH BITS_TO_LIMBS(255)
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo p255 = 2^255 - 19
|
||||
* Write N as A0 + 2^256 A1, return A0 + 38 * A1
|
||||
*/
|
||||
static int ecp_mod_p255(mbedtls_mpi *N)
|
||||
{
|
||||
@@ -5422,6 +5486,14 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Raw fast quasi-reduction modulo p255 = 2^255 - 19
|
||||
*
|
||||
* See ecp_invasive.h and FAST_QUASI_REDUCTION above.
|
||||
*
|
||||
* First write N as A0 + 2^256 A1, compute A0 + 38 * A1.
|
||||
* Then handle the carry and remaining bit.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs)
|
||||
{
|
||||
@@ -5430,22 +5502,18 @@ int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs)
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
mbedtls_mpi_uint *carry = mbedtls_calloc(P255_WIDTH, ciL);
|
||||
if (carry == NULL) {
|
||||
return MBEDTLS_ERR_ECP_ALLOC_FAILED;
|
||||
}
|
||||
mbedtls_mpi_uint carry[P255_WIDTH] = { 0 };
|
||||
|
||||
/* Step 1: Reduction to P255_WIDTH limbs */
|
||||
if (X_Limbs > P255_WIDTH) {
|
||||
/* Helper references for top part of X */
|
||||
mbedtls_mpi_uint * const A1 = X + P255_WIDTH;
|
||||
const size_t A1_limbs = X_Limbs - P255_WIDTH;
|
||||
mbedtls_mpi_uint * const A1 = X + P255_WIDTH;
|
||||
const size_t A1_limbs = X_Limbs - P255_WIDTH;
|
||||
|
||||
/* X = A0 + 38 * A1, capture carry out */
|
||||
*carry = mbedtls_mpi_core_mla(X, P255_WIDTH, A1, A1_limbs, 38);
|
||||
/* Clear top part */
|
||||
memset(A1, 0, sizeof(mbedtls_mpi_uint) * A1_limbs);
|
||||
}
|
||||
/* X = A0 + 38 * A1, capture carry out
|
||||
* Note: X truncated to P255_WIDTH does not overlap with A1
|
||||
* (mbedtls_mpi_core_mla() doesn't support overlap other than aliasing) */
|
||||
*carry = mbedtls_mpi_core_mla(X, P255_WIDTH, A1, A1_limbs, 38);
|
||||
/* Clear top part */
|
||||
memset(A1, 0, sizeof(mbedtls_mpi_uint) * A1_limbs);
|
||||
|
||||
/* Step 2: Reduce to <2p
|
||||
* Split as A0 + 2^255*c, with c a scalar, and compute A0 + 19*c */
|
||||
@@ -5464,7 +5532,6 @@ int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs)
|
||||
* - If X > 2^255 ==> X < 2^256 - 2^255 < 2p */
|
||||
(void) mbedtls_mpi_core_add(X, X, carry, P255_WIDTH);
|
||||
|
||||
mbedtls_free(carry);
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
|
||||
@@ -5472,15 +5539,21 @@ int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_Limbs)
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
|
||||
|
||||
/* Size of p448 in terms of mbedtls_mpi_uint */
|
||||
#define P448_WIDTH (448 / 8 / sizeof(mbedtls_mpi_uint))
|
||||
#define P448_WIDTH BITS_TO_LIMBS(448)
|
||||
|
||||
/* 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)
|
||||
#define P224_WIDTH_MIN (P224_SIZE / sizeof(mbedtls_mpi_uint))
|
||||
#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)
|
||||
|
||||
/* 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))
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction module p448
|
||||
*/
|
||||
static int ecp_mod_p448(mbedtls_mpi *N)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
@@ -5523,12 +5596,36 @@ 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
|
||||
}
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
|
||||
* Write X as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return A0 + A1 + B1 +
|
||||
* (B0 + B1) * 2^224. This is different to the reference implementation of
|
||||
* Raw fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
|
||||
*
|
||||
* See ecp_invasive.h and FAST_QUASI_REDUCTION above.
|
||||
*
|
||||
* Write X as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and
|
||||
* compute A0 + A1 + B1 + (B0 + B1) * 2^224.
|
||||
*
|
||||
* This is different to the reference implementation of
|
||||
* Curve448, which uses its own special 56-bit limbs rather than a generic
|
||||
* bignum library. We could squeeze some extra speed out on 32-bit machines by
|
||||
* bignum library.
|
||||
*
|
||||
* We could squeeze some extra speed out on 32-bit machines by
|
||||
* splitting N up into 32-bit limbs and doing the arithmetic using the limbs
|
||||
* directly as we do for the NIST primes above, but for 64-bit targets it should
|
||||
* use half the number of operations if we do the reduction with 224-bit limbs,
|
||||
@@ -5537,106 +5634,78 @@ static void ecp_shift_l_224(mbedtls_mpi_uint *X)
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p448_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
{
|
||||
size_t round;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (X_limbs != BITS_TO_LIMBS(448) * 2) {
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
/* Both M and Q require an extra limb to catch carries. */
|
||||
size_t M_limbs = BITS_TO_LIMBS(448) + 1;
|
||||
|
||||
const size_t Q_limbs = M_limbs;
|
||||
mbedtls_mpi_uint *M = NULL;
|
||||
mbedtls_mpi_uint *Q = NULL;
|
||||
|
||||
M = mbedtls_calloc(M_limbs, ciL);
|
||||
|
||||
if (M == NULL) {
|
||||
return MBEDTLS_ERR_ECP_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
Q = mbedtls_calloc(Q_limbs, ciL);
|
||||
|
||||
if (Q == NULL) {
|
||||
ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
mbedtls_mpi_uint M[P448_WIDTH + 1];
|
||||
mbedtls_mpi_uint Q[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);
|
||||
|
||||
/* In the second and third rounds A1 and B0 have at most 1 non-zero limb and
|
||||
* B1=0.
|
||||
* Using this we need to calculate:
|
||||
* A0 + A1 + B1 + (B0 + B1) * 2^224 = A0 + A1 + B0 * 2^224. */
|
||||
for (round = 0; round < 2; ++round) {
|
||||
/* Clear M once before the loop */
|
||||
memset(M, 0, ((P448_WIDTH + 1) * ciL));
|
||||
|
||||
/* M = A1 */
|
||||
memset(M, 0, (M_limbs * ciL));
|
||||
memcpy(M, X + P448_WIDTH, ((M_limbs - 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,
|
||||
* A1 has at most 1 non-zero limb, so B0 = A1 and B1 = 0.
|
||||
* So the update formula simplifies as follows:
|
||||
* A0 + A1 + B1 + (B0 + B1) * 2^224 = A0 + A1 + A1 * 2^224.
|
||||
*
|
||||
* Two rounds are enough because:
|
||||
* 1st round: A0 < 2^448, A1 <= 2^3 - 1
|
||||
* so X < 2^448 + 2^227 (at most 449 bits).
|
||||
* 2nd round: Either A1 is 0 and we're done already,
|
||||
* or A1 is 1 and A0 = X - A1 * 2^448 < 2^227,
|
||||
* so X < 2^227 + 1 + 1 * 2^224 is less than 448 bits.
|
||||
*/
|
||||
for (size_t round = 0; round < 2; ++round) {
|
||||
/* M = A1 + A1 * 2^224
|
||||
* 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[224 / biL] = X[P448_WIDTH] << (224 % biL);
|
||||
|
||||
/* X = A0 */
|
||||
memset(X + P448_WIDTH, 0, ((M_limbs - 1) * ciL));
|
||||
/* X = A0 (only 1 limb to clear) */
|
||||
X[P448_WIDTH] = 0;
|
||||
|
||||
/* M = A1 + B0 * 2^224
|
||||
* We know that only one limb of A1 will be non-zero and that it will be
|
||||
* limb 0. We also know that B0 is the bottom 224 bits of A1 (which is
|
||||
* then shifted up 224 bits), so, given M is currently A1 this turns
|
||||
* into:
|
||||
* M = M + (M << 224)
|
||||
* As the single non-zero limb in B0 will be A1 limb 0 shifted up by 224
|
||||
* bits, we can just move that into the right place, shifted up
|
||||
* accordingly.*/
|
||||
M[P224_WIDTH_MIN] = M[0] << (224 & (biL - 1));
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
mbedtls_free(M);
|
||||
mbedtls_free(Q);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
|
||||
|
||||
@@ -5644,21 +5713,33 @@ cleanup:
|
||||
defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
|
||||
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo P = 2^s - R,
|
||||
* with R about 33 bits, used by the Koblitz curves.
|
||||
*
|
||||
* Write X as A0 + 2^224 A1, return A0 + R * A1.
|
||||
*/
|
||||
#define P_KOBLITZ_R (8 / sizeof(mbedtls_mpi_uint)) // Limbs in R
|
||||
/* Limb size of R for ecp_mod_koblitz() */
|
||||
#define P_KOBLITZ_R BITS_TO_LIMBS(33)
|
||||
|
||||
/* Maximum limb size of P for ecp_mod_koblitz() */
|
||||
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
|
||||
#define P_KOBLITZ_MAX_P BITS_TO_LIMBS(256)
|
||||
#elif defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
|
||||
#define P_KOBLITZ_MAX_P BITS_TO_LIMBS(224)
|
||||
#else
|
||||
#define P_KOBLITZ_MAX_P BITS_TO_LIMBS(192)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo P = 2^n - R,
|
||||
* with R a curve-dependent 33-bit value.
|
||||
*
|
||||
* This function is the core of mbedtls_ecp_mod_p192k1_raw(),
|
||||
* mbedtls_ecp_mod_p224k1_raw(), and mbedtls_ecp_mod_p256k1_raw().
|
||||
*
|
||||
* See ecp_invasive.h and FAST_QUASI_REDUCTION above.
|
||||
*
|
||||
* Write X as A0 + 2^n A1, update as A0 + R * A1.
|
||||
*/
|
||||
static inline int ecp_mod_koblitz(mbedtls_mpi_uint *X,
|
||||
size_t X_limbs,
|
||||
mbedtls_mpi_uint *R,
|
||||
size_t bits)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* Determine if A1 is aligned to limb bitsize. If not then the used limbs
|
||||
* of P, A0 and A1 must be set accordingly and there is a middle limb
|
||||
* which is shared by A0 and A1 and need to handle accordingly.
|
||||
@@ -5667,29 +5748,18 @@ static inline int ecp_mod_koblitz(mbedtls_mpi_uint *X,
|
||||
size_t adjust = (shift + biL - 1) / biL;
|
||||
size_t P_limbs = bits / biL + adjust;
|
||||
|
||||
mbedtls_mpi_uint *A1 = mbedtls_calloc(P_limbs, ciL);
|
||||
if (A1 == NULL) {
|
||||
return MBEDTLS_ERR_ECP_ALLOC_FAILED;
|
||||
}
|
||||
mbedtls_mpi_uint A1[P_KOBLITZ_MAX_P] = { 0 };
|
||||
|
||||
/* Create a buffer to store the value of `R * A1` */
|
||||
size_t R_limbs = P_KOBLITZ_R;
|
||||
size_t M_limbs = P_limbs + R_limbs;
|
||||
mbedtls_mpi_uint *M = mbedtls_calloc(M_limbs, ciL);
|
||||
if (M == NULL) {
|
||||
ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
mbedtls_mpi_uint M[P_KOBLITZ_MAX_P + P_KOBLITZ_R] = { 0 };
|
||||
|
||||
mbedtls_mpi_uint mask = 0;
|
||||
if (adjust != 0) {
|
||||
mask = ((mbedtls_mpi_uint) 1 << shift) - 1;
|
||||
}
|
||||
|
||||
/* Two passes are needed to reduce the value of `A0 + R * A1` and then
|
||||
* we need an additional one to reduce the possible overflow during
|
||||
* the addition.
|
||||
*/
|
||||
/* See end of the loop for why 3 passes */
|
||||
for (size_t pass = 0; pass < 3; pass++) {
|
||||
/* Copy A1 */
|
||||
memcpy(A1, X + P_limbs - adjust, P_limbs * ciL);
|
||||
@@ -5704,30 +5774,28 @@ static inline int ecp_mod_koblitz(mbedtls_mpi_uint *X,
|
||||
X[P_limbs - 1] &= mask;
|
||||
}
|
||||
|
||||
/* X = A0
|
||||
* Zeroize the A1 part of X to keep only the A0 part.
|
||||
*/
|
||||
for (size_t i = P_limbs; i < X_limbs; i++) {
|
||||
X[i] = 0;
|
||||
}
|
||||
/* X = A0: Zeroize the A1 part of X to keep only the A0 part. */
|
||||
memset(X + P_limbs, 0, P_limbs * ciL);
|
||||
|
||||
/* X = A0 + R * A1 */
|
||||
mbedtls_mpi_core_mul(M, A1, P_limbs, R, R_limbs);
|
||||
(void) mbedtls_mpi_core_add(X, X, M, P_limbs + R_limbs);
|
||||
|
||||
/* Carry can not be generated since R is a 33-bit value and stored in
|
||||
* 64 bits. The result value of the multiplication is at most
|
||||
* P length + 33 bits in length and the result value of the addition
|
||||
* is at most P length + 34 bits in length. So the result of the
|
||||
* addition always fits in P length + 64 bits.
|
||||
/* The above cannot generate a carry since P_limbs + R_limbs is enough.
|
||||
*
|
||||
* More precisely, if n is P's bit length:
|
||||
* 1st pass: A0 is n bits, R * A1 is 33 + n, so X is n + 34 bits.
|
||||
* This fits in P_limbs + R_limbs which is n + 64 bits.
|
||||
* 2nd pass: A0 is n bits, R * A1 is 33 + 34, so X is n + 1 bits.
|
||||
* Actually, X < 2^n + 2^67
|
||||
* 3rd pass: Either A1 is 0, then X = A0 is at most n bits.
|
||||
* Or A1 is 1, but then A0 = X - A1 * 2^n < 2^67,
|
||||
* so X = A0 + R * A1 < 2^67 + 2^33 is less than n bits,
|
||||
* since n >= 68.
|
||||
* So, after the 3rd pass, X is at most n bits.
|
||||
*/
|
||||
}
|
||||
|
||||
cleanup:
|
||||
mbedtls_free(M);
|
||||
mbedtls_free(A1);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
|
||||
@@ -5737,8 +5805,7 @@ cleanup:
|
||||
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo p192k1 = 2^192 - R,
|
||||
* with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9
|
||||
* Fast quasi-reduction modulo p192k1 = 2^192 - 0x01000011C9
|
||||
*/
|
||||
static int ecp_mod_p192k1(mbedtls_mpi *N)
|
||||
{
|
||||
@@ -5751,6 +5818,9 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Raw fast quasi-reduction modulo p192k1 = 2^192 - 0x01000011C9
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
{
|
||||
@@ -5763,7 +5833,7 @@ int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return ecp_mod_koblitz(X, X_limbs, Rp, 192);
|
||||
return ecp_mod_koblitz(X, Rp, 192);
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
|
||||
@@ -5771,8 +5841,7 @@ int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo p224k1 = 2^224 - R,
|
||||
* with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
|
||||
* Fast quasi-reduction modulo p224k1 = 2^224 - 0x0100001A93
|
||||
*/
|
||||
static int ecp_mod_p224k1(mbedtls_mpi *N)
|
||||
{
|
||||
@@ -5785,6 +5854,9 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Raw fast quasi-reduction modulo p224k1 = 2^224 - 0x0100001A93
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
{
|
||||
@@ -5797,7 +5869,7 @@ int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return ecp_mod_koblitz(X, X_limbs, Rp, 224);
|
||||
return ecp_mod_koblitz(X, Rp, 224);
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
|
||||
@@ -5805,8 +5877,7 @@ int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
|
||||
|
||||
/*
|
||||
* Fast quasi-reduction modulo p256k1 = 2^256 - R,
|
||||
* with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
|
||||
* Fast quasi-reduction modulo p256k1 = 2^256 - 0x01000003D1
|
||||
*/
|
||||
static int ecp_mod_p256k1(mbedtls_mpi *N)
|
||||
{
|
||||
@@ -5819,6 +5890,9 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Raw fast quasi-reduction modulo p256k1 = 2^256 - 0x01000003D1
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
{
|
||||
@@ -5831,7 +5905,7 @@ int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs)
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return ecp_mod_koblitz(X, X_limbs, Rp, 256);
|
||||
return ecp_mod_koblitz(X, Rp, 256);
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
|
||||
|
||||
+18
-25
@@ -61,7 +61,7 @@ int mbedtls_ecp_gen_privkey_mx(size_t high_bit,
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
|
||||
/** Fast quasi-reduction modulo p192
|
||||
*
|
||||
* This operation expects a 384 bit MPI and the result of the reduction
|
||||
* is a 192 bit MPI.
|
||||
@@ -80,7 +80,7 @@ int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn);
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
|
||||
/** Fast quasi-reduction modulo p224
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 448-bit MPI
|
||||
@@ -102,7 +102,7 @@ int mbedtls_ecp_mod_p224_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
|
||||
/** Fast quasi-reduction modulo p256
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 512-bit MPI
|
||||
@@ -124,7 +124,7 @@ int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5)
|
||||
/** Fast quasi-reduction modulo p521 = 2^521 - 1
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have twice as many limbs as the modulus
|
||||
@@ -146,7 +146,7 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
|
||||
/** Fast quasi-reduction modulo p384
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 768-bit MPI
|
||||
@@ -168,8 +168,7 @@ int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p192k1 = 2^192 - R,
|
||||
* with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9
|
||||
/** Fast quasi-reduction modulo p192k1 = 2^192 - 0x01000011C9
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 384-bit MPI
|
||||
@@ -183,7 +182,6 @@ int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
|
||||
* twice as many limbs as the modulus.
|
||||
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
@@ -192,8 +190,7 @@ int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p224k1 = 2^224 - R,
|
||||
* with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
|
||||
/** Fast quasi-reduction modulo p224k1 = 2^224 - 0x0100001A93
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 448-bit MPI
|
||||
@@ -207,7 +204,6 @@ int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
|
||||
* twice as many limbs as the modulus.
|
||||
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
@@ -216,8 +212,7 @@ int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p256k1 = 2^256 - R,
|
||||
* with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
|
||||
/** Fast quasi-reduction modulo p256k1 = 2^256 - 0x01000003D1
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 512-bit MPI
|
||||
@@ -231,7 +226,6 @@ int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
|
||||
* twice as many limbs as the modulus.
|
||||
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
@@ -247,12 +241,13 @@ int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
* (double the bitlength of the modulus).
|
||||
* Upon return holds the reduced value which is
|
||||
* in range `0 <= X < 2 * N` (where N is the modulus).
|
||||
* The bitlength of the reduced value is at most 256
|
||||
* (that is, 1 more than that of the modulus).
|
||||
* \param[in] X_limbs The length of \p X in limbs.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
|
||||
* twice as many limbs as the modulus.
|
||||
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
@@ -262,29 +257,26 @@ int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
|
||||
|
||||
/** Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
|
||||
* Write X as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return A0 + A1 + B1 +
|
||||
* (B0 + B1) * 2^224.
|
||||
*
|
||||
* \param[in,out] X The address of the MPI to be converted.
|
||||
* Must have exact limb size that stores a 896-bit MPI
|
||||
* (double the bitlength of the modulus). Upon return
|
||||
* holds the reduced value which is in range `0 <= X <
|
||||
* N` (where N is the modulus). The bitlength of the
|
||||
* reduced value is the same as that of the modulus
|
||||
* (448 bits).
|
||||
* (double the bitlength of the modulus).
|
||||
* Upon return holds the reduced value which is in
|
||||
* range `0 <= X < 2 * N` (where N is the modulus).
|
||||
* The bitlength of the reduced value is the same as
|
||||
* that of the modulus (448 bits).
|
||||
* \param[in] X_limbs The length of \p X in limbs.
|
||||
*
|
||||
* \return \c 0 on Success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
|
||||
* twice as many limbs as the modulus.
|
||||
* \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation
|
||||
* failed.
|
||||
*/
|
||||
MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_mod_p448_raw(mbedtls_mpi_uint *X, size_t X_limbs);
|
||||
|
||||
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_WITH_MPI_UINT)
|
||||
/** Initialise a modulus with hard-coded const curve data.
|
||||
*
|
||||
* \note The caller is responsible for the \p N modulus' memory.
|
||||
@@ -306,7 +298,8 @@ MBEDTLS_STATIC_TESTABLE
|
||||
int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N,
|
||||
const mbedtls_ecp_group_id id,
|
||||
const mbedtls_ecp_modulus_type ctype);
|
||||
#endif /* MBEDTLS_ECP_WITH_MPI_UINT */
|
||||
|
||||
#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_ECP_C */
|
||||
#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_ECP_LIGHT */
|
||||
|
||||
#endif /* MBEDTLS_ECP_INVASIVE_H */
|
||||
|
||||
@@ -1671,7 +1671,12 @@ void ecp_mod_p_generic_raw(int curve_id,
|
||||
mbedtls_mpi_uint c = mbedtls_mpi_core_sub(X, X, N, limbs_N);
|
||||
(void) mbedtls_mpi_core_add_if(X, N, limbs_N, (unsigned) c);
|
||||
#endif
|
||||
/* Checking that the result is equal to the expected value is enough,
|
||||
* but in case of failures, it's useful to know if the incorrect result
|
||||
* had the correct bitlength or not / was in the correct range or not. */
|
||||
TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), curve_bits);
|
||||
/* This only works because we know from above the top limbs of X are 0. */
|
||||
TEST_EQUAL(MBEDTLS_CT_TRUE, mbedtls_mpi_core_lt_ct(X, N, limbs_N));
|
||||
TEST_MEMORY_COMPARE(X, bytes, res, bytes);
|
||||
|
||||
exit:
|
||||
|
||||
Reference in New Issue
Block a user