Make WINDOW_G configurable
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 27 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.
This commit is contained in:
parent
1a02d6ce51
commit
2842dc523e
32
configure.ac
32
configure.ac
|
@ -151,6 +151,15 @@ AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto],
|
||||||
AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm|no|auto]
|
AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm|no|auto]
|
||||||
[Specify assembly optimizations to use. Default is auto (experimental: arm)])],[req_asm=$withval], [req_asm=auto])
|
[Specify assembly optimizations to use. Default is auto (experimental: arm)])],[req_asm=$withval], [req_asm=auto])
|
||||||
|
|
||||||
|
AC_ARG_WITH([ecmult-window], [AS_HELP_STRING([--with-ecmult-window=SIZE|auto],
|
||||||
|
[window size for ecmult precomputation for verification, specified as integer in range [2..24].]
|
||||||
|
[Larger values result in possibly better performance at the cost of an exponentially larger precomputed table.]
|
||||||
|
[The table will store 2^(SIZE-2) * 64 bytes of data but can be larger in memory due to platform-specific padding and alignment.]
|
||||||
|
[If the endomorphism optimization is enabled, two tables of this size are used instead of only one.]
|
||||||
|
["auto" is a reasonable setting for desktop machines (currently 15). [default=auto]]
|
||||||
|
)],
|
||||||
|
[req_ecmult_window=$withval], [req_ecmult_window=auto])
|
||||||
|
|
||||||
AC_CHECK_TYPES([__int128])
|
AC_CHECK_TYPES([__int128])
|
||||||
|
|
||||||
if test x"$enable_coverage" = x"yes"; then
|
if test x"$enable_coverage" = x"yes"; then
|
||||||
|
@ -387,6 +396,28 @@ case $set_scalar in
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
#set ecmult window size
|
||||||
|
if test x"$req_ecmult_window" = x"auto"; then
|
||||||
|
set_ecmult_window=15
|
||||||
|
else
|
||||||
|
set_ecmult_window=$req_ecmult_window
|
||||||
|
fi
|
||||||
|
|
||||||
|
error_window_size=['window size for ecmult precomputation not an integer in range [2..24] or "auto"']
|
||||||
|
case $set_ecmult_window in
|
||||||
|
''|*[[!0-9]]*)
|
||||||
|
# no valid integer
|
||||||
|
AC_MSG_ERROR($error_window_size)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if test "$set_ecmult_window" -lt 2 -o "$set_ecmult_window" -gt 24 ; then
|
||||||
|
# not in range
|
||||||
|
AC_MSG_ERROR($error_window_size)
|
||||||
|
fi
|
||||||
|
AC_DEFINE_UNQUOTED(ECMULT_WINDOW_SIZE, $set_ecmult_window, [Set window size for ecmult precomputation])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
if test x"$use_tests" = x"yes"; then
|
if test x"$use_tests" = x"yes"; then
|
||||||
SECP_OPENSSL_CHECK
|
SECP_OPENSSL_CHECK
|
||||||
if test x"$has_openssl_ec" = x"yes"; then
|
if test x"$has_openssl_ec" = x"yes"; then
|
||||||
|
@ -516,6 +547,7 @@ echo " asm = $set_asm"
|
||||||
echo " bignum = $set_bignum"
|
echo " bignum = $set_bignum"
|
||||||
echo " field = $set_field"
|
echo " field = $set_field"
|
||||||
echo " scalar = $set_scalar"
|
echo " scalar = $set_scalar"
|
||||||
|
echo " ecmult window size = $set_ecmult_window"
|
||||||
echo
|
echo
|
||||||
echo " CC = $CC"
|
echo " CC = $CC"
|
||||||
echo " CFLAGS = $CFLAGS"
|
echo " CFLAGS = $CFLAGS"
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#define USE_SCALAR_INV_BUILTIN 1
|
#define USE_SCALAR_INV_BUILTIN 1
|
||||||
#define USE_FIELD_10X26 1
|
#define USE_FIELD_10X26 1
|
||||||
#define USE_SCALAR_8X32 1
|
#define USE_SCALAR_8X32 1
|
||||||
|
#define ECMULT_WINDOW_SIZE 15
|
||||||
|
|
||||||
#endif /* USE_BASIC_CONFIG */
|
#endif /* USE_BASIC_CONFIG */
|
||||||
|
|
||||||
|
|
|
@ -30,16 +30,32 @@
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
/* optimal for 128-bit and 256-bit exponents. */
|
/* optimal for 128-bit and 256-bit exponents. */
|
||||||
#define WINDOW_A 5
|
# define WINDOW_A 5
|
||||||
/** larger numbers may result in slightly better performance, at the cost of
|
/** Larger values for ECMULT_WINDOW_SIZE result in possibly better
|
||||||
exponentially larger precomputed tables. */
|
* performance at the cost of an exponentially larger precomputed
|
||||||
#ifdef USE_ENDOMORPHISM
|
* table. The exact table size is
|
||||||
/** Two tables for window size 15: 1.375 MiB. */
|
* (1 << (WINDOW_G - 2)) * sizeof(secp256k1_ge_storage) bytes,
|
||||||
#define WINDOW_G 15
|
* where sizeof(secp256k1_ge_storage) is typically 64 bytes but can
|
||||||
#else
|
* be larger due to platform-specific padding and alignment.
|
||||||
/** One table for window size 16: 1.375 MiB. */
|
* If the endomorphism optimization is enabled (USE_ENDOMORMPHSIM)
|
||||||
#define WINDOW_G 16
|
* two tables of this size are used instead of only one.
|
||||||
|
*/
|
||||||
|
# define WINDOW_G ECMULT_WINDOW_SIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Noone will ever need more than a window size of 24. The code might
|
||||||
|
* be correct for larger values of ECMULT_WINDOW_SIZE but this is not
|
||||||
|
* not tested.
|
||||||
|
*
|
||||||
|
* The following limitations are known, and there are probably more:
|
||||||
|
* If WINDOW_G > 27 and size_t has 32 bits, then the code is incorrect
|
||||||
|
* because the size of the memory object that we allocate (in bytes)
|
||||||
|
* will not fit in a size_t.
|
||||||
|
* If WINDOW_G > 31 and int has 32 bits, then the code is incorrect
|
||||||
|
* because certain expressions will overflow.
|
||||||
|
*/
|
||||||
|
#if ECMULT_WINDOW_SIZE < 2 || ECMULT_WINDOW_SIZE > 24
|
||||||
|
# error Set ECMULT_WINDOW_SIZE to an integer in range [2..24].
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ENDOMORPHISM
|
#ifdef USE_ENDOMORPHISM
|
||||||
|
@ -311,7 +327,12 @@ static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const
|
||||||
/* get the generator */
|
/* get the generator */
|
||||||
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
|
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
|
||||||
|
|
||||||
ctx->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
|
{
|
||||||
|
size_t size = sizeof((*ctx->pre_g)[0]) * ((size_t)ECMULT_TABLE_SIZE(WINDOW_G));
|
||||||
|
/* check for overflow */
|
||||||
|
VERIFY_CHECK(size / sizeof((*ctx->pre_g)[0]) == ((size_t)ECMULT_TABLE_SIZE(WINDOW_G)));
|
||||||
|
ctx->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, size);
|
||||||
|
}
|
||||||
|
|
||||||
/* precompute the tables with odd multiples */
|
/* precompute the tables with odd multiples */
|
||||||
secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g, &gj);
|
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
|
||||||
secp256k1_gej g_128j;
|
secp256k1_gej g_128j;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ctx->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
|
size_t size = sizeof((*ctx->pre_g_128)[0]) * ((size_t) ECMULT_TABLE_SIZE(WINDOW_G));
|
||||||
|
/* check for overflow */
|
||||||
|
VERIFY_CHECK(size / sizeof((*ctx->pre_g_128)[0]) == ((size_t)ECMULT_TABLE_SIZE(WINDOW_G)));
|
||||||
|
ctx->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, size);
|
||||||
|
|
||||||
/* calculate 2^128*generator */
|
/* calculate 2^128*generator */
|
||||||
g_128j = gj;
|
g_128j = gj;
|
||||||
|
@ -338,7 +362,7 @@ static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst,
|
||||||
if (src->pre_g == NULL) {
|
if (src->pre_g == NULL) {
|
||||||
dst->pre_g = NULL;
|
dst->pre_g = NULL;
|
||||||
} else {
|
} else {
|
||||||
size_t size = sizeof((*dst->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G);
|
size_t size = sizeof((*dst->pre_g)[0]) * ((size_t)ECMULT_TABLE_SIZE(WINDOW_G));
|
||||||
dst->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, size);
|
dst->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, size);
|
||||||
memcpy(dst->pre_g, src->pre_g, size);
|
memcpy(dst->pre_g, src->pre_g, size);
|
||||||
}
|
}
|
||||||
|
@ -346,7 +370,7 @@ static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst,
|
||||||
if (src->pre_g_128 == NULL) {
|
if (src->pre_g_128 == NULL) {
|
||||||
dst->pre_g_128 = NULL;
|
dst->pre_g_128 = NULL;
|
||||||
} else {
|
} else {
|
||||||
size_t size = sizeof((*dst->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G);
|
size_t size = sizeof((*dst->pre_g_128)[0]) * ((size_t)ECMULT_TABLE_SIZE(WINDOW_G));
|
||||||
dst->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, size);
|
dst->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, size);
|
||||||
memcpy(dst->pre_g_128, src->pre_g_128, size);
|
memcpy(dst->pre_g_128, src->pre_g_128, size);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue