Skip to content

Commit fdb33dd

Browse files
refactor: Make PREC_BITS a parameter of ecmult_gen_build_prec_table
1 parent a4875e3 commit fdb33dd

6 files changed

+49
-36
lines changed

src/ecmult_gen.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@
1313
#if ECMULT_GEN_PREC_BITS != 2 && ECMULT_GEN_PREC_BITS != 4 && ECMULT_GEN_PREC_BITS != 8
1414
# error "Set ECMULT_GEN_PREC_BITS to 2, 4 or 8."
1515
#endif
16-
#define ECMULT_GEN_PREC_B ECMULT_GEN_PREC_BITS
17-
#define ECMULT_GEN_PREC_G (1 << ECMULT_GEN_PREC_B)
18-
#define ECMULT_GEN_PREC_N (256 / ECMULT_GEN_PREC_B)
16+
#define ECMULT_GEN_PREC_G(bits) (1 << bits)
17+
#define ECMULT_GEN_PREC_N(bits) (256 / bits)
1918

2019
typedef struct {
2120
/* Whether the context has been built. */

src/ecmult_gen_impl.h

+9-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx
3131

3232
/* For accelerating the computation of a*G:
3333
* To harden against timing attacks, use the following mechanism:
34-
* * Break up the multiplicand into groups of PREC_B bits, called n_0, n_1, n_2, ..., n_(PREC_N-1).
34+
* * Break up the multiplicand into groups of PREC_BITS bits, called n_0, n_1, n_2, ..., n_(PREC_N-1).
3535
* * Compute sum(n_i * (PREC_G)^i * G + U_i, i=0 ... PREC_N-1), where:
3636
* * U_i = U * 2^i, for i=0 ... PREC_N-2
3737
* * U_i = U * (1-2^(PREC_N-1)), for i=PREC_N-1
@@ -43,18 +43,23 @@ static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx
4343
* The prec values are stored in secp256k1_ecmult_gen_prec_table[i][n_i] = n_i * (PREC_G)^i * G + U_i.
4444
*/
4545
static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *gn) {
46+
int bits = ECMULT_GEN_PREC_BITS;
47+
int g = ECMULT_GEN_PREC_G(bits);
48+
int n = ECMULT_GEN_PREC_N(bits);
49+
4650
secp256k1_ge add;
4751
secp256k1_ge_storage adds;
4852
secp256k1_scalar gnb;
4953
int i, j, n_i;
54+
5055
memset(&adds, 0, sizeof(adds));
5156
*r = ctx->initial;
5257
/* Blind scalar/point multiplication by computing (n-b)G + bG instead of nG. */
5358
secp256k1_scalar_add(&gnb, gn, &ctx->blind);
5459
add.infinity = 0;
55-
for (i = 0; i < ECMULT_GEN_PREC_N; i++) {
56-
n_i = secp256k1_scalar_get_bits(&gnb, i * ECMULT_GEN_PREC_B, ECMULT_GEN_PREC_B);
57-
for (j = 0; j < ECMULT_GEN_PREC_G; j++) {
60+
for (i = 0; i < n; i++) {
61+
n_i = secp256k1_scalar_get_bits(&gnb, i * bits, bits);
62+
for (j = 0; j < g; j++) {
5863
/** This uses a conditional move to avoid any secret data in array indexes.
5964
* _Any_ use of secret indexes has been demonstrated to result in timing
6065
* sidechannels, even when the cache-line access patterns are uniform.

src/ecmult_gen_prec.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
#include "ecmult_gen.h"
1111

12-
static const size_t ECMULT_GEN_PREC_TABLE_SIZE = ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G * sizeof(secp256k1_ge_storage);
13-
14-
static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table, const secp256k1_ge* gen);
12+
static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits);
1513

1614
#endif /* SECP256K1_ECMULT_GEN_PREC_H */

src/ecmult_gen_prec_impl.h

+20-14
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@
1111
#include "group_impl.h"
1212
#include "field_impl.h"
1313
#include "ecmult_gen.h"
14+
#include "util.h"
1415

15-
static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table, const secp256k1_ge* gen) {
16-
secp256k1_ge prec[ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G];
16+
static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits) {
17+
int g = ECMULT_GEN_PREC_G(bits);
18+
int n = ECMULT_GEN_PREC_N(bits);
19+
20+
secp256k1_ge* prec = checked_malloc(&default_error_callback, n * g * sizeof(*prec));
1721
secp256k1_gej gj;
1822
secp256k1_gej nums_gej;
1923
int i, j;
@@ -35,41 +39,43 @@ static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table,
3539
VERIFY_CHECK(r);
3640
secp256k1_gej_set_ge(&nums_gej, &nums_ge);
3741
/* Add G to make the bits in x uniformly distributed. */
38-
secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g, NULL);
42+
secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, gen, NULL);
3943
}
4044

4145
/* compute prec. */
4246
{
43-
secp256k1_gej precj[ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G]; /* Jacobian versions of prec. */
4447
secp256k1_gej gbase;
4548
secp256k1_gej numsbase;
49+
secp256k1_gej* precj = checked_malloc(&default_error_callback, n * g * sizeof(*precj)); /* Jacobian versions of prec. */
4650
gbase = gj; /* PREC_G^j * G */
4751
numsbase = nums_gej; /* 2^j * nums. */
48-
for (j = 0; j < ECMULT_GEN_PREC_N; j++) {
52+
for (j = 0; j < n; j++) {
4953
/* Set precj[j*PREC_G .. j*PREC_G+(PREC_G-1)] to (numsbase, numsbase + gbase, ..., numsbase + (PREC_G-1)*gbase). */
50-
precj[j*ECMULT_GEN_PREC_G] = numsbase;
51-
for (i = 1; i < ECMULT_GEN_PREC_G; i++) {
52-
secp256k1_gej_add_var(&precj[j*ECMULT_GEN_PREC_G + i], &precj[j*ECMULT_GEN_PREC_G + i - 1], &gbase, NULL);
54+
precj[j*g] = numsbase;
55+
for (i = 1; i < g; i++) {
56+
secp256k1_gej_add_var(&precj[j*g + i], &precj[j*g + i - 1], &gbase, NULL);
5357
}
5458
/* Multiply gbase by PREC_G. */
55-
for (i = 0; i < ECMULT_GEN_PREC_B; i++) {
59+
for (i = 0; i < bits; i++) {
5660
secp256k1_gej_double_var(&gbase, &gbase, NULL);
5761
}
5862
/* Multiply numbase by 2. */
5963
secp256k1_gej_double_var(&numsbase, &numsbase, NULL);
60-
if (j == ECMULT_GEN_PREC_N - 2) {
64+
if (j == n - 2) {
6165
/* In the last iteration, numsbase is (1 - 2^j) * nums instead. */
6266
secp256k1_gej_neg(&numsbase, &numsbase);
6367
secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL);
6468
}
6569
}
66-
secp256k1_ge_set_all_gej_var(prec, precj, ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G);
70+
secp256k1_ge_set_all_gej_var(prec, precj, n * g);
71+
free(precj);
6772
}
68-
for (j = 0; j < ECMULT_GEN_PREC_N; j++) {
69-
for (i = 0; i < ECMULT_GEN_PREC_G; i++) {
70-
secp256k1_ge_to_storage(&table[j*ECMULT_GEN_PREC_G + i], &prec[j*ECMULT_GEN_PREC_G + i]);
73+
for (j = 0; j < n; j++) {
74+
for (i = 0; i < g; i++) {
75+
secp256k1_ge_to_storage(&table[j*g + i], &prec[j*g + i]);
7176
}
7277
}
78+
free(prec);
7379
}
7480

7581
#endif /* SECP256K1_ECMULT_GEN_PREC_IMPL_H */

src/gen_ecmult_gen_static_prec_table.c

+16-11
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ int main(int argc, char **argv) {
3030
const char outfile[] = "src/ecmult_gen_static_prec_table.h";
3131
FILE* fp;
3232

33+
int bits = ECMULT_GEN_PREC_BITS;
34+
int g = ECMULT_GEN_PREC_G(bits);
35+
int n = ECMULT_GEN_PREC_N(bits);
36+
table = checked_malloc(&default_error_callback, n * g * sizeof(secp256k1_ge_storage));
37+
3338
(void)argc;
3439
(void)argv;
3540

@@ -46,28 +51,28 @@ int main(int argc, char **argv) {
4651

4752
fprintf(fp, "#define SC SECP256K1_GE_STORAGE_CONST\n");
4853

49-
fprintf(fp, "#if ECMULT_GEN_PREC_N != %d || ECMULT_GEN_PREC_G != %d\n", ECMULT_GEN_PREC_N, ECMULT_GEN_PREC_G);
50-
fprintf(fp, " #error configuration mismatch, invalid ECMULT_GEN_PREC_N, ECMULT_GEN_PREC_G. Try deleting %s before the build.\n", outfile);
54+
fprintf(fp, "#if ECMULT_GEN_PREC_BITS != %d\n", bits);
55+
fprintf(fp, " #error configuration mismatch, invalid ECMULT_GEN_PREC_BITS. Try deleting ecmult_static_context.h before the build.\n");
5156
fprintf(fp, "#endif\n");
5257

5358
fprintf(fp, "#ifdef EXHAUSTIVE_TEST_ORDER\n");
54-
fprintf(fp, "static secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G];\n");
59+
fprintf(fp, "static secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N(ECMULT_GEN_PREC_BITS)][ECMULT_GEN_PREC_G(ECMULT_GEN_PREC_BITS)];\n");
5560
fprintf(fp, "#else\n");
56-
fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G] = {\n");
61+
fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N(ECMULT_GEN_PREC_BITS)][ECMULT_GEN_PREC_G(ECMULT_GEN_PREC_BITS)] = {\n");
62+
63+
secp256k1_ecmult_gen_create_prec_table(table, &secp256k1_ge_const_g, bits);
5764

58-
table = checked_malloc(&default_error_callback, ECMULT_GEN_PREC_TABLE_SIZE);
59-
secp256k1_ecmult_gen_create_prec_table(table, &secp256k1_ge_const_g);
60-
for(outer = 0; outer != ECMULT_GEN_PREC_N; outer++) {
65+
for(outer = 0; outer != n; outer++) {
6166
fprintf(fp,"{\n");
62-
for(inner = 0; inner != ECMULT_GEN_PREC_G; inner++) {
63-
fprintf(fp," SC(%uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu)", SECP256K1_GE_STORAGE_CONST_GET(table[outer * ECMULT_GEN_PREC_G + inner]));
64-
if (inner != ECMULT_GEN_PREC_G - 1) {
67+
for(inner = 0; inner != g; inner++) {
68+
fprintf(fp," SC(%uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu)", SECP256K1_GE_STORAGE_CONST_GET(table[outer * g + inner]));
69+
if (inner != g - 1) {
6570
fprintf(fp,",\n");
6671
} else {
6772
fprintf(fp,"\n");
6873
}
6974
}
70-
if (outer != ECMULT_GEN_PREC_N - 1) {
75+
if (outer != n - 1) {
7176
fprintf(fp,"},\n");
7277
} else {
7378
fprintf(fp,"}\n");

src/tests_exhaustive.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ int main(int argc, char** argv) {
390390
}
391391

392392
/* Recreate the ecmult_gen table using the right generator (as selected via EXHAUSTIVE_TEST_ORDER) */
393-
secp256k1_ecmult_gen_create_prec_table(&secp256k1_ecmult_gen_prec_table[0][0], &secp256k1_ge_const_g);
393+
secp256k1_ecmult_gen_create_prec_table(&secp256k1_ecmult_gen_prec_table[0][0], &secp256k1_ge_const_g, ECMULT_GEN_PREC_BITS);
394394

395395
while (count--) {
396396
/* Build context */

0 commit comments

Comments
 (0)