Skip to content

Commit

Permalink
refactor: Make PREC_BITS a parameter of ecmult_gen_build_prec_table
Browse files Browse the repository at this point in the history
  • Loading branch information
real-or-random committed Dec 5, 2021
1 parent a4875e3 commit fdb33dd
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 36 deletions.
5 changes: 2 additions & 3 deletions src/ecmult_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
13 changes: 9 additions & 4 deletions src/ecmult_gen_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down
4 changes: 1 addition & 3 deletions src/ecmult_gen_prec.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
34 changes: 20 additions & 14 deletions src/ecmult_gen_prec_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 */
27 changes: 16 additions & 11 deletions src/gen_ecmult_gen_static_prec_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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");
Expand Down
2 changes: 1 addition & 1 deletion src/tests_exhaustive.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit fdb33dd

Please sign in to comment.