From 462a3351a16a8fa7f22756413e931a24c6569baf Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Fri, 10 May 2019 00:56:13 +0000 Subject: [PATCH] Use a static constant table for small ecmult WINDOW_G sizes. --- src/ecmult_impl.h | 97 ++++++++++++++++++++++++++++++++++++++++++ src/tests_exhaustive.c | 1 + 2 files changed, 98 insertions(+) diff --git a/src/ecmult_impl.h b/src/ecmult_impl.h index bb7adedfb1..d45ed3f0e0 100644 --- a/src/ecmult_impl.h +++ b/src/ecmult_impl.h @@ -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. @@ -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; @@ -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. */ @@ -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; @@ -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; @@ -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; } diff --git a/src/tests_exhaustive.c b/src/tests_exhaustive.c index b44e357cb6..d6e80bcaff 100644 --- a/src/tests_exhaustive.c +++ b/src/tests_exhaustive.c @@ -14,6 +14,7 @@ #include #undef USE_ECMULT_STATIC_PRECOMPUTATION +#undef STATIC_WINDOW_G #ifndef EXHAUSTIVE_TEST_ORDER /* see group_impl.h for allowable values */