From fdb33dd1227f935ca95c7f8bd9429f42e18a870e Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Wed, 8 Sep 2021 18:49:06 +0200 Subject: [PATCH] refactor: Make PREC_BITS a parameter of ecmult_gen_build_prec_table --- src/ecmult_gen.h | 5 ++-- src/ecmult_gen_impl.h | 13 +++++++--- src/ecmult_gen_prec.h | 4 +-- src/ecmult_gen_prec_impl.h | 34 +++++++++++++++----------- src/gen_ecmult_gen_static_prec_table.c | 27 +++++++++++--------- src/tests_exhaustive.c | 2 +- 6 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/ecmult_gen.h b/src/ecmult_gen.h index 9930b6ac3..f48f26646 100644 --- a/src/ecmult_gen.h +++ b/src/ecmult_gen.h @@ -13,9 +13,8 @@ #if ECMULT_GEN_PREC_BITS != 2 && ECMULT_GEN_PREC_BITS != 4 && ECMULT_GEN_PREC_BITS != 8 # error "Set ECMULT_GEN_PREC_BITS to 2, 4 or 8." #endif -#define ECMULT_GEN_PREC_B ECMULT_GEN_PREC_BITS -#define ECMULT_GEN_PREC_G (1 << ECMULT_GEN_PREC_B) -#define ECMULT_GEN_PREC_N (256 / ECMULT_GEN_PREC_B) +#define ECMULT_GEN_PREC_G(bits) (1 << bits) +#define ECMULT_GEN_PREC_N(bits) (256 / bits) typedef struct { /* Whether the context has been built. */ diff --git a/src/ecmult_gen_impl.h b/src/ecmult_gen_impl.h index 22b7aca0c..6a6ab9a4b 100644 --- a/src/ecmult_gen_impl.h +++ b/src/ecmult_gen_impl.h @@ -31,7 +31,7 @@ static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx /* For accelerating the computation of a*G: * To harden against timing attacks, use the following mechanism: - * * Break up the multiplicand into groups of PREC_B bits, called n_0, n_1, n_2, ..., n_(PREC_N-1). + * * Break up the multiplicand into groups of PREC_BITS bits, called n_0, n_1, n_2, ..., n_(PREC_N-1). * * Compute sum(n_i * (PREC_G)^i * G + U_i, i=0 ... PREC_N-1), where: * * U_i = U * 2^i, for i=0 ... PREC_N-2 * * 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 * The prec values are stored in secp256k1_ecmult_gen_prec_table[i][n_i] = n_i * (PREC_G)^i * G + U_i. */ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *gn) { + int bits = ECMULT_GEN_PREC_BITS; + int g = ECMULT_GEN_PREC_G(bits); + int n = ECMULT_GEN_PREC_N(bits); + secp256k1_ge add; secp256k1_ge_storage adds; secp256k1_scalar gnb; int i, j, n_i; + memset(&adds, 0, sizeof(adds)); *r = ctx->initial; /* Blind scalar/point multiplication by computing (n-b)G + bG instead of nG. */ secp256k1_scalar_add(&gnb, gn, &ctx->blind); add.infinity = 0; - for (i = 0; i < ECMULT_GEN_PREC_N; i++) { - n_i = secp256k1_scalar_get_bits(&gnb, i * ECMULT_GEN_PREC_B, ECMULT_GEN_PREC_B); - for (j = 0; j < ECMULT_GEN_PREC_G; j++) { + for (i = 0; i < n; i++) { + n_i = secp256k1_scalar_get_bits(&gnb, i * bits, bits); + for (j = 0; j < g; j++) { /** This uses a conditional move to avoid any secret data in array indexes. * _Any_ use of secret indexes has been demonstrated to result in timing * sidechannels, even when the cache-line access patterns are uniform. diff --git a/src/ecmult_gen_prec.h b/src/ecmult_gen_prec.h index c8bd731f3..0cfcde9b7 100644 --- a/src/ecmult_gen_prec.h +++ b/src/ecmult_gen_prec.h @@ -9,8 +9,6 @@ #include "ecmult_gen.h" -static const size_t ECMULT_GEN_PREC_TABLE_SIZE = ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G * sizeof(secp256k1_ge_storage); - -static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table, const secp256k1_ge* gen); +static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits); #endif /* SECP256K1_ECMULT_GEN_PREC_H */ diff --git a/src/ecmult_gen_prec_impl.h b/src/ecmult_gen_prec_impl.h index 19ed6c63c..bac76c8b1 100644 --- a/src/ecmult_gen_prec_impl.h +++ b/src/ecmult_gen_prec_impl.h @@ -11,9 +11,13 @@ #include "group_impl.h" #include "field_impl.h" #include "ecmult_gen.h" +#include "util.h" -static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table, const secp256k1_ge* gen) { - secp256k1_ge prec[ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G]; +static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits) { + int g = ECMULT_GEN_PREC_G(bits); + int n = ECMULT_GEN_PREC_N(bits); + + secp256k1_ge* prec = checked_malloc(&default_error_callback, n * g * sizeof(*prec)); secp256k1_gej gj; secp256k1_gej nums_gej; int i, j; @@ -35,41 +39,43 @@ static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table, VERIFY_CHECK(r); secp256k1_gej_set_ge(&nums_gej, &nums_ge); /* Add G to make the bits in x uniformly distributed. */ - secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g, NULL); + secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, gen, NULL); } /* compute prec. */ { - secp256k1_gej precj[ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G]; /* Jacobian versions of prec. */ secp256k1_gej gbase; secp256k1_gej numsbase; + secp256k1_gej* precj = checked_malloc(&default_error_callback, n * g * sizeof(*precj)); /* Jacobian versions of prec. */ gbase = gj; /* PREC_G^j * G */ numsbase = nums_gej; /* 2^j * nums. */ - for (j = 0; j < ECMULT_GEN_PREC_N; j++) { + for (j = 0; j < n; j++) { /* Set precj[j*PREC_G .. j*PREC_G+(PREC_G-1)] to (numsbase, numsbase + gbase, ..., numsbase + (PREC_G-1)*gbase). */ - precj[j*ECMULT_GEN_PREC_G] = numsbase; - for (i = 1; i < ECMULT_GEN_PREC_G; i++) { - secp256k1_gej_add_var(&precj[j*ECMULT_GEN_PREC_G + i], &precj[j*ECMULT_GEN_PREC_G + i - 1], &gbase, NULL); + precj[j*g] = numsbase; + for (i = 1; i < g; i++) { + secp256k1_gej_add_var(&precj[j*g + i], &precj[j*g + i - 1], &gbase, NULL); } /* Multiply gbase by PREC_G. */ - for (i = 0; i < ECMULT_GEN_PREC_B; i++) { + for (i = 0; i < bits; i++) { secp256k1_gej_double_var(&gbase, &gbase, NULL); } /* Multiply numbase by 2. */ secp256k1_gej_double_var(&numsbase, &numsbase, NULL); - if (j == ECMULT_GEN_PREC_N - 2) { + if (j == n - 2) { /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ secp256k1_gej_neg(&numsbase, &numsbase); secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL); } } - secp256k1_ge_set_all_gej_var(prec, precj, ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G); + secp256k1_ge_set_all_gej_var(prec, precj, n * g); + free(precj); } - for (j = 0; j < ECMULT_GEN_PREC_N; j++) { - for (i = 0; i < ECMULT_GEN_PREC_G; i++) { - secp256k1_ge_to_storage(&table[j*ECMULT_GEN_PREC_G + i], &prec[j*ECMULT_GEN_PREC_G + i]); + for (j = 0; j < n; j++) { + for (i = 0; i < g; i++) { + secp256k1_ge_to_storage(&table[j*g + i], &prec[j*g + i]); } } + free(prec); } #endif /* SECP256K1_ECMULT_GEN_PREC_IMPL_H */ diff --git a/src/gen_ecmult_gen_static_prec_table.c b/src/gen_ecmult_gen_static_prec_table.c index 58684705e..0a5c59284 100644 --- a/src/gen_ecmult_gen_static_prec_table.c +++ b/src/gen_ecmult_gen_static_prec_table.c @@ -30,6 +30,11 @@ int main(int argc, char **argv) { const char outfile[] = "src/ecmult_gen_static_prec_table.h"; FILE* fp; + int bits = ECMULT_GEN_PREC_BITS; + int g = ECMULT_GEN_PREC_G(bits); + int n = ECMULT_GEN_PREC_N(bits); + table = checked_malloc(&default_error_callback, n * g * sizeof(secp256k1_ge_storage)); + (void)argc; (void)argv; @@ -46,28 +51,28 @@ int main(int argc, char **argv) { fprintf(fp, "#define SC SECP256K1_GE_STORAGE_CONST\n"); - fprintf(fp, "#if ECMULT_GEN_PREC_N != %d || ECMULT_GEN_PREC_G != %d\n", ECMULT_GEN_PREC_N, ECMULT_GEN_PREC_G); - fprintf(fp, " #error configuration mismatch, invalid ECMULT_GEN_PREC_N, ECMULT_GEN_PREC_G. Try deleting %s before the build.\n", outfile); + fprintf(fp, "#if ECMULT_GEN_PREC_BITS != %d\n", bits); + fprintf(fp, " #error configuration mismatch, invalid ECMULT_GEN_PREC_BITS. Try deleting ecmult_static_context.h before the build.\n"); fprintf(fp, "#endif\n"); fprintf(fp, "#ifdef EXHAUSTIVE_TEST_ORDER\n"); - fprintf(fp, "static secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G];\n"); + 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"); fprintf(fp, "#else\n"); - fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G] = {\n"); + 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"); + + secp256k1_ecmult_gen_create_prec_table(table, &secp256k1_ge_const_g, bits); - table = checked_malloc(&default_error_callback, ECMULT_GEN_PREC_TABLE_SIZE); - secp256k1_ecmult_gen_create_prec_table(table, &secp256k1_ge_const_g); - for(outer = 0; outer != ECMULT_GEN_PREC_N; outer++) { + for(outer = 0; outer != n; outer++) { fprintf(fp,"{\n"); - for(inner = 0; inner != ECMULT_GEN_PREC_G; inner++) { - 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])); - if (inner != ECMULT_GEN_PREC_G - 1) { + for(inner = 0; inner != g; inner++) { + 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])); + if (inner != g - 1) { fprintf(fp,",\n"); } else { fprintf(fp,"\n"); } } - if (outer != ECMULT_GEN_PREC_N - 1) { + if (outer != n - 1) { fprintf(fp,"},\n"); } else { fprintf(fp,"}\n"); diff --git a/src/tests_exhaustive.c b/src/tests_exhaustive.c index 1d025ac73..6bae7a477 100644 --- a/src/tests_exhaustive.c +++ b/src/tests_exhaustive.c @@ -390,7 +390,7 @@ int main(int argc, char** argv) { } /* Recreate the ecmult_gen table using the right generator (as selected via EXHAUSTIVE_TEST_ORDER) */ - secp256k1_ecmult_gen_create_prec_table(&secp256k1_ecmult_gen_prec_table[0][0], &secp256k1_ge_const_g); + secp256k1_ecmult_gen_create_prec_table(&secp256k1_ecmult_gen_prec_table[0][0], &secp256k1_ge_const_g, ECMULT_GEN_PREC_BITS); while (count--) { /* Build context */