Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use s2n-bignum P-384 scalar multiplication and Montgomery inverse #1878

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crypto/fipsmodule/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,17 @@ if((((ARCH STREQUAL "x86_64") AND NOT MY_ASSEMBLER_IS_TOO_OLD_FOR_512AVX) OR
p384/bignum_neg_p384.S
p384/bignum_tomont_p384.S
p384/bignum_deamont_p384.S
p384/bignum_montinv_p384.S
p384/bignum_montmul_p384.S
p384/bignum_montmul_p384_alt.S
p384/bignum_montsqr_p384.S
p384/bignum_montsqr_p384_alt.S
p384/bignum_nonzero_6.S
p384/bignum_littleendian_6.S
p384/p384_montjdouble.S
p384/p384_montjdouble_alt.S
p384/p384_montjscalarmul.S
p384/p384_montjscalarmul_alt.S

p521/bignum_add_p521.S
p521/bignum_sub_p521.S
Expand Down
63 changes: 62 additions & 1 deletion crypto/fipsmodule/ec/p384.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,17 @@ static void p384_from_scalar(p384_felem out, const EC_SCALAR *in) {
}

// p384_inv_square calculates |out| = |in|^{-2}
//

#if defined(EC_NISTP_USE_S2N_BIGNUM)
static void p384_inv_square(p384_felem out,const p384_felem in) {

p384_felem z2;
p384_felem_sqr(z2,in);
bignum_montinv_p384(out,z2);
}

#else

// Based on Fermat's Little Theorem:
// a^p = a (mod p)
// a^{p-1} = 1 (mod p)
Expand Down Expand Up @@ -241,6 +251,32 @@ static void p384_inv_square(p384_felem out,
p384_felem_sqr(out, ret); // 2^384 - 2^128 - 2^96 + 2^32 - 2^2 = p - 3
}

#endif

#if defined(EC_NISTP_USE_S2N_BIGNUM)

static void p384_point_double(p384_felem x_out,
p384_felem y_out,
p384_felem z_out,
const p384_felem x_in,
const p384_felem y_in,
const p384_felem z_in) {

uint64_t s2n_point[18], s2n_result[18];

OPENSSL_memcpy(s2n_point,x_in,48);
OPENSSL_memcpy(s2n_point+6,y_in,48);
OPENSSL_memcpy(s2n_point+12,z_in,48);

p384_montjdouble_selector(s2n_result,s2n_point);

OPENSSL_memcpy(x_out,s2n_result,48);
OPENSSL_memcpy(y_out,s2n_result+6,48);
OPENSSL_memcpy(z_out,s2n_result+12,48);
}

#else

static void p384_point_double(p384_felem x_out,
p384_felem y_out,
p384_felem z_out,
Expand All @@ -250,6 +286,8 @@ static void p384_point_double(p384_felem x_out,
ec_nistp_point_double(p384_methods(), x_out, y_out, z_out, x_in, y_in, z_in);
}

#endif

// p384_point_add calculates (x1, y1, z1) + (x2, y2, z2)
//
// The method is taken from:
Expand Down Expand Up @@ -509,6 +547,27 @@ static void p384_select_point_affine(p384_felem out[2],
}

// Multiplication of an arbitrary point by a scalar, r = [scalar]P.

#if defined(EC_NISTP_USE_S2N_BIGNUM)

static void ec_GFp_nistp384_point_mul(const EC_GROUP *group, EC_JACOBIAN *r,
const EC_JACOBIAN *p,
const EC_SCALAR *scalar) {
uint64_t s2n_point[18], s2n_result[18];

OPENSSL_memcpy(s2n_point,p->X.words,48);
OPENSSL_memcpy(s2n_point+6,p->Y.words,48);
OPENSSL_memcpy(s2n_point+12,p->Z.words,48);

p384_montjscalarmul_selector(s2n_result,(uint64_t*)scalar,s2n_point);

OPENSSL_memcpy(r->X.words,s2n_result,48);
OPENSSL_memcpy(r->Y.words,s2n_result+6,48);
OPENSSL_memcpy(r->Z.words,s2n_result+12,48);
}

#else

static void ec_GFp_nistp384_point_mul(const EC_GROUP *group, EC_JACOBIAN *r,
const EC_JACOBIAN *p,
const EC_SCALAR *scalar) {
Expand All @@ -526,6 +585,8 @@ static void ec_GFp_nistp384_point_mul(const EC_GROUP *group, EC_JACOBIAN *r,
p384_to_generic(&r->Z, res[2]);
}

#endif

// Include the precomputed table for the based point scalar multiplication.
#include "p384_table.h"

Expand Down
25 changes: 23 additions & 2 deletions third_party/s2n-bignum/include/s2n-bignum_aws-lc.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static inline void bignum_deamont_p384_selector(uint64_t z[static 6], const uint
else { bignum_deamont_p384(z, x); }
}

// Montgomery multiply, z := (x * y / 2^384) mod p_384
// Montgomery multiply, z := (x * y / 2^384) mod p_384
// Inputs x[6], y[6]; output z[6]
extern void bignum_montmul_p384(uint64_t z[static 6], const uint64_t x[static 6], const uint64_t y[static 6]);
extern void bignum_montmul_p384_alt(uint64_t z[static 6], const uint64_t x[static 6], const uint64_t y[static 6]);
Expand All @@ -87,7 +87,7 @@ extern void bignum_neg_p384(uint64_t z[static 6], const uint64_t x[static 6]);

// Subtract modulo p_384, z := (x - y) mod p_384
// Inputs x[6], y[6]; output z[6]
extern void bignum_sub_p384(uint64_t z[static 6], const uint64_t x[static 6], const uint64_t y[static 6]);
extern void bignum_sub_p384(uint64_t z[static 6], const uint64_t x[static 6], const uint64_t y[static 6]);

// Convert to Montgomery form z := (2^384 * x) mod p_384 */
// Input x[6]; output z[6] */
Expand All @@ -110,6 +110,27 @@ extern void bignum_tolebytes_6(uint8_t z[static 48], const uint64_t x[static 6])
// Input x[6]; output function return
extern uint64_t bignum_nonzero_6(const uint64_t x[static 6]);

// Montgomery inverse modulo p_384 = 2^384 - 2^128 - 2^96 + 2^32 - 1
// Input x[6]; output z[6]
extern void bignum_montinv_p384(uint64_t z[static 6],const uint64_t x[static 6]);

// Montgomery-Jacobian form point doubling for P-384
// Input p1[18]; output p3[18]
extern void p384_montjdouble(uint64_t p3[static 18],const uint64_t p1[static 18]);
extern void p384_montjdouble_alt(uint64_t p3[static 18],const uint64_t p1[static 18]);
static inline void p384_montjdouble_selector(uint64_t p3[static 18], const uint64_t p1[static 18]) {
if (use_s2n_bignum_alt()) { p384_montjdouble_alt(p3, p1); }
else { p384_montjdouble(p3, p1); }
}
// Montgomery-Jacobian form scalar multiplication for P-384
// Input scalar[6], point[18]; output res[18]
extern void p384_montjscalarmul(uint64_t res[static 18],const uint64_t scalar[static 6],const uint64_t point[static 18]);
extern void p384_montjscalarmul_alt(uint64_t res[static 18],const uint64_t scalar[static 6],const uint64_t point[static 18]);
static inline void p384_montjscalarmul_selector(uint64_t res[static 18], const uint64_t scalar[static 6], const uint64_t point[static 18]) {
if (use_s2n_bignum_alt()) { p384_montjscalarmul_alt(res, scalar, point); }
else { p384_montjscalarmul(res, scalar, point); }
}

// Add modulo p_521, z := (x + y) mod p_521, assuming x and y reduced
// Inputs x[9], y[9]; output z[9]
extern void bignum_add_p521(uint64_t z[static 9], const uint64_t x[static 9], const uint64_t y[static 9]);
Expand Down