Skip to content

Commit 250905a

Browse files
author
dkostic
committed
Added generic EC scalar rwnaf encoding for ec_nistp
1 parent 88faaa2 commit 250905a

File tree

4 files changed

+46
-75
lines changed

4 files changed

+46
-75
lines changed

crypto/fipsmodule/ec/ec_nistp.c

+39
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,42 @@ void ec_nistp_point_add(const ec_nistp_meth *ctx,
259259
cmovznz(z3, ctx->felem_num_limbs, z2nz, z1, z_out);
260260
}
261261

262+
static int16_t get_bit(const EC_SCALAR *in, size_t in_bit_size, size_t i) {
263+
if (i >= in_bit_size) {
264+
return 0;
265+
}
266+
#if defined(OPENSSL_64_BIT)
267+
assert(sizeof(BN_ULONG) == 8);
268+
return (in->words[i >> 6] >> (i & 63)) & 1;
269+
#else
270+
assert(sizeof(BN_ULONG) == 4);
271+
return (in->words[i >> 5] >> (i & 31)) & 1;
272+
#endif
273+
}
274+
275+
#define DIV_AND_CEIL(a, b) ((a + b - 1) / b)
276+
277+
// Compute "regular" wNAF representation of a scalar, see
278+
// Joye, Tunstall, "Exponent Recoding and Regular Exponentiation Algorithms",
279+
// AfricaCrypt 2009, Alg 6.
280+
// It forces an odd scalar and outputs digits in
281+
// {\pm 1, \pm 3, \pm 5, \pm 7, \pm 9, ...}
282+
// i.e. signed odd digits with _no zeroes_ -- that makes it "regular".
283+
void scalar_rwnaf(int16_t *out, size_t window_size,
284+
const EC_SCALAR *scalar, size_t scalar_bit_size) {
285+
int16_t window, d;
286+
287+
const BN_ULONG window_mask = (1 << (window_size + 1)) - 1;
288+
const size_t num_windows = DIV_AND_CEIL(scalar_bit_size, window_size);
289+
290+
window = (scalar->words[0] & window_mask) | 1;
291+
for (size_t i = 0; i < num_windows - 1; i++) {
292+
d = (window & window_mask) - (1 << window_size);
293+
out[i] = d;
294+
window = (window - d) >> window_size;
295+
for (size_t j = 1; j <= window_size; j++) {
296+
window += get_bit(scalar, scalar_bit_size, (i + 1) * window_size + j) << j;
297+
}
298+
}
299+
out[num_windows - 1] = window;
300+
}

crypto/fipsmodule/ec/ec_nistp.h

+3
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,8 @@ void ec_nistp_point_add(const ec_nistp_meth *ctx,
9595
const ec_nistp_felem_limb *x2,
9696
const ec_nistp_felem_limb *y2,
9797
const ec_nistp_felem_limb *z2);
98+
99+
void scalar_rwnaf(int16_t *out, size_t window_size,
100+
const EC_SCALAR *scalar, size_t scalar_bit_size);
98101
#endif // EC_NISTP_H
99102

crypto/fipsmodule/ec/p384.c

+2-38
Original file line numberDiff line numberDiff line change
@@ -470,21 +470,6 @@ static int ec_GFp_nistp384_cmp_x_coordinate(const EC_GROUP *group,
470470
//
471471
// For detailed analysis of different window sizes see the bottom of this file.
472472

473-
474-
// p384_get_bit returns the |i|-th bit in |in|
475-
static crypto_word_t p384_get_bit(const EC_SCALAR *in, int i) {
476-
if (i < 0 || i >= 384) {
477-
return 0;
478-
}
479-
#if defined(OPENSSL_64_BIT)
480-
assert(sizeof(BN_ULONG) == 8);
481-
return (in->words[i >> 6] >> (i & 63)) & 1;
482-
#else
483-
assert(sizeof(BN_ULONG) == 4);
484-
return (in->words[i >> 5] >> (i & 31)) & 1;
485-
#endif
486-
}
487-
488473
// Constants for scalar encoding in the scalar multiplication functions.
489474
#define P384_MUL_WSIZE (5) // window size w
490475
// Assert the window size is 5 because the pre-computed table in |p384_table.h|
@@ -506,27 +491,6 @@ OPENSSL_STATIC_ASSERT(P384_MUL_WSIZE == 5,
506491
#define P384_MUL_TABLE_SIZE (P384_MUL_TWO_TO_WSIZE >> 1)
507492
#define P384_MUL_PUB_TABLE_SIZE (1 << (P384_MUL_PUB_WSIZE - 1))
508493

509-
// Compute "regular" wNAF representation of a scalar, see
510-
// Joye, Tunstall, "Exponent Recoding and Regular Exponentiation Algorithms",
511-
// AfricaCrypt 2009, Alg 6.
512-
// It forces an odd scalar and outputs digits in
513-
// {\pm 1, \pm 3, \pm 5, \pm 7, \pm 9, ...}
514-
// i.e. signed odd digits with _no zeroes_ -- that makes it "regular".
515-
static void p384_felem_mul_scalar_rwnaf(int16_t *out, const EC_SCALAR *in) {
516-
int16_t window, d;
517-
518-
window = (in->words[0] & P384_MUL_WSIZE_MASK) | 1;
519-
for (size_t i = 0; i < P384_MUL_NWINDOWS - 1; i++) {
520-
d = (window & P384_MUL_WSIZE_MASK) - P384_MUL_TWO_TO_WSIZE;
521-
out[i] = d;
522-
window = (window - d) >> P384_MUL_WSIZE;
523-
for (size_t j = 1; j <= P384_MUL_WSIZE; j++) {
524-
window += p384_get_bit(in, (i + 1) * P384_MUL_WSIZE + j) << j;
525-
}
526-
}
527-
out[P384_MUL_NWINDOWS - 1] = window;
528-
}
529-
530494
// p384_select_point selects the |idx|-th projective point from the given
531495
// precomputed table and copies it to |out| in constant time.
532496
static void p384_select_point(p384_felem out[3],
@@ -614,7 +578,7 @@ static void ec_GFp_nistp384_point_mul(const EC_GROUP *group, EC_JACOBIAN *r,
614578

615579
// Recode the scalar.
616580
int16_t rnaf[P384_MUL_NWINDOWS] = {0};
617-
p384_felem_mul_scalar_rwnaf(rnaf, scalar);
581+
scalar_rwnaf(rnaf, P384_MUL_WSIZE, scalar, 384);
618582

619583
// Initialize the accumulator |res| with the table entry corresponding to
620584
// the most significant digit of the recoded scalar (note that this digit
@@ -738,7 +702,7 @@ static void ec_GFp_nistp384_point_mul_base(const EC_GROUP *group,
738702
int16_t rnaf[P384_MUL_NWINDOWS] = {0};
739703

740704
// Recode the scalar.
741-
p384_felem_mul_scalar_rwnaf(rnaf, scalar);
705+
scalar_rwnaf(rnaf, P384_MUL_WSIZE, scalar, 384);
742706

743707
// Process the 4 groups of digits starting from group (3) down to group (0).
744708
for (int i = 3; i >= 0; i--) {

crypto/fipsmodule/ec/p521.c

+2-37
Original file line numberDiff line numberDiff line change
@@ -407,20 +407,6 @@ static void ec_GFp_nistp521_dbl(const EC_GROUP *group, EC_JACOBIAN *r,
407407
// The precomputed table of base point multiples is generated by the code in
408408
// |make_tables.go| script.
409409

410-
// p521_get_bit returns the |i|-th bit in |in|
411-
static crypto_word_t p521_get_bit(const EC_SCALAR *in, int i) {
412-
if (i < 0 || i >= 521) {
413-
return 0;
414-
}
415-
#if defined(OPENSSL_64_BIT)
416-
assert(sizeof(BN_ULONG) == 8);
417-
return (in->words[i >> 6] >> (i & 63)) & 1;
418-
#else
419-
assert(sizeof(BN_ULONG) == 4);
420-
return (in->words[i >> 5] >> (i & 31)) & 1;
421-
#endif
422-
}
423-
424410
// Constants for scalar encoding in the scalar multiplication functions.
425411
#define P521_MUL_WSIZE (5) // window size w
426412
// Assert the window size is 5 because the pre-computed table in |p521_table.h|
@@ -442,27 +428,6 @@ OPENSSL_STATIC_ASSERT(P521_MUL_WSIZE == 5,
442428
#define P521_MUL_TABLE_SIZE (P521_MUL_TWO_TO_WSIZE >> 1)
443429
#define P521_MUL_PUB_TABLE_SIZE (1 << (P521_MUL_PUB_WSIZE - 1))
444430

445-
// Compute "regular" wNAF representation of a scalar, see
446-
// Joye, Tunstall, "Exponent Recoding and Regular Exponentiation Algorithms",
447-
// AfricaCrypt 2009, Alg 6.
448-
// It forces an odd scalar and outputs digits in
449-
// {\pm 1, \pm 3, \pm 5, \pm 7, \pm 9, ...}
450-
// i.e. signed odd digits with _no zeroes_ -- that makes it "regular".
451-
static void p521_felem_mul_scalar_rwnaf(int16_t *out, const EC_SCALAR *in) {
452-
int16_t window, d;
453-
454-
window = (in->words[0] & P521_MUL_WSIZE_MASK) | 1;
455-
for (size_t i = 0; i < P521_MUL_NWINDOWS - 1; i++) {
456-
d = (window & P521_MUL_WSIZE_MASK) - P521_MUL_TWO_TO_WSIZE;
457-
out[i] = d;
458-
window = (window - d) >> P521_MUL_WSIZE;
459-
for (size_t j = 1; j <= P521_MUL_WSIZE; j++) {
460-
window += p521_get_bit(in, (i + 1) * P521_MUL_WSIZE + j) << j;
461-
}
462-
}
463-
out[P521_MUL_NWINDOWS - 1] = window;
464-
}
465-
466431
// p521_select_point selects the |idx|-th projective point from the given
467432
// precomputed table and copies it to |out| in constant time.
468433
static void p521_select_point(p521_felem out[3],
@@ -550,7 +515,7 @@ static void ec_GFp_nistp521_point_mul(const EC_GROUP *group, EC_JACOBIAN *r,
550515

551516
// Recode the scalar.
552517
int16_t rnaf[P521_MUL_NWINDOWS] = {0};
553-
p521_felem_mul_scalar_rwnaf(rnaf, scalar);
518+
scalar_rwnaf(rnaf, P521_MUL_WSIZE, scalar, 521);
554519

555520
// Initialize the accumulator |res| with the table entry corresponding to
556521
// the most significant digit of the recoded scalar (note that this digit
@@ -674,7 +639,7 @@ static void ec_GFp_nistp521_point_mul_base(const EC_GROUP *group,
674639
int16_t rnaf[P521_MUL_NWINDOWS] = {0};
675640

676641
// Recode the scalar.
677-
p521_felem_mul_scalar_rwnaf(rnaf, scalar);
642+
scalar_rwnaf(rnaf, P521_MUL_WSIZE, scalar, 521);
678643

679644
// Process the 4 groups of digits starting from group (3) down to group (0).
680645
for (int i = 3; i >= 0; i--) {

0 commit comments

Comments
 (0)