Skip to content

Commit 9a5a87e

Browse files
Merge #956: Replace ecmult_context with a generated static array.
20abd52 Add tests for pre_g tables. (Russell O'Connor) 6815761 Remove ecmult_context. (Russell O'Connor) f20dcbb Correct typo. (Russell O'Connor) 16a3cc0 Generate ecmult_static_pre_g.h (Russell O'Connor) 8de2d86 Bump memory limits in advance of making the ecmult context static. (Russell O'Connor) Pull request description: Replace ecmult_context with a static array. ACKs for top commit: real-or-random: ACK 20abd52 code inspection and tested some parameters sipa: utACK 20abd52 (reviewed diff with earlier reviewed commit 8e9f75a) Tree-SHA512: 9980edf36e81430ea1774e6d5eef81946c26684f6e13eab2b61a8a6c9f23ed074ea8f33e80023bdf4275749275221879eacc8f222d2027e4286725127139f069
2 parents d7ec49a + 20abd52 commit 9a5a87e

24 files changed

+17061
-461
lines changed

.cirrus.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ task:
278278
container:
279279
dockerfile: ci/linux-debian.Dockerfile
280280
cpu: 1
281-
memory: 1G
281+
memory: 2G
282282
env:
283283
ECDH: yes
284284
RECOVERY: yes

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
src/ecmult_static_pre_g.h linguist-generated

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ bench_internal
99
tests
1010
exhaustive_tests
1111
gen_context
12+
gen_ecmult_static_pre_g
1213
valgrind_ctime_test
1314
*.exe
1415
*.so

Makefile.am

+9-2
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,19 @@ exhaustive_tests_LDFLAGS = -static
127127
TESTS += exhaustive_tests
128128
endif
129129

130+
EXTRA_PROGRAMS = gen_ecmult_static_pre_g
131+
gen_ecmult_static_pre_g_SOURCES = src/gen_ecmult_static_pre_g.c
132+
# See Automake manual, Section "Errors with distclean"
133+
src/ecmult_static_pre_g.h:
134+
$(MAKE) $(AM_MAKEFLAGS) gen_ecmult_static_pre_g$(EXEEXT)
135+
./gen_ecmult_static_pre_g$(EXEEXT)
136+
130137
if USE_ECMULT_STATIC_PRECOMPUTATION
131138
CPPFLAGS_FOR_BUILD +=-I$(top_srcdir) -I$(builddir)/src
132139

133140
gen_context_OBJECTS = gen_context.o
134141
gen_context_BIN = gen_context$(BUILD_EXEEXT)
135-
gen_%.o: src/gen_%.c src/libsecp256k1-config.h
142+
$(gen_context_OBJECTS): src/gen_context.c src/libsecp256k1-config.h
136143
$(CC_FOR_BUILD) $(DEFS) $(CPPFLAGS_FOR_BUILD) $(SECP_CFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@
137144

138145
$(gen_context_BIN): $(gen_context_OBJECTS)
@@ -149,7 +156,7 @@ src/ecmult_static_context.h: $(gen_context_BIN)
149156
CLEANFILES = $(gen_context_BIN) src/ecmult_static_context.h
150157
endif
151158

152-
EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h
159+
EXTRA_DIST = autogen.sh src/gen_context.c src/ecmult_static_pre_g.h src/basic-config.h
153160

154161
if ENABLE_MODULE_ECDH
155162
include src/modules/ecdh/Makefile.am.include

configure.ac

+2
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ AC_ARG_WITH([ecmult-window], [AS_HELP_STRING([--with-ecmult-window=SIZE|auto],
177177
[window size for ecmult precomputation for verification, specified as integer in range [2..24].]
178178
[Larger values result in possibly better performance at the cost of an exponentially larger precomputed table.]
179179
[The table will store 2^(SIZE-1) * 64 bytes of data but can be larger in memory due to platform-specific padding and alignment.]
180+
[A window size larger than 15 will require you delete the prebuilt ecmult_static_pre_g.h file so that it can be rebuilt.]
181+
[For very large window sizes, use "make -j 1" to reduce memory use during compilation.]
180182
["auto" is a reasonable setting for desktop machines (currently 15). [default=auto]]
181183
)],
182184
[req_ecmult_window=$withval], [req_ecmult_window=auto])

src/bench_ecmult.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ static void bench_ecmult_1(void* arg, int iters) {
129129
int i;
130130

131131
for (i = 0; i < iters; ++i) {
132-
secp256k1_ecmult(&data->ctx->ecmult_ctx, &data->output[i], &data->pubkeys_gej[(data->offset1+i) % POINTS], &data->scalars[(data->offset2+i) % POINTS], NULL);
132+
secp256k1_ecmult(&data->output[i], &data->pubkeys_gej[(data->offset1+i) % POINTS], &data->scalars[(data->offset2+i) % POINTS], NULL);
133133
}
134134
}
135135

@@ -145,7 +145,7 @@ static void bench_ecmult_1g(void* arg, int iters) {
145145

146146
secp256k1_scalar_set_int(&zero, 0);
147147
for (i = 0; i < iters; ++i) {
148-
secp256k1_ecmult(&data->ctx->ecmult_ctx, &data->output[i], NULL, &zero, &data->scalars[(data->offset1+i) % POINTS]);
148+
secp256k1_ecmult(&data->output[i], NULL, &zero, &data->scalars[(data->offset1+i) % POINTS]);
149149
}
150150
}
151151

@@ -159,7 +159,7 @@ static void bench_ecmult_2g(void* arg, int iters) {
159159
int i;
160160

161161
for (i = 0; i < iters/2; ++i) {
162-
secp256k1_ecmult(&data->ctx->ecmult_ctx, &data->output[i], &data->pubkeys_gej[(data->offset1+i) % POINTS], &data->scalars[(data->offset2+i) % POINTS], &data->scalars[(data->offset1+i) % POINTS]);
162+
secp256k1_ecmult(&data->output[i], &data->pubkeys_gej[(data->offset1+i) % POINTS], &data->scalars[(data->offset2+i) % POINTS], &data->scalars[(data->offset1+i) % POINTS]);
163163
}
164164
}
165165

@@ -207,7 +207,7 @@ static void bench_ecmult_multi(void* arg, int iters) {
207207
iters = iters / data->count;
208208

209209
for (iter = 0; iter < iters; ++iter) {
210-
data->ecmult_multi(&data->ctx->error_callback, &data->ctx->ecmult_ctx, data->scratch, &data->output[iter], data->includes_g ? &data->scalars[data->offset1] : NULL, bench_ecmult_multi_callback, arg, count - includes_g);
210+
data->ecmult_multi(&data->ctx->error_callback, data->scratch, &data->output[iter], data->includes_g ? &data->scalars[data->offset1] : NULL, bench_ecmult_multi_callback, arg, count - includes_g);
211211
data->offset1 = (data->offset1 + count) % POINTS;
212212
data->offset2 = (data->offset2 + count - 1) % POINTS;
213213
}
@@ -266,7 +266,7 @@ static void run_ecmult_multi_bench(bench_data* data, size_t count, int includes_
266266
secp256k1_scalar_add(&total, &total, &tmp);
267267
}
268268
secp256k1_scalar_negate(&total, &total);
269-
secp256k1_ecmult(&data->ctx->ecmult_ctx, &data->expected_output[iter], NULL, &zero, &total);
269+
secp256k1_ecmult(&data->expected_output[iter], NULL, &zero, &total);
270270
}
271271

272272
/* Run the benchmark. */

src/ecdsa.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size);
1717
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s);
18-
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message);
18+
static int secp256k1_ecdsa_sig_verify(const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message);
1919
static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid);
2020

