Skip to content

Commit 36698dc

Browse files
committed
Merge #596: Make WINDOW_G configurable
a61a93f Clean up ./configure help strings (Tim Ruffing) 2842dc5 Make WINDOW_G configurable (Tim Ruffing) Pull request description: This makes WINDOW_G a configurable value in the range of [2..24]. The upper limit of 24 is a defensive choice. The code is probably correct for values up to 33 but those larger values yield in huge tables (>= 256MiB), which are i) unlikely to be really beneficial in practice and ii) increasingly difficult to test. The main point of this is not to make the window size configurable (using ./configure) but rather to use an external #define for the window size, which makes it configurable for embedded system that rely on their own build system (like in #595). ACKs for commit a61a93: Tree-SHA512: 0d58fdf4763340ddab992e95f6302a33d891476a7ac1748202ee99808e72b20754bb6935cbeaf0bb36077abaaff7d65f4848b1af64f1a0a5258239ba0d27020c
2 parents 1a02d6c + a61a93f commit 36698dc

File tree

3 files changed

+85
-28
lines changed

3 files changed

+85
-28
lines changed

configure.ac

+47-15
Original file line numberDiff line numberDiff line change
@@ -85,42 +85,42 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])],
8585
])
8686

8787
AC_ARG_ENABLE(benchmark,
88-
AS_HELP_STRING([--enable-benchmark],[compile benchmark (default is yes)]),
88+
AS_HELP_STRING([--enable-benchmark],[compile benchmark [default=yes]]),
8989
[use_benchmark=$enableval],
9090
[use_benchmark=yes])
9191

9292
AC_ARG_ENABLE(coverage,
93-
AS_HELP_STRING([--enable-coverage],[enable compiler flags to support kcov coverage analysis]),
93+
AS_HELP_STRING([--enable-coverage],[enable compiler flags to support kcov coverage analysis [default=no]]),
9494
[enable_coverage=$enableval],
9595
[enable_coverage=no])
9696

9797
AC_ARG_ENABLE(tests,
98-
AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]),
98+
AS_HELP_STRING([--enable-tests],[compile tests [default=yes]]),
9999
[use_tests=$enableval],
100100
[use_tests=yes])
101101

102102
AC_ARG_ENABLE(openssl_tests,
103-
AS_HELP_STRING([--enable-openssl-tests],[enable OpenSSL tests, if OpenSSL is available (default is auto)]),
103+
AS_HELP_STRING([--enable-openssl-tests],[enable OpenSSL tests [default=auto]]),
104104
[enable_openssl_tests=$enableval],
105105
[enable_openssl_tests=auto])
106106

107107
AC_ARG_ENABLE(experimental,
108-
AS_HELP_STRING([--enable-experimental],[allow experimental configure options (default is no)]),
108+
AS_HELP_STRING([--enable-experimental],[allow experimental configure options [default=no]]),
109109
[use_experimental=$enableval],
110110
[use_experimental=no])
111111

112112
AC_ARG_ENABLE(exhaustive_tests,
113-
AS_HELP_STRING([--enable-exhaustive-tests],[compile exhaustive tests (default is yes)]),
113+
AS_HELP_STRING([--enable-exhaustive-tests],[compile exhaustive tests [default=yes]]),
114114
[use_exhaustive_tests=$enableval],
115115
[use_exhaustive_tests=yes])
116116

117117
AC_ARG_ENABLE(endomorphism,
118-
AS_HELP_STRING([--enable-endomorphism],[enable endomorphism (default is no)]),
118+
AS_HELP_STRING([--enable-endomorphism],[enable endomorphism [default=no]]),
119119
[use_endomorphism=$enableval],
120120
[use_endomorphism=no])
121121

122122
AC_ARG_ENABLE(ecmult_static_precomputation,
123-
AS_HELP_STRING([--enable-ecmult-static-precomputation],[enable precomputed ecmult table for signing (default is yes)]),
123+
AS_HELP_STRING([--enable-ecmult-static-precomputation],[enable precomputed ecmult table for signing [default=auto]]),
124124
[use_ecmult_static_precomputation=$enableval],
125125
[use_ecmult_static_precomputation=auto])
126126

@@ -130,26 +130,35 @@ AC_ARG_ENABLE(module_ecdh,
130130
[enable_module_ecdh=no])
131131

