diff --git a/crypto/fipsmodule/ec/ec_nistp.c b/crypto/fipsmodule/ec/ec_nistp.c index 092a9bd8363..3c042a73a04 100644 --- a/crypto/fipsmodule/ec/ec_nistp.c +++ b/crypto/fipsmodule/ec/ec_nistp.c @@ -300,3 +300,48 @@ void scalar_rwnaf(int16_t *out, size_t window_size, } out[num_windows - 1] = window; } + +// The window size for scalar multiplication is hard coded for now. +#define SCALAR_MUL_WINDOW_SIZE (5) +#define SCALAR_MUL_TABLE_NUM_POINTS (1 << (SCALAR_MUL_WINDOW_SIZE - 1)) + +// Generate table of multiples of the input point P = (x_in, y_in, z_in): +// table <-- [2i + 1]P for i in [0, 15]. +void generate_table(const ec_nistp_meth *ctx, + ec_nistp_felem_limb *table, + ec_nistp_felem_limb *x_in, + ec_nistp_felem_limb *y_in, + ec_nistp_felem_limb *z_in) +{ + const size_t felem_num_limbs = ctx->felem_num_limbs; + const size_t felem_num_bytes = felem_num_limbs * sizeof(ec_nistp_felem_limb); + + // table[0] <-- P. + OPENSSL_memcpy(&table[felem_num_limbs * 0], x_in, felem_num_bytes); + OPENSSL_memcpy(&table[felem_num_limbs * 1], y_in, felem_num_bytes); + OPENSSL_memcpy(&table[felem_num_limbs * 2], z_in, felem_num_bytes); + + // Compute 2P. + ec_nistp_felem x_in_dbl, y_in_dbl, z_in_dbl; + ctx->point_dbl(x_in_dbl, y_in_dbl, z_in_dbl, + &table[0 * felem_num_limbs], + &table[1 * felem_num_limbs], + &table[2 * felem_num_limbs]); + + // Compute the rest of the table. + for (size_t i = 1; i < SCALAR_MUL_TABLE_NUM_POINTS; i++) { + // Just getting pointers to i-th and (i-1)-th point in the table. + ec_nistp_felem_limb *point_i = &table[i * 3 * felem_num_limbs]; + ec_nistp_felem_limb *point_im1 = &table[(i - 1) * 3 * felem_num_limbs]; + + // table[i] <-- table[i - 1] + 2P + ctx->point_add(&point_i[0 * felem_num_limbs], + &point_i[1 * felem_num_limbs], + &point_i[2 * felem_num_limbs], + &point_im1[0 * felem_num_limbs], + &point_im1[1 * felem_num_limbs], + &point_im1[2 * felem_num_limbs], + 0, x_in_dbl, y_in_dbl, z_in_dbl); + } +} + diff --git a/crypto/fipsmodule/ec/ec_nistp.h b/crypto/fipsmodule/ec/ec_nistp.h index da4476265a8..524241a5d3f 100644 --- a/crypto/fipsmodule/ec/ec_nistp.h +++ b/crypto/fipsmodule/ec/ec_nistp.h @@ -96,7 +96,15 @@ void ec_nistp_point_add(const ec_nistp_meth *ctx, const ec_nistp_felem_limb *y2, const ec_nistp_felem_limb *z2); +// These two functions are temporarily defined here. +// They will be moved to ec_nistp.c as static function +// once all the scalar multiplications are implemented. void scalar_rwnaf(int16_t *out, size_t window_size, const EC_SCALAR *scalar, size_t scalar_bit_size); +void generate_table(const ec_nistp_meth *ctx, + ec_nistp_felem_limb *table, + ec_nistp_felem_limb *x_in, + ec_nistp_felem_limb *y_in, + ec_nistp_felem_limb *z_in); #endif // EC_NISTP_H diff --git a/crypto/fipsmodule/ec/p384.c b/crypto/fipsmodule/ec/p384.c index 36cfef41f0f..3ae3cfecaeb 100644 --- a/crypto/fipsmodule/ec/p384.c +++ b/crypto/fipsmodule/ec/p384.c @@ -559,22 +559,11 @@ static void ec_GFp_nistp384_point_mul(const EC_GROUP *group, EC_JACOBIAN *r, p384_felem p_pre_comp[P384_MUL_TABLE_SIZE][3]; // Set the first point in the table to P. - p384_from_generic(p_pre_comp[0][0], &p->X); - p384_from_generic(p_pre_comp[0][1], &p->Y); - p384_from_generic(p_pre_comp[0][2], &p->Z); + p384_from_generic(tmp[0], &p->X); + p384_from_generic(tmp[1], &p->Y); + p384_from_generic(tmp[2], &p->Z); - // Compute tmp = [2]P. - p384_point_double(tmp[0], tmp[1], tmp[2], - p_pre_comp[0][0], p_pre_comp[0][1], p_pre_comp[0][2]); - - // Generate the remaining 15 multiples of P. - for (size_t i = 1; i < P384_MUL_TABLE_SIZE; i++) { - p384_point_add(p_pre_comp[i][0], p_pre_comp[i][1], p_pre_comp[i][2], - tmp[0], tmp[1], tmp[2], 0 /* both Jacobian */, - p_pre_comp[i - 1][0], - p_pre_comp[i - 1][1], - p_pre_comp[i - 1][2]); - } + generate_table(p384_methods(), (ec_nistp_felem_limb*)p_pre_comp, tmp[0], tmp[1], tmp[2]); // Recode the scalar. int16_t rnaf[P384_MUL_NWINDOWS] = {0}; diff --git a/crypto/fipsmodule/ec/p521.c b/crypto/fipsmodule/ec/p521.c index c4e6fa22a2a..527542eae22 100644 --- a/crypto/fipsmodule/ec/p521.c +++ b/crypto/fipsmodule/ec/p521.c @@ -496,22 +496,11 @@ static void ec_GFp_nistp521_point_mul(const EC_GROUP *group, EC_JACOBIAN *r, p521_felem p_pre_comp[P521_MUL_TABLE_SIZE][3]; // Set the first point in the table to P. - p521_from_generic(p_pre_comp[0][0], &p->X); - p521_from_generic(p_pre_comp[0][1], &p->Y); - p521_from_generic(p_pre_comp[0][2], &p->Z); + p521_from_generic(tmp[0], &p->X); + p521_from_generic(tmp[1], &p->Y); + p521_from_generic(tmp[2], &p->Z); - // Compute tmp = [2]P. - p521_point_double(tmp[0], tmp[1], tmp[2], - p_pre_comp[0][0], p_pre_comp[0][1], p_pre_comp[0][2]); - - // Generate the remaining 15 multiples of P. - for (size_t i = 1; i < P521_MUL_TABLE_SIZE; i++) { - p521_point_add(p_pre_comp[i][0], p_pre_comp[i][1], p_pre_comp[i][2], - tmp[0], tmp[1], tmp[2], 0 /* both Jacobian */, - p_pre_comp[i - 1][0], - p_pre_comp[i - 1][1], - p_pre_comp[i - 1][2]); - } + generate_table(p521_methods(), (ec_nistp_felem_limb*)p_pre_comp, tmp[0], tmp[1], tmp[2]); // Recode the scalar. int16_t rnaf[P521_MUL_NWINDOWS] = {0};