Changeset View
Changeset View
Standalone View
Standalone View
src/secp256k1/src/ecmult_impl.h
Show All 24 Lines | |||||
# define WINDOW_A 4 | # define WINDOW_A 4 | ||||
# define WINDOW_G 4 | # define WINDOW_G 4 | ||||
# else | # else | ||||
# define WINDOW_A 2 | # define WINDOW_A 2 | ||||
# define WINDOW_G 2 | # define WINDOW_G 2 | ||||
# 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 | |||||
* 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 | ||||
#define WNAF_BITS 128 | #define WNAF_BITS 128 | ||||
#else | #else | ||||
#define WNAF_BITS 256 | #define WNAF_BITS 256 | ||||
#endif | #endif | ||||
#define WNAF_SIZE_BITS(bits, w) (((bits) + (w) - 1) / (w)) | #define WNAF_SIZE_BITS(bits, w) (((bits) + (w) - 1) / (w)) | ||||
▲ Show 20 Lines • Show All 255 Lines • ▼ Show 20 Lines | static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb) { | ||||
if (ctx->pre_g != NULL) { | if (ctx->pre_g != NULL) { | ||||
return; | return; | ||||
} | } | ||||
/* 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); | ||||
#ifdef USE_ENDOMORPHISM | #ifdef USE_ENDOMORPHISM | ||||
{ | { | ||||
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; | ||||
for (i = 0; i < 128; i++) { | for (i = 0; i < 128; i++) { | ||||
secp256k1_gej_double_var(&g_128j, &g_128j, NULL); | secp256k1_gej_double_var(&g_128j, &g_128j, NULL); | ||||
} | } | ||||
secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g_128, &g_128j); | secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g_128, &g_128j); | ||||
} | } | ||||
#endif | #endif | ||||
} | } | ||||
static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, | static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, | ||||
const secp256k1_ecmult_context *src, const secp256k1_callback *cb) { | const secp256k1_ecmult_context *src, const secp256k1_callback *cb) { | ||||
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); | ||||
} | } | ||||
#ifdef USE_ENDOMORPHISM | #ifdef USE_ENDOMORPHISM | ||||
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); | ||||
} | } | ||||
#endif | #endif | ||||
} | } | ||||
static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx) { | static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx) { | ||||
return ctx->pre_g != NULL; | return ctx->pre_g != NULL; | ||||
▲ Show 20 Lines • Show All 826 Lines • Show Last 20 Lines |