Skip to content

Commit 22dc2c0

Browse files
ecmult_gen: Move table creation to new file and force static prec
1 parent ea5e8a9 commit 22dc2c0

7 files changed

+105
-97
lines changed

Makefile.am

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ noinst_HEADERS += src/ecmult_const.h
2828
noinst_HEADERS += src/ecmult_const_impl.h
2929
noinst_HEADERS += src/ecmult_gen.h
3030
noinst_HEADERS += src/ecmult_gen_impl.h
31+
noinst_HEADERS += src/ecmult_gen_prec.h
32+
noinst_HEADERS += src/ecmult_gen_prec_impl.h
3133
noinst_HEADERS += src/field_10x26.h
3234
noinst_HEADERS += src/field_10x26_impl.h
3335
noinst_HEADERS += src/field_5x52.h
@@ -143,6 +145,7 @@ $(gen_context_BIN): $(gen_context_OBJECTS)
143145

144146
$(libsecp256k1_la_OBJECTS): src/ecmult_static_context.h
145147
$(tests_OBJECTS): src/ecmult_static_context.h
148+
$(exhaustive_tests_OBJECTS): src/ecmult_static_context.h
146149
$(bench_internal_OBJECTS): src/ecmult_static_context.h
147150
$(bench_ecmult_OBJECTS): src/ecmult_static_context.h
148151

configure.ac

+2-4
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,8 @@ AC_ARG_ENABLE(exhaustive_tests,
125125
[use_exhaustive_tests=$enableval],
126126
[use_exhaustive_tests=yes])
127127

128-
AC_ARG_ENABLE(ecmult_static_precomputation,
129-
AS_HELP_STRING([--enable-ecmult-static-precomputation],[enable precomputed ecmult table for signing [default=auto]]),
130-
[use_ecmult_static_precomputation=$enableval],
131-
[use_ecmult_static_precomputation=auto])
128+
# Force static precomputation. The code handling this will be removed in a later commit.
129+
use_ecmult_static_precomputation=yes
132130

133131
AC_ARG_ENABLE(module_ecdh,
134132
AS_HELP_STRING([--enable-module-ecdh],[enable ECDH shared secret computation]),

src/ecmult_gen_impl.h

+1-80
Original file line numberDiff line numberDiff line change
@@ -12,92 +12,20 @@
1212
#include "group.h"
1313
#include "ecmult_gen.h"
1414
#include "hash_impl.h"
15-
#ifdef USE_ECMULT_STATIC_PRECOMPUTATION
1615
#include "ecmult_static_context.h"
17-
#endif
1816

19-
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
20-
static const size_t SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE = ROUND_TO_ALIGN(sizeof(*((secp256k1_ecmult_gen_context*) NULL)->prec));
21-
#else
22-
static const size_t SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE = 0;
23-
#endif
17+
static const size_t SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE = 0;
2418

2519
static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context *ctx) {
2620
ctx->prec = NULL;
2721
}
2822

2923
static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx, void **prealloc) {
30-
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
31-
secp256k1_ge prec[ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G];
32-
secp256k1_gej gj;
33-
secp256k1_gej nums_gej;
34-
int i, j;
35-
size_t const prealloc_size = SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE;
36-
void* const base = *prealloc;
37-
#endif
38-
3924
if (ctx->prec != NULL) {
4025
return;
4126
}
42-
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
43-
ctx->prec = (secp256k1_ge_storage (*)[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G])manual_alloc(prealloc, prealloc_size, base, prealloc_size);
44-
45-
/* get the generator */
46-
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
47-
48-
/* Construct a group element with no known corresponding scalar (nothing up my sleeve). */
49-
{
50-
static const unsigned char nums_b32[33] = "The scalar for this x is unknown";
51-
secp256k1_fe nums_x;
52-
secp256k1_ge nums_ge;
53-
int r;
54-
r = secp256k1_fe_set_b32(&nums_x, nums_b32);
55-
(void)r;
56-
VERIFY_CHECK(r);
57-
r = secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0);
58-
(void)r;
59-
VERIFY_CHECK(r);
60-
secp256k1_gej_set_ge(&nums_gej, &nums_ge);
61-
/* Add G to make the bits in x uniformly distributed. */
62-
secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g, NULL);
63-
}
64-
65-
/* compute prec. */
66-
{
67-
secp256k1_gej precj[ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G]; /* Jacobian versions of prec. */
68-
secp256k1_gej gbase;
69-
secp256k1_gej numsbase;
70-
gbase = gj; /* PREC_G^j * G */
71-
numsbase = nums_gej; /* 2^j * nums. */
72-
for (j = 0; j < ECMULT_GEN_PREC_N; j++) {
73-
/* Set precj[j*PREC_G .. j*PREC_G+(PREC_G-1)] to (numsbase, numsbase + gbase, ..., numsbase + (PREC_G-1)*gbase). */
74-
precj[j*ECMULT_GEN_PREC_G] = numsbase;
75-
for (i = 1; i < ECMULT_GEN_PREC_G; i++) {
76-
secp256k1_gej_add_var(&precj[j*ECMULT_GEN_PREC_G + i], &precj[j*ECMULT_GEN_PREC_G + i - 1], &gbase, NULL);
77-
}
78-
/* Multiply gbase by PREC_G. */
79-
for (i = 0; i < ECMULT_GEN_PREC_B; i++) {
80-
secp256k1_gej_double_var(&gbase, &gbase, NULL);
81-
}
82-
/* Multiply numbase by 2. */
83-
secp256k1_gej_double_var(&numsbase, &numsbase, NULL);
84-
if (j == ECMULT_GEN_PREC_N - 2) {
85-
/* In the last iteration, numsbase is (1 - 2^j) * nums instead. */
86-
secp256k1_gej_neg(&numsbase, &numsbase);
87-
secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL);
88-
}
89-
}
90-
secp256k1_ge_set_all_gej_var(prec, precj, ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G);
91-
}
92-
for (j = 0; j < ECMULT_GEN_PREC_N; j++) {
93-
for (i = 0; i < ECMULT_GEN_PREC_G; i++) {
94-
secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*ECMULT_GEN_PREC_G + i]);
95-
}
96-
}
97-
#else
9827
(void)prealloc;
9928
ctx->prec = (secp256k1_ge_storage (*)[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G])secp256k1_ecmult_static_context;
100-
#endif
10129
secp256k1_ecmult_gen_blind(ctx, NULL);
10230
}
10331

@@ -106,14 +34,7 @@ static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_cont
10634
}
10735

10836
static void secp256k1_ecmult_gen_context_finalize_memcpy(secp256k1_ecmult_gen_context *dst, const secp256k1_ecmult_gen_context *src) {
109-
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
110-
if (src->prec != NULL) {
111-
/* We cast to void* first to suppress a -Wcast-align warning. */
112-
dst->prec = (secp256k1_ge_storage (*)[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G])(void*)((unsigned char*)dst + ((unsigned char*)src->prec - (unsigned char*)src));
113-
}
114-
#else
11537
(void)dst, (void)src;
116-
#endif
11738
}
11839

11940
static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx) {

src/ecmult_gen_prec.h

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/***********************************************************************
2+
* Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell *
3+
* Distributed under the MIT software license, see the accompanying *
4+
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5+
***********************************************************************/
6+
7+
#ifndef SECP256K1_ECMULT_GEN_PREC_H
8+
#define SECP256K1_ECMULT_GEN_PREC_H
9+
10+
#include "ecmult_gen.h"
11+
12+
static const size_t ECMULT_GEN_PREC_TABLE_SIZE = ROUND_TO_ALIGN(sizeof(*((secp256k1_ecmult_gen_context*) NULL)->prec));
13+
14+
static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ecmult_gen_context *ctx, void **prealloc);
15+
16+
#endif /* SECP256K1_ECMULT_GEN_PREC_H */

src/ecmult_gen_prec_impl.h

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/***********************************************************************
2+
* Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell *
3+
* Distributed under the MIT software license, see the accompanying *
4+
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5+
***********************************************************************/
6+
7+
#ifndef SECP256K1_ECMULT_GEN_PREC_IMPL_H
8+
#define SECP256K1_ECMULT_GEN_PREC_IMPL_H
9+
10+
#include "ecmult_gen_prec.h"
11+
#include "group_impl.h"
12+
#include "field_impl.h"
13+
#include "ecmult_gen.h"
14+
15+
static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ecmult_gen_context *ctx, void **prealloc) {
16+
secp256k1_ge prec[ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G];
17+
secp256k1_gej gj;
18+
secp256k1_gej nums_gej;
19+
int i, j;
20+
size_t const prealloc_size = ECMULT_GEN_PREC_TABLE_SIZE;
21+
void* const base = *prealloc;
22+
ctx->prec = (secp256k1_ge_storage (*)[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G])manual_alloc(prealloc, prealloc_size, base, prealloc_size);
23+
24+
/* get the generator */
25+
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
26+
27+
/* Construct a group element with no known corresponding scalar (nothing up my sleeve). */
28+
{
29+
static const unsigned char nums_b32[33] = "The scalar for this x is unknown";
30+
secp256k1_fe nums_x;
31+
secp256k1_ge nums_ge;
32+
int r;
33+
r = secp256k1_fe_set_b32(&nums_x, nums_b32);
34+
(void)r;
35+
VERIFY_CHECK(r);
36+
r = secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0);
37+
(void)r;
38+
VERIFY_CHECK(r);
39+
secp256k1_gej_set_ge(&nums_gej, &nums_ge);
40+
/* Add G to make the bits in x uniformly distributed. */
41+
secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g, NULL);
42+
}
43+
44+
/* compute prec. */
45+
{
46+
secp256k1_gej precj[ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G]; /* Jacobian versions of prec. */
47+
secp256k1_gej gbase;
48+
secp256k1_gej numsbase;
49+
gbase = gj; /* PREC_G^j * G */
50+
numsbase = nums_gej; /* 2^j * nums. */
51+
for (j = 0; j < ECMULT_GEN_PREC_N; j++) {
52+
/* Set precj[j*PREC_G .. j*PREC_G+(PREC_G-1)] to (numsbase, numsbase + gbase, ..., numsbase + (PREC_G-1)*gbase). */
53+
precj[j*ECMULT_GEN_PREC_G] = numsbase;
54+
for (i = 1; i < ECMULT_GEN_PREC_G; i++) {
55+
secp256k1_gej_add_var(&precj[j*ECMULT_GEN_PREC_G + i], &precj[j*ECMULT_GEN_PREC_G + i - 1], &gbase, NULL);
56+
}
57+
/* Multiply gbase by PREC_G. */
58+
for (i = 0; i < ECMULT_GEN_PREC_B; i++) {
59+
secp256k1_gej_double_var(&gbase, &gbase, NULL);
60+
}
61+
/* Multiply numbase by 2. */
62+
secp256k1_gej_double_var(&numsbase, &numsbase, NULL);
63+
if (j == ECMULT_GEN_PREC_N - 2) {
64+
/* In the last iteration, numsbase is (1 - 2^j) * nums instead. */
65+
secp256k1_gej_neg(&numsbase, &numsbase);
66+
secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL);
67+
}
68+
}
69+
secp256k1_ge_set_all_gej_var(prec, precj, ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G);
70+
}
71+
for (j = 0; j < ECMULT_GEN_PREC_N; j++) {
72+
for (i = 0; i < ECMULT_GEN_PREC_G; i++) {
73+
secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*ECMULT_GEN_PREC_G + i]);
74+
}
75+
}
76+
}
77+
78+
#endif /* SECP256K1_ECMULT_GEN_PREC_IMPL_H */

src/gen_context.c

+5-11
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010
#include "libsecp256k1-config.h"
1111
#endif
1212

13-
/* We can't require the precomputed tables when creating them. */
14-
#undef USE_ECMULT_STATIC_PRECOMPUTATION
15-
1613
/* In principle we could use ASM, but this yields only a minor speedup in
1714
build time and it's very complicated. In particular when cross-compiling, we'd
1815
need to build the ASM for the build and the host machine. */
@@ -22,10 +19,9 @@
2219
#include "../include/secp256k1.h"
2320
#include "assumptions.h"
2421
#include "util.h"
25-
#include "field_impl.h"
26-
#include "scalar_impl.h"
27-
#include "group_impl.h"
28-
#include "ecmult_gen_impl.h"
22+
#include "group.h"
23+
#include "ecmult_gen.h"
24+
#include "ecmult_gen_prec_impl.h"
2925

3026
static void default_error_callback_fn(const char* str, void* data) {
3127
(void)data;
@@ -63,10 +59,9 @@ int main(int argc, char **argv) {
6359
fprintf(fp, "#endif\n");
6460
fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_static_context[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G] = {\n");
6561

66-
base = checked_malloc(&default_error_callback, SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE);
62+
base = checked_malloc(&default_error_callback, ECMULT_GEN_PREC_TABLE_SIZE);
6763
prealloc = base;
68-
secp256k1_ecmult_gen_context_init(&ctx);
69-
secp256k1_ecmult_gen_context_build(&ctx, &prealloc);
64+
secp256k1_ecmult_gen_create_prec_table(&ctx, &prealloc);
7065
for(outer = 0; outer != ECMULT_GEN_PREC_N; outer++) {
7166
fprintf(fp,"{\n");
7267
for(inner = 0; inner != ECMULT_GEN_PREC_G; inner++) {
@@ -84,7 +79,6 @@ int main(int argc, char **argv) {
8479
}
8580
}
8681
fprintf(fp,"};\n");
87-
secp256k1_ecmult_gen_context_clear(&ctx);
8882
free(base);
8983

9084
fprintf(fp, "#undef SC\n");

src/tests_exhaustive.c

-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
#include <stdlib.h>
1313
#include <time.h>
1414

15-
#undef USE_ECMULT_STATIC_PRECOMPUTATION
16-
1715
#ifndef EXHAUSTIVE_TEST_ORDER
1816
/* see group_impl.h for allowable values */
1917
#define EXHAUSTIVE_TEST_ORDER 13

0 commit comments

Comments
 (0)