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

P-256 scalar mul and modular inverse from s2n-bignum #1794

Draft
wants to merge 4 commits 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
4 changes: 4 additions & 0 deletions crypto/fipsmodule/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ if((((ARCH STREQUAL "x86_64") AND NOT MY_ASSEMBLER_IS_TOO_OLD_FOR_512AVX) OR
set(
S2N_BIGNUM_ASM_SOURCES

p256/bignum_montinv_p256.S
p256/p256_montjscalarmul_alt.S
p256/p256_montjscalarmul.S

p384/bignum_add_p384.S
p384/bignum_sub_p384.S
p384/bignum_neg_p384.S
Expand Down
73 changes: 60 additions & 13 deletions crypto/fipsmodule/ec/p256-nistz.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
#include "internal.h"
#include "p256-nistz.h"

#if defined(EC_P256_USE_S2N_BIGNUM)
# include "../../../third_party/s2n-bignum/include/s2n-bignum_aws-lc.h"
#endif

#if !defined(OPENSSL_NO_ASM) && \
(defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \
!defined(OPENSSL_SMALL)
Expand All @@ -47,19 +51,6 @@ static const BN_ULONG ONE[P256_LIMBS] = {
// Precomputed tables for the default generator
#include "p256-nistz-table.h"

// Recode window to a signed digit, see |ec_GFp_nistp_recode_scalar_bits| in
// util.c for details
static crypto_word_t booth_recode_w5(crypto_word_t in) {
crypto_word_t s, d;

s = ~((in >> 5) - 1);
d = (1 << 6) - in - 1;
d = (d & s) | (in & ~s);
d = (d >> 1) + (d & 1);

return (d << 1) + (s & 1);
}

static crypto_word_t booth_recode_w7(crypto_word_t in) {
crypto_word_t s, d;

Expand Down Expand Up @@ -119,6 +110,16 @@ static BN_ULONG is_not_zero(BN_ULONG in) {
// ecp_nistz256_mod_inverse_sqr_mont sets |r| to (|in| * 2^-256)^-2 * 2^256 mod
// p. That is, |r| is the modular inverse square of |in| for input and output in
// the Montgomery domain.

#if defined(EC_P256_USE_S2N_BIGNUM)
static void ecp_nistz256_mod_inverse_sqr_mont(BN_ULONG r[P256_LIMBS],
const BN_ULONG in[P256_LIMBS]) {
BN_ULONG z2[P256_LIMBS];
ecp_nistz256_sqr_mont(z2,in);
bignum_montinv_p256(r,z2);
}

#else
static void ecp_nistz256_mod_inverse_sqr_mont(BN_ULONG r[P256_LIMBS],
const BN_ULONG in[P256_LIMBS]) {
// This implements the addition chain described in
Expand Down Expand Up @@ -185,7 +186,50 @@ static void ecp_nistz256_mod_inverse_sqr_mont(BN_ULONG r[P256_LIMBS],
ecp_nistz256_sqr_mont(r, ret); // 2^256 - 2^224 + 2^192 + 2^96 - 2^2
}

#endif


// r = p * p_scalar

#if defined(EC_P256_USE_S2N_BIGNUM)

static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
const EC_JACOBIAN *p,
const EC_SCALAR *p_scalar) {
uint64_t s2n_point[12], s2n_result[12];

assert(p != NULL);
assert(p_scalar != NULL);
assert(group->field.N.width == P256_LIMBS);

OPENSSL_memcpy(s2n_point,p->X.words,32);
OPENSSL_memcpy(s2n_point+4,p->Y.words,32);
OPENSSL_memcpy(s2n_point+8,p->Z.words,32);

p256_montjscalarmul_selector(s2n_result,(uint64_t*)p_scalar,s2n_point);

OPENSSL_memcpy(r->X,s2n_result,32);
OPENSSL_memcpy(r->Y,s2n_result+4,32);
OPENSSL_memcpy(r->Z,s2n_result+8,32);
}

#else

// Recode window to a signed digit, see |ec_GFp_nistp_recode_scalar_bits| in
// util.c for details
static crypto_word_t booth_recode_w5(crypto_word_t in) {
crypto_word_t s, d;

s = ~((in >> 5) - 1);
d = (1 << 6) - in - 1;
d = (d & s) | (in & ~s);
d = (d >> 1) + (d & 1);

return (d << 1) + (s & 1);
}

// r = p * p_scalar

static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
const EC_JACOBIAN *p,
const EC_SCALAR *p_scalar) {
Expand Down Expand Up @@ -279,6 +323,9 @@ static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
ecp_nistz256_point_add(r, r, aligned_h);
}

#endif


static crypto_word_t calc_first_wvalue(size_t *index, const uint8_t p_str[33]) {
static const size_t kWindowSize = 7;
static const crypto_word_t kMask = (1 << (7 /* kWindowSize */ + 1)) - 1;
Expand Down
7 changes: 7 additions & 0 deletions crypto/fipsmodule/ec/p256-nistz.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@
extern "C" {
#endif

#if !defined(OPENSSL_NO_ASM) && \
(defined(OPENSSL_LINUX) || defined(OPENSSL_APPLE)) && \
((defined(OPENSSL_X86_64) && \
!defined(MY_ASSEMBLER_IS_TOO_OLD_FOR_512AVX)) || \
defined(OPENSSL_AARCH64))
#define EC_P256_USE_S2N_BIGNUM
#endif

#if !defined(OPENSSL_NO_ASM) && \
(defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \
Expand Down
Loading
Loading