2121
#endif /* SECP256K1_ECDSA_H */

src/ecdsa_impl.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const
204204
return 1;
205205
}
206206

207-
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) {
207+
static int secp256k1_ecdsa_sig_verify(const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) {
208208
unsigned char c[32];
209209
secp256k1_scalar sn, u1, u2;
210210
#if !defined(EXHAUSTIVE_TEST_ORDER)
@@ -221,7 +221,7 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const
221221
secp256k1_scalar_mul(&u1, &sn, message);
222222
secp256k1_scalar_mul(&u2, &sn, sigr);
223223
secp256k1_gej_set_ge(&pubkeyj, pubkey);
224-
secp256k1_ecmult(ctx, &pr, &pubkeyj, &u2, &u1);
224+
secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1);
225225
if (secp256k1_gej_is_infinity(&pr)) {
226226
return 0;
227227
}

src/eckey.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char
1818
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed);
1919

2020
static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak);
21-
static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak);
21+
static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge *key, const secp256k1_scalar *tweak);
2222
static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak);
23-
static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak);
23+
static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge *key, const secp256k1_scalar *tweak);
2424

2525
#endif /* SECP256K1_ECKEY_H */

src/eckey_impl.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp25
5757
return !secp256k1_scalar_is_zero(key);
5858
}
5959

60-
static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) {
60+
static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge *key, const secp256k1_scalar *tweak) {
6161
secp256k1_gej pt;
6262
secp256k1_scalar one;
6363
secp256k1_gej_set_ge(&pt, key);
6464
secp256k1_scalar_set_int(&one, 1);
65-
secp256k1_ecmult(ctx, &pt, &pt, &one, tweak);
65+
secp256k1_ecmult(&pt, &pt, &one, tweak);
6666

6767
if (secp256k1_gej_is_infinity(&pt)) {
6868
return 0;
@@ -79,7 +79,7 @@ static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp25
7979
return ret;
8080
}
8181

82-
static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) {
82+
static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge *key, const secp256k1_scalar *tweak) {
8383
secp256k1_scalar zero;
8484
secp256k1_gej pt;
8585
if (secp256k1_scalar_is_zero(tweak)) {
@@ -88,7 +88,7 @@ static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx,
8888

8989
secp256k1_scalar_set_int(&zero, 0);
9090
secp256k1_gej_set_ge(&pt, key);
91-
secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero);
91+
secp256k1_ecmult(&pt, &pt, tweak, &zero);
9292
secp256k1_ge_set_gej(key, &pt);
9393
return 1;
9494
}

src/ecmult.h

+19-13
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,26 @@
1111
#include "scalar.h"
1212
#include "scratch.h"
1313

14-
typedef struct {
15-
/* For accelerating the computation of a*P + b*G: */
16-
secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */
17-
secp256k1_ge_storage (*pre_g_128)[]; /* odd multiples of 2^128*generator */
18-
} secp256k1_ecmult_context;
19-
20-
static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx);
21-
static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, void **prealloc);
22-
static void secp256k1_ecmult_context_finalize_memcpy(secp256k1_ecmult_context *dst, const secp256k1_ecmult_context *src);
23-
static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx);
24-
static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx);
14+
/* Noone will ever need more than a window size of 24. The code might
15+
* be correct for larger values of ECMULT_WINDOW_SIZE but this is not
16+
* tested.
17+
*
18+
* The following limitations are known, and there are probably more:
19+
* If WINDOW_G > 27 and size_t has 32 bits, then the code is incorrect
20+
* because the size of the memory object that we allocate (in bytes)
21+
* will not fit in a size_t.
22+
* If WINDOW_G > 31 and int has 32 bits, then the code is incorrect
23+
* because certain expressions will overflow.
24+
*/
25+
#if ECMULT_WINDOW_SIZE < 2 || ECMULT_WINDOW_SIZE > 24
26+
# error Set ECMULT_WINDOW_SIZE to an integer in range [2..24].
27+
#endif
28+
29+
/** The number of entries a table with precomputed multiples needs to have. */
30+
#define ECMULT_TABLE_SIZE(w) (1L << ((w)-2))
2531

2632
/** Double multiply: R = na*A + ng*G */
27-
static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng);
33+
static void secp256k1_ecmult(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng);
2834

2935
typedef int (secp256k1_ecmult_multi_callback)(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data);
3036

@@ -39,6 +45,6 @@ typedef int (secp256k1_ecmult_multi_callback)(secp256k1_scalar *sc, secp256k1_ge
3945
* 0 if there is not enough scratch space for a single point or
4046
* callback returns 0
4147
*/
42-
static int secp256k1_ecmult_multi_var(const secp256k1_callback* error_callback, const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n);
48+
static int secp256k1_ecmult_multi_var(const secp256k1_callback* error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n);
4349

4450
#endif /* SECP256K1_ECMULT_H */

0 commit comments

Comments
 (0)