132132
AC_ARG_ENABLE(module_recovery,
133-
AS_HELP_STRING([--enable-module-recovery],[enable ECDSA pubkey recovery module (default is no)]),
133+
AS_HELP_STRING([--enable-module-recovery],[enable ECDSA pubkey recovery module [default=no]]),
134134
[enable_module_recovery=$enableval],
135135
[enable_module_recovery=no])
136136

137137
AC_ARG_ENABLE(jni,
138-
AS_HELP_STRING([--enable-jni],[enable libsecp256k1_jni (default is no)]),
138+
AS_HELP_STRING([--enable-jni],[enable libsecp256k1_jni [default=no]]),
139139
[use_jni=$enableval],
140140
[use_jni=no])
141141

142142
AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto],
143-
[Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto])
143+
[finite field implementation to use [default=auto]])],[req_field=$withval], [req_field=auto])
144144

145145
AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|no|auto],
146-
[Specify Bignum Implementation. Default is auto])],[req_bignum=$withval], [req_bignum=auto])
146+
[bignum implementation to use [default=auto]])],[req_bignum=$withval], [req_bignum=auto])
147147

148148
AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto],
149-
[Specify scalar implementation. Default is auto])],[req_scalar=$withval], [req_scalar=auto])
149+
[scalar implementation to use [default=auto]])],[req_scalar=$withval], [req_scalar=auto])
150150

151-
AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm|no|auto]
152-
[Specify assembly optimizations to use. Default is auto (experimental: arm)])],[req_asm=$withval], [req_asm=auto])
151+
AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm|no|auto],
152+
[assembly optimizations to use (experimental: arm) [default=auto]])],[req_asm=$withval], [req_asm=auto])
153+
154+
AC_ARG_WITH([ecmult-window], [AS_HELP_STRING([--with-ecmult-window=SIZE|auto],
155+
[window size for ecmult precomputation for verification, specified as integer in range [2..24].]
156+
[Larger values result in possibly better performance at the cost of an exponentially larger precomputed table.]
157+
[The table will store 2^(SIZE-2) * 64 bytes of data but can be larger in memory due to platform-specific padding and alignment.]
158+
[If the endomorphism optimization is enabled, two tables of this size are used instead of only one.]
159+
["auto" is a reasonable setting for desktop machines (currently 15). [default=auto]]
160+
)],
161+
[req_ecmult_window=$withval], [req_ecmult_window=auto])
153162

154163
AC_CHECK_TYPES([__int128])
155164

@@ -387,6 +396,28 @@ case $set_scalar in
387396
;;
388397
esac
389398

399+
#set ecmult window size
400+
if test x"$req_ecmult_window" = x"auto"; then
401+
set_ecmult_window=15
402+
else
403+
set_ecmult_window=$req_ecmult_window
404+
fi
405+
406+
error_window_size=['window size for ecmult precomputation not an integer in range [2..24] or "auto"']
407+
case $set_ecmult_window in
408+
''|*[[!0-9]]*)
409+
# no valid integer
410+
AC_MSG_ERROR($error_window_size)
411+
;;
412+
*)
413+
if test "$set_ecmult_window" -lt 2 -o "$set_ecmult_window" -gt 24 ; then
414+
# not in range
415+
AC_MSG_ERROR($error_window_size)
416+
fi
417+
AC_DEFINE_UNQUOTED(ECMULT_WINDOW_SIZE, $set_ecmult_window, [Set window size for ecmult precomputation])
418+
;;
419+
esac
420+
390421
if test x"$use_tests" = x"yes"; then
391422
SECP_OPENSSL_CHECK
392423
if test x"$has_openssl_ec" = x"yes"; then
@@ -516,6 +547,7 @@ echo " asm = $set_asm"
516547
echo " bignum = $set_bignum"
517548
echo " field = $set_field"
518549
echo " scalar = $set_scalar"
550+
echo " ecmult window size = $set_ecmult_window"
519551
echo
520552
echo " CC = $CC"
521553
echo " CFLAGS = $CFLAGS"

src/basic-config.h

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#define USE_SCALAR_INV_BUILTIN 1
2929
#define USE_FIELD_10X26 1
3030
#define USE_SCALAR_8X32 1
31+
#define ECMULT_WINDOW_SIZE 15
3132

3233
#endif /* USE_BASIC_CONFIG */
3334

src/ecmult_impl.h

+37-13
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,32 @@
3030
# endif
3131
#else
3232
/* optimal for 128-bit and 256-bit exponents. */
33-
#define WINDOW_A 5
34-
/** larger numbers may result in slightly better performance, at the cost of
35-
exponentially larger precomputed tables. */
36-
#ifdef USE_ENDOMORPHISM
37-
/** Two tables for window size 15: 1.375 MiB. */
38-
#define WINDOW_G 15
39-
#else
40-
/** One table for window size 16: 1.375 MiB. */
41-
#define WINDOW_G 16
33+
# define WINDOW_A 5
34+
/** Larger values for ECMULT_WINDOW_SIZE result in possibly better
35+
* performance at the cost of an exponentially larger precomputed
36+
* table. The exact table size is
37+
* (1 << (WINDOW_G - 2)) * sizeof(secp256k1_ge_storage) bytes,
38+
* where sizeof(secp256k1_ge_storage) is typically 64 bytes but can
39+
* be larger due to platform-specific padding and alignment.
40+
* If the endomorphism optimization is enabled (USE_ENDOMORMPHSIM)
41+
* two tables of this size are used instead of only one.
42+
*/
43+
# define WINDOW_G ECMULT_WINDOW_SIZE
4244
#endif
45+
46+
/* Noone will ever need more than a window size of 24. The code might
47+
* be correct for larger values of ECMULT_WINDOW_SIZE but this is not
48+
* not tested.
49+
*
50+
* The following limitations are known, and there are probably more:
51+
* If WINDOW_G > 27 and size_t has 32 bits, then the code is incorrect
52+
* because the size of the memory object that we allocate (in bytes)
53+
* will not fit in a size_t.
54+
* If WINDOW_G > 31 and int has 32 bits, then the code is incorrect
55+
* because certain expressions will overflow.
56+
*/
57+
#if ECMULT_WINDOW_SIZE < 2 || ECMULT_WINDOW_SIZE > 24
58+
# error Set ECMULT_WINDOW_SIZE to an integer in range [2..24].
4359
#endif
4460

4561
#ifdef USE_ENDOMORPHISM
@@ -311,7 +327,12 @@ static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const
311327
/* get the generator */
312328
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
313329

314-
ctx->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
330+
{
331+
size_t size = sizeof((*ctx->pre_g)[0]) * ((size_t)ECMULT_TABLE_SIZE(WINDOW_G));
332+
/* check for overflow */
333+
VERIFY_CHECK(size / sizeof((*ctx->pre_g)[0]) == ((size_t)ECMULT_TABLE_SIZE(WINDOW_G)));
334+
ctx->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, size);
335+
}
315336

316337
/* precompute the tables with odd multiples */
317338
secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g, &gj);
@@ -321,7 +342,10 @@ static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const
321342
secp256k1_gej g_128j;
322343
int i;
323344

324-
ctx->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
345+
size_t size = sizeof((*ctx->pre_g_128)[0]) * ((size_t) ECMULT_TABLE_SIZE(WINDOW_G));
346+
/* check for overflow */
347+
VERIFY_CHECK(size / sizeof((*ctx->pre_g_128)[0]) == ((size_t)ECMULT_TABLE_SIZE(WINDOW_G)));
348+
ctx->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, size);
325349

326350
/* calculate 2^128*generator */
327351
g_128j = gj;
@@ -338,15 +362,15 @@ static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst,
338362
if (src->pre_g == NULL) {
339363
dst->pre_g = NULL;
340364
} else {
341-
size_t size = sizeof((*dst->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G);
365+
size_t size = sizeof((*dst->pre_g)[0]) * ((size_t)ECMULT_TABLE_SIZE(WINDOW_G));
342366
dst->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, size);
343367
memcpy(dst->pre_g, src->pre_g, size);
344368
}
345369
#ifdef USE_ENDOMORPHISM
346370
if (src->pre_g_128 == NULL) {
347371
dst->pre_g_128 = NULL;
348372
} else {
349-
size_t size = sizeof((*dst->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G);
373+
size_t size = sizeof((*dst->pre_g_128)[0]) * ((size_t)ECMULT_TABLE_SIZE(WINDOW_G));
350374
dst->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, size);
351375
memcpy(dst->pre_g_128, src->pre_g_128, size);
352376
}

0 commit comments

Comments
 (0)