Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a static constant table for small ecmult WINDOW_G sizes. #614

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions src/ecmult_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,77 @@
#define ECMULT_MAX_POINTS_PER_BATCH 10000000
#endif

#ifndef STATIC_WINDOW_G
# ifndef EXHAUSTIVE_TEST_ORDER
# if ECMULT_WINDOW_SIZE <= 6
# define STATIC_WINDOW_G
# endif
# endif
#endif

#ifdef STATIC_WINDOW_G
static const secp256k1_ge_storage secp256k1_pre_g_static_context[ECMULT_TABLE_SIZE(WINDOW_G)] = {
SECP256K1_GE_STORAGE_CONST(2042521214u, 4191992748u, 1436574357u, 3464956679u, 43777243u, 768485593u, 1509065051u, 385357720u, 1211816567u, 648266853u, 1571093500u, 235997352u, 4246189128u, 2793755673u, 2621952143u, 4212184248u),
#if ECMULT_TABLE_SIZE(WINDOW_G) > 1
SECP256K1_GE_STORAGE_CONST(4180707841u, 2455290640u, 1228164997u, 4171059753u, 3039938629u, 2205129136u, 2248274195u, 3168810745u, 948927247u, 1663952916u, 266549222u, 708309846u, 1694542233u, 885138203u, 1824128373u, 2226710130u),
#if ECMULT_TABLE_SIZE(WINDOW_G) > 2
SECP256K1_GE_STORAGE_CONST(797695565u, 436674707u, 1437902629u, 173822248u, 3901457597u, 3697384119u, 3416839529u, 2990600164u, 3635159590u, 921035734u, 3571165661u, 2798240806u, 4152895259u, 2869782592u, 3702029626u, 2796315350u),
SECP256K1_GE_STORAGE_CONST(1555951716u, 1851634922u, 2744709989u, 4075452942u, 1027709822u, 53535644u, 3911966189u, 3401906620u, 1793837632u, 3123009888u, 2736229741u, 2249872603u, 2819870904u, 335407029u, 2768774696u, 141714650u),
#if ECMULT_TABLE_SIZE(WINDOW_G) > 4
SECP256K1_GE_STORAGE_CONST(2899608802u, 4039636563u, 162338698u, 2673187517u, 3768030871u, 1280829204u, 3277787405u, 4230466750u, 3425929505u, 2963790333u, 1681394033u, 1983603177u, 2916649124u, 929009167u, 97265194u, 3327106103u),
SECP256K1_GE_STORAGE_CONST(2001397752u, 1487487262u, 1593058411u, 1892047532u, 1447663627u, 3854661777u, 3152811913u, 1570769099u, 3649347634u, 3949682201u, 38002006u, 3619140453u, 925741538u, 3757692584u, 807236809u, 3377710619u),
SECP256K1_GE_STORAGE_CONST(4068963266u, 3648333963u, 3352416773u, 3279193681u, 2960522182u, 1628330189u, 3740131215u, 423647912u, 179343406u, 2374503049u, 1971458795u, 1707978567u, 974784218u, 1377806623u, 699779922u, 3674467713u),
SECP256K1_GE_STORAGE_CONST(3616689487u, 2101602966u, 1514560227u, 157283345u, 837129327u, 1015412638u, 1152236792u, 3799910414u, 1478371442u, 2825679526u, 2206478018u, 684486127u, 3930107691u, 3633763237u, 3305430175u, 4137839448u),
#if ECMULT_TABLE_SIZE(WINDOW_G) > 8
SECP256K1_GE_STORAGE_CONST(3741182540u, 3680991056u, 2753625832u, 132828961u, 3952646318u, 2042197639u, 1726282400u, 1244482100u, 1108454150u, 2489536872u, 3919032554u, 3534306734u, 3469866144u, 1251328246u, 3484522998u, 2656496503u),
SECP256K1_GE_STORAGE_CONST(726573223u, 2544124882u, 2481937663u, 1146046841u, 4033531883u, 3622333735u, 1953850721u, 943217516u, 2246613952u, 932470163u, 3007514683u, 1511818771u, 436336140u, 1344706403u, 3044067412u, 3854605178u),
SECP256K1_GE_STORAGE_CONST(892059466u, 1289556566u, 1335097907u, 753087280u, 496686082u, 1912082545u, 2167671535u, 633231829u, 840872967u, 1397290292u, 3583776805u, 2648325663u, 1243298606u, 1907426204u, 1740455307u, 3481377164u),
SECP256K1_GE_STORAGE_CONST(799150157u, 1798885659u, 36700421u, 1502056740u, 3828005087u, 4025876265u, 3701267165u, 1321913407u, 48107624u, 694016101u, 3058002227u, 1540742528u, 404582636u, 4236781128u, 1111205739u, 1395359079u),
SECP256K1_GE_STORAGE_CONST(2454202267u, 162846349u, 2871110064u, 1726864003u, 641482116u, 3767890658u, 1774849239u, 4114954004u, 1929473915u, 4063537886u, 1562027803u, 3735204351u, 1069604394u, 2289636095u, 3846845134u, 2546676738u),
SECP256K1_GE_STORAGE_CONST(3672985387u, 3819487015u, 2389709615u, 2965288786u, 794234388u, 1274418624u, 2123984196u, 1039042345u, 2795359818u, 2104269032u, 3567365288u, 2130237184u, 1065599536u, 4088375078u, 2873156898u, 2428378197u),
SECP256K1_GE_STORAGE_CONST(3293385415u, 106791214u, 2328832215u, 3417415568u, 300734953u, 4260528560u, 3869488616u, 2099439579u, 555328608u, 3459411164u, 1992579366u, 3380805036u, 235957894u, 517956037u, 2688091711u, 235824258u),
SECP256K1_GE_STORAGE_CONST(1780767734u, 3697902852u, 3365544143u, 3738568787u, 355166547u, 918716515u, 3055314379u, 3530155700u, 3760377666u, 3267185264u, 2336182566u, 4050265261u, 2335423048u, 3494001518u, 4250821448u, 269322882u),
#if ECMULT_TABLE_SIZE(WINDOW_G) > 16
# error "ECMULT_WINDOW_SIZE > 6 and not enough static table data."
#endif
#endif /*ECMULT_TABLE_SIZE(WINDOW_G) > 8*/
#endif /*ECMULT_TABLE_SIZE(WINDOW_G) > 4*/
#endif /*ECMULT_TABLE_SIZE(WINDOW_G) > 2*/
#endif /*ECMULT_TABLE_SIZE(WINDOW_G) > 1*/
};
#ifdef USE_ENDOMORPHISM
static const secp256k1_ge_storage secp256k1_pre_g_128_static_context[ECMULT_TABLE_SIZE(WINDOW_G)] = {
SECP256K1_GE_STORAGE_CONST(2406005202u, 4131086131u, 2453258669u, 2552174126u, 3901511288u, 1916707637u, 461063244u, 2663694554u, 1714069293u, 3120970118u, 3726479554u, 3065913693u, 3152686334u, 2505116669u, 4064067449u, 1344274306u),
#if ECMULT_TABLE_SIZE(WINDOW_G) > 1
SECP256K1_GE_STORAGE_CONST(943201726u, 777035554u, 2343121763u, 4064616200u, 4253310131u, 1373197502u, 417511661u, 3526887930u, 3835899146u, 263788508u, 2962490789u, 1376694732u, 914488523u, 853078605u, 3178263832u, 857730386u),
#if ECMULT_TABLE_SIZE(WINDOW_G) > 2
SECP256K1_GE_STORAGE_CONST(1227237156u, 3828820710u, 4136770434u, 2856753569u, 4052135589u, 1074931248u, 1050945096u, 2546115344u, 322430835u, 3165105145u, 1512897110u, 2534682683u, 1830172178u, 2808084686u, 205633153u, 1579671248u),
SECP256K1_GE_STORAGE_CONST(3808843404u, 438570128u, 3588379571u, 3833062136u, 1305221718u, 4278639501u, 327463033u, 3468504369u, 246181859u, 2022916704u, 2291084048u, 2138901942u, 4290543682u, 3191289894u, 1764442243u, 2455006788u),
#if ECMULT_TABLE_SIZE(WINDOW_G) > 4
SECP256K1_GE_STORAGE_CONST(1000214542u, 606654204u, 656084598u, 603706931u, 1961621721u, 2863930841u, 3308307358u, 909194928u, 4210792469u, 756464497u, 3742708715u, 2403818278u, 2729322659u, 986914689u, 2503917935u, 1826339978u),
SECP256K1_GE_STORAGE_CONST(3138039113u, 1898629545u, 729205376u, 4125023991u, 399116136u, 2164768494u, 2517168199u, 793271615u, 3932789843u, 3313718393u, 2395807775u, 1922554420u, 2304400122u, 828836863u, 3885208144u, 1017313653u),
SECP256K1_GE_STORAGE_CONST(2030635720u, 3840867520u, 3572034329u, 2063466771u, 3789917005u, 2953913310u, 1257165626u, 913411529u, 3937104427u, 2442156943u, 332928715u, 3449465430u, 3711348663u, 195625099u, 2519933617u, 486205381u),
SECP256K1_GE_STORAGE_CONST(3883696557u, 3925441365u, 470014908u, 3846814310u, 2379685351u, 3447151314u, 2724817228u, 2137049041u, 986649720u, 4009235233u, 3321641778u, 1051202883u, 1662284023u, 472483539u, 1321566706u, 2195137609u),
#if ECMULT_TABLE_SIZE(WINDOW_G) > 8
SECP256K1_GE_STORAGE_CONST(3727383785u, 3687731484u, 4074276750u, 1038976972u, 1029914030u, 2731823937u, 1344254884u, 1439495856u, 4043667187u, 3552829665u, 3153532905u, 2333751108u, 1706607706u, 3328383163u, 880975543u, 286262886u),
SECP256K1_GE_STORAGE_CONST(3497778687u, 3566314238u, 514170813u, 2081559063u, 694525093u, 3729155467u, 649152011u, 331365462u, 2997700360u, 3443300317u, 261898466u, 2715682005u, 1641636863u, 2361585319u, 1810101772u, 725638375u),
SECP256K1_GE_STORAGE_CONST(2185248380u, 1563432623u, 929426508u, 963438817u, 260940892u, 1129022039u, 284011329u, 3144306001u, 218719771u, 3799824231u, 1146534621u, 3018342481u, 2578148556u, 1321630747u, 300494509u, 2068200217u),
SECP256K1_GE_STORAGE_CONST(3940299057u, 4225115893u, 641706584u, 3301635289u, 2467271485u, 2504114751u, 1133294726u, 1963360463u, 3553195953u, 3384060055u, 1550103404u, 2536332545u, 2743663517u, 3279493748u, 906579953u, 747088148u),
SECP256K1_GE_STORAGE_CONST(956558943u, 1733885732u, 3306726579u, 2255785807u, 918410844u, 3078518956u, 1621043465u, 4235823065u, 244455758u, 2706522582u, 1083267380u, 3173205833u, 2367826456u, 1227335898u, 2966413998u, 405530683u),
SECP256K1_GE_STORAGE_CONST(3498064760u, 967526563u, 2222308812u, 4188664345u, 1465500483u, 3686764179u, 602011778u, 1541842393u, 751022464u, 4280928638u, 2704195935u, 3012276132u, 82636908u, 3843890468u, 680831270u, 1683500811u),
SECP256K1_GE_STORAGE_CONST(525791382u, 2978641049u, 2706613678u, 2901982725u, 2224479523u, 3666766873u, 559294715u, 3226894032u, 4277283722u, 995292304u, 2197832758u, 191221097u, 3376515572u, 445890773u, 532757684u, 933101400u),
SECP256K1_GE_STORAGE_CONST(496986545u, 2762241074u, 3817272613u, 37005872u, 2045331407u, 3474993815u, 1309655131u, 1670259003u, 3633900567u, 2493253473u, 3011838147u, 2729564708u, 1413010867u, 3556177696u, 1106337134u, 3839151291u),
#if ECMULT_TABLE_SIZE(WINDOW_G) > 16
# error "ECMULT_WINDOW_SIZE > 6 and not enough static table data."
#endif
#endif /*ECMULT_TABLE_SIZE(WINDOW_G) > 8*/
#endif /*ECMULT_TABLE_SIZE(WINDOW_G) > 4*/
#endif /*ECMULT_TABLE_SIZE(WINDOW_G) > 2*/
#endif /*ECMULT_TABLE_SIZE(WINDOW_G) > 1*/
};
#endif /*USE_ENDOMORPHISM*/
#endif /*STATIC_WINDOW_G*/

/** Fill a table 'prej' with precomputed odd multiples of a. Prej will contain
* the values [1*a,3*a,...,(2*n-1)*a], so it space for n values. zr[0] will
* contain prej[0].z / a.z. The other zr[i] values = prej[i].z / prej[i-1].z.
Expand Down Expand Up @@ -154,6 +225,7 @@ static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge *p
secp256k1_ge_globalz_set_table_gej(ECMULT_TABLE_SIZE(WINDOW_A), pre, globalz, prej, zr);
}

#ifndef STATIC_WINDOW_G
static void secp256k1_ecmult_odd_multiples_table_storage_var(const int n, secp256k1_ge_storage *pre, const secp256k1_gej *a) {
secp256k1_gej d;
secp256k1_ge d_ge, p_ge;
Expand Down Expand Up @@ -284,6 +356,7 @@ static void secp256k1_ecmult_odd_multiples_table_storage_var(const int n, secp25
secp256k1_ge_to_storage(&pre[i], &p_ge);
}
}
#endif

/** The following two macro retrieves a particular odd multiple from a table
* of precomputed multiples. */
Expand Down Expand Up @@ -311,12 +384,16 @@ static void secp256k1_ecmult_odd_multiples_table_storage_var(const int n, secp25
} \
} while(0)

#ifndef STATIC_WINDOW_G
static const size_t SECP256K1_ECMULT_CONTEXT_PREALLOCATED_SIZE =
ROUND_TO_ALIGN(sizeof((*((secp256k1_ecmult_context*) NULL)->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G))
#ifdef USE_ENDOMORPHISM
+ ROUND_TO_ALIGN(sizeof((*((secp256k1_ecmult_context*) NULL)->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G))
#endif
;
#else
static const size_t SECP256K1_ECMULT_CONTEXT_PREALLOCATED_SIZE = 0;
#endif

static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx) {
ctx->pre_g = NULL;
Expand All @@ -326,6 +403,16 @@ static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx) {
}

static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, void **prealloc) {
#ifdef STATIC_WINDOW_G
(void)prealloc;
if (ctx->pre_g != NULL) {
return;
}
ctx->pre_g = (secp256k1_ge_storage (*)[ECMULT_TABLE_SIZE(WINDOW_G)])secp256k1_pre_g_static_context;
#ifdef USE_ENDOMORPHISM
ctx->pre_g_128 = (secp256k1_ge_storage (*)[ECMULT_TABLE_SIZE(WINDOW_G)])secp256k1_pre_g_128_static_context;
#endif
#else
secp256k1_gej gj;
void* const base = *prealloc;
size_t const prealloc_size = SECP256K1_ECMULT_CONTEXT_PREALLOCATED_SIZE;
Expand Down Expand Up @@ -365,20 +452,30 @@ static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, void *
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_finalize_memcpy(secp256k1_ecmult_context *dst, const secp256k1_ecmult_context *src) {
if (src->pre_g != NULL) {
/* We cast to void* first to suppress a -Wcast-align warning. */
#ifdef STATIC_WINDOW_G
dst->pre_g = (secp256k1_ge_storage (*)[ECMULT_TABLE_SIZE(WINDOW_G)])secp256k1_pre_g_static_context;
#else
dst->pre_g = (secp256k1_ge_storage (*)[])(void*)((unsigned char*)dst + ((unsigned char*)(src->pre_g) - (unsigned char*)src));
#endif
}
#ifdef USE_ENDOMORPHISM
if (src->pre_g_128 != NULL) {
#ifdef STATIC_WINDOW_G
dst->pre_g_128 = (secp256k1_ge_storage (*)[ECMULT_TABLE_SIZE(WINDOW_G)])secp256k1_pre_g_128_static_context;
#else
dst->pre_g_128 = (secp256k1_ge_storage (*)[])(void*)((unsigned char*)dst + ((unsigned char*)(src->pre_g_128) - (unsigned char*)src));
#endif
}
#endif
}


static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx) {
return ctx->pre_g != NULL;
}
Expand Down
1 change: 1 addition & 0 deletions src/tests_exhaustive.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <time.h>

#undef USE_ECMULT_STATIC_PRECOMPUTATION
#undef STATIC_WINDOW_G

#ifndef EXHAUSTIVE_TEST_ORDER
/* see group_impl.h for allowable values */
Expand Down