Generate ecmult_static_pre_g.h
This header contains a static array that replaces the ecmult_context pre_g and pre_g_128 tables. The gen_ecmult_static_pre_g program generates this header file.
This commit is contained in:
parent
8de2d86a06
commit
16a3cc07e8
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
src/ecmult_static_pre_g.h linguist-generated
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,6 +9,7 @@ bench_internal
|
||||
tests
|
||||
exhaustive_tests
|
||||
gen_context
|
||||
gen_ecmult_static_pre_g
|
||||
valgrind_ctime_test
|
||||
*.exe
|
||||
*.so
|
||||
|
11
Makefile.am
11
Makefile.am
@ -127,12 +127,19 @@ exhaustive_tests_LDFLAGS = -static
|
||||
TESTS += exhaustive_tests
|
||||
endif
|
||||
|
||||
EXTRA_PROGRAMS = gen_ecmult_static_pre_g
|
||||
gen_ecmult_static_pre_g_SOURCES = src/gen_ecmult_static_pre_g.c
|
||||
# See Automake manual, Section "Errors with distclean"
|
||||
src/ecmult_static_pre_g.h:
|
||||
$(MAKE) $(AM_MAKEFLAGS) gen_ecmult_static_pre_g$(EXEEXT)
|
||||
./gen_ecmult_static_pre_g$(EXEEXT)
|
||||
|
||||
if USE_ECMULT_STATIC_PRECOMPUTATION
|
||||
CPPFLAGS_FOR_BUILD +=-I$(top_srcdir) -I$(builddir)/src
|
||||
|
||||
gen_context_OBJECTS = gen_context.o
|
||||
gen_context_BIN = gen_context$(BUILD_EXEEXT)
|
||||
gen_%.o: src/gen_%.c src/libsecp256k1-config.h
|
||||
$(gen_context_OBJECTS): src/gen_context.c src/libsecp256k1-config.h
|
||||
$(CC_FOR_BUILD) $(DEFS) $(CPPFLAGS_FOR_BUILD) $(SECP_CFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@
|
||||
|
||||
$(gen_context_BIN): $(gen_context_OBJECTS)
|
||||
@ -149,7 +156,7 @@ src/ecmult_static_context.h: $(gen_context_BIN)
|
||||
CLEANFILES = $(gen_context_BIN) src/ecmult_static_context.h
|
||||
endif
|
||||
|
||||
EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h
|
||||
EXTRA_DIST = autogen.sh src/gen_context.c src/ecmult_static_pre_g.h src/basic-config.h
|
||||
|
||||
if ENABLE_MODULE_ECDH
|
||||
include src/modules/ecdh/Makefile.am.include
|
||||
|
@ -177,6 +177,8 @@ 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-1) * 64 bytes of data but can be larger in memory due to platform-specific padding and alignment.]
|
||||
[A window size larger than 15 will require you delete the prebuilt ecmult_static_pre_g.h file so that it can be rebuilt.]
|
||||
[For very large window sizes, use "make -j 1" to reduce memory use during compilation.]
|
||||
["auto" is a reasonable setting for desktop machines (currently 15). [default=auto]]
|
||||
)],
|
||||
[req_ecmult_window=$withval], [req_ecmult_window=auto])
|
||||
|
18
src/ecmult.h
18
src/ecmult.h
@ -11,6 +11,24 @@
|
||||
#include "scalar.h"
|
||||
#include "scratch.h"
|
||||
|
||||
/* 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
|
||||
|
||||
/** The number of entries a table with precomputed multiples needs to have. */
|
||||
#define ECMULT_TABLE_SIZE(w) (1L << ((w)-2))
|
||||
|
||||
typedef struct {
|
||||
/* For accelerating the computation of a*P + b*G: */
|
||||
secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */
|
||||
|
@ -44,28 +44,14 @@
|
||||
# define WINDOW_G ECMULT_WINDOW_SIZE
|
||||
#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].
|
||||
#if ECMULT_WINDOW_SIZE < WINDOW_G
|
||||
# error ECMULT_WINDOW_SIZE too small for WINDOW_G.
|
||||
#endif
|
||||
|
||||
#define WNAF_BITS 128
|
||||
#define WNAF_SIZE_BITS(bits, w) (((bits) + (w) - 1) / (w))
|
||||
#define WNAF_SIZE(w) WNAF_SIZE_BITS(WNAF_BITS, w)
|
||||
|
||||
/** The number of entries a table with precomputed multiples needs to have. */
|
||||
#define ECMULT_TABLE_SIZE(w) (1 << ((w)-2))
|
||||
|
||||
/* The number of objects allocated on the scratch space for ecmult_multi algorithms */
|
||||
#define PIPPENGER_SCRATCH_OBJECTS 6
|
||||
#define STRAUSS_SCRATCH_OBJECTS 6
|
||||
|
16611
src/ecmult_static_pre_g.h
generated
Normal file
16611
src/ecmult_static_pre_g.h
generated
Normal file
File diff suppressed because it is too large
Load Diff
137
src/gen_ecmult_static_pre_g.c
Normal file
137
src/gen_ecmult_static_pre_g.c
Normal file
@ -0,0 +1,137 @@
|
||||
/*****************************************************************************************************
|
||||
* Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or https://www.opensource.org/licenses/mit-license.php. *
|
||||
*****************************************************************************************************/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Autotools creates libsecp256k1-config.h, of which ECMULT_WINDOW_SIZE is needed.
|
||||
ifndef guard so downstream users can define their own if they do not use autotools. */
|
||||
#if !defined(ECMULT_WINDOW_SIZE)
|
||||
#include "libsecp256k1-config.h"
|
||||
#endif
|
||||
|
||||
/* In principle we could use ASM, but this yields only a minor speedup in
|
||||
build time and it's very complicated. In particular when cross-compiling, we'd
|
||||
need to build the ASM for the build and the host machine. */
|
||||
#undef USE_EXTERNAL_ASM
|
||||
#undef USE_ASM_X86_64
|
||||
|
||||
#include "../include/secp256k1.h"
|
||||
#include "assumptions.h"
|
||||
#include "util.h"
|
||||
#include "field_impl.h"
|
||||
#include "group_impl.h"
|
||||
#include "ecmult.h"
|
||||
|
||||
void print_table(FILE *fp, const char *name, int window_g, const secp256k1_gej *gen, int with_conditionals) {
|
||||
static secp256k1_gej gj;
|
||||
static secp256k1_ge ge, dgen;
|
||||
static secp256k1_ge_storage ges;
|
||||
int j;
|
||||
int i;
|
||||
|
||||
gj = *gen;
|
||||
secp256k1_ge_set_gej_var(&ge, &gj);
|
||||
secp256k1_ge_to_storage(&ges, &ge);
|
||||
|
||||
fprintf(fp, "static const secp256k1_ge_storage %s[ECMULT_TABLE_SIZE(WINDOW_G)] = {\n", name);
|
||||
fprintf(fp, " S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32
|
||||
",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")\n",
|
||||
SECP256K1_GE_STORAGE_CONST_GET(ges));
|
||||
|
||||
secp256k1_gej_double_var(&gj, gen, NULL);
|
||||
secp256k1_ge_set_gej_var(&dgen, &gj);
|
||||
|
||||
j = 1;
|
||||
for(i = 3; i <= window_g; ++i) {
|
||||
if (with_conditionals) {
|
||||
fprintf(fp, "#if ECMULT_TABLE_SIZE(WINDOW_G) > %ld\n", ECMULT_TABLE_SIZE(i-1));
|
||||
}
|
||||
for(;j < ECMULT_TABLE_SIZE(i); ++j) {
|
||||
secp256k1_gej_set_ge(&gj, &ge);
|
||||
secp256k1_gej_add_ge_var(&gj, &gj, &dgen, NULL);
|
||||
secp256k1_ge_set_gej_var(&ge, &gj);
|
||||
secp256k1_ge_to_storage(&ges, &ge);
|
||||
|
||||
fprintf(fp, ",S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32
|
||||
",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")\n",
|
||||
SECP256K1_GE_STORAGE_CONST_GET(ges));
|
||||
}
|
||||
if (with_conditionals) {
|
||||
fprintf(fp, "#endif\n");
|
||||
}
|
||||
}
|
||||
fprintf(fp, "};\n");
|
||||
}
|
||||
|
||||
void print_two_tables(FILE *fp, int window_g, const secp256k1_ge *g, int with_conditionals) {
|
||||
secp256k1_gej gj;
|
||||
int i;
|
||||
|
||||
secp256k1_gej_set_ge(&gj, g);
|
||||
print_table(fp, "secp256k1_pre_g", window_g, &gj, with_conditionals);
|
||||
for (i = 0; i < 128; ++i) {
|
||||
secp256k1_gej_double_var(&gj, &gj, NULL);
|
||||
}
|
||||
print_table(fp, "secp256k1_pre_g_128", window_g, &gj, with_conditionals);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
const secp256k1_ge g = SECP256K1_G;
|
||||
const secp256k1_ge g_13 = SECP256K1_G_ORDER_13;
|
||||
const secp256k1_ge g_199 = SECP256K1_G_ORDER_199;
|
||||
const int window_g_13 = 4;
|
||||
const int window_g_199 = 8;
|
||||
FILE* fp;
|
||||
|
||||
fp = fopen("src/ecmult_static_pre_g.h","w");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "Could not open src/ecmult_static_pre_g.h for writing!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(fp, "/* This file was automatically generated by gen_ecmult_static_pre_g. */\n");
|
||||
fprintf(fp, "/* This file contains an array secp256k1_pre_g with odd multiples of the base point G and\n");
|
||||
fprintf(fp, " * an array secp256k1_pre_g_128 with odd multiples of 2^128*G for accelerating the computation of a*P + b*G.\n");
|
||||
fprintf(fp, " */\n");
|
||||
fprintf(fp, "#ifndef SECP256K1_ECMULT_STATIC_PRE_G_H\n");
|
||||
fprintf(fp, "#define SECP256K1_ECMULT_STATIC_PRE_G_H\n");
|
||||
fprintf(fp, "#include \"group.h\"\n");
|
||||
fprintf(fp, "#ifdef S\n");
|
||||
fprintf(fp, " #error macro identifier S already in use.\n");
|
||||
fprintf(fp, "#endif\n");
|
||||
fprintf(fp, "#define S(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) "
|
||||
"SECP256K1_GE_STORAGE_CONST(0x##a##u,0x##b##u,0x##c##u,0x##d##u,0x##e##u,0x##f##u,0x##g##u,"
|
||||
"0x##h##u,0x##i##u,0x##j##u,0x##k##u,0x##l##u,0x##m##u,0x##n##u,0x##o##u,0x##p##u)\n");
|
||||
fprintf(fp, "#if ECMULT_TABLE_SIZE(ECMULT_WINDOW_SIZE) > %ld\n", ECMULT_TABLE_SIZE(ECMULT_WINDOW_SIZE));
|
||||
fprintf(fp, " #error configuration mismatch, invalid ECMULT_WINDOW_SIZE. Try deleting ecmult_static_pre_g.h before the build.\n");
|
||||
fprintf(fp, "#endif\n");
|
||||
fprintf(fp, "#if defined(EXHAUSTIVE_TEST_ORDER)\n");
|
||||
fprintf(fp, "#if EXHAUSTIVE_TEST_ORDER == 13\n");
|
||||
fprintf(fp, "#define WINDOW_G %d\n", window_g_13);
|
||||
|
||||
print_two_tables(fp, window_g_13, &g_13, 0);
|
||||
|
||||
fprintf(fp, "#elif EXHAUSTIVE_TEST_ORDER == 199\n");
|
||||
fprintf(fp, "#define WINDOW_G %d\n", window_g_199);
|
||||
|
||||
print_two_tables(fp, window_g_199, &g_199, 0);
|
||||
|
||||
fprintf(fp, "#else\n");
|
||||
fprintf(fp, " #error No known generator for the specified exhaustive test group order.\n");
|
||||
fprintf(fp, "#endif\n");
|
||||
fprintf(fp, "#else /* !defined(EXHAUSTIVE_TEST_ORDER) */\n");
|
||||
fprintf(fp, "#define WINDOW_G ECMULT_WINDOW_SIZE\n");
|
||||
|
||||
print_two_tables(fp, ECMULT_WINDOW_SIZE, &g, 1);
|
||||
|
||||
fprintf(fp, "#endif\n");
|
||||
fprintf(fp, "#undef S\n");
|
||||
fprintf(fp, "#endif\n");
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
@ -10,6 +10,27 @@
|
||||
#include "field.h"
|
||||
#include "group.h"
|
||||
|
||||
#define SECP256K1_G_ORDER_13 SECP256K1_GE_CONST(\
|
||||
0xc3459c3d, 0x35326167, 0xcd86cce8, 0x07a2417f,\
|
||||
0x5b8bd567, 0xde8538ee, 0x0d507b0c, 0xd128f5bb,\
|
||||
0x8e467fec, 0xcd30000a, 0x6cc1184e, 0x25d382c2,\
|
||||
0xa2f4494e, 0x2fbe9abc, 0x8b64abac, 0xd005fb24\
|
||||
)
|
||||
#define SECP256K1_G_ORDER_199 SECP256K1_GE_CONST(\
|
||||
0x226e653f, 0xc8df7744, 0x9bacbf12, 0x7d1dcbf9,\
|
||||
0x87f05b2a, 0xe7edbd28, 0x1f564575, 0xc48dcf18,\
|
||||
0xa13872c2, 0xe933bb17, 0x5d9ffd5b, 0xb5b6e10c,\
|
||||
0x57fe3c00, 0xbaaaa15a, 0xe003ec3e, 0x9c269bae\
|
||||
)
|
||||
/** Generator for secp256k1, value 'g' defined in
|
||||
* "Standards for Efficient Cryptography" (SEC2) 2.7.1.
|
||||
*/
|
||||
#define SECP256K1_G SECP256K1_GE_CONST(\
|
||||
0x79BE667EUL, 0xF9DCBBACUL, 0x55A06295UL, 0xCE870B07UL,\
|
||||
0x029BFCDBUL, 0x2DCE28D9UL, 0x59F2815BUL, 0x16F81798UL,\
|
||||
0x483ADA77UL, 0x26A3C465UL, 0x5DA4FBFCUL, 0x0E1108A8UL,\
|
||||
0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL\
|
||||
)
|
||||
/* These exhaustive group test orders and generators are chosen such that:
|
||||
* - The field size is equal to that of secp256k1, so field code is the same.
|
||||
* - The curve equation is of the form y^2=x^3+B for some constant B.
|
||||
@ -21,23 +42,15 @@
|
||||
*/
|
||||
#if defined(EXHAUSTIVE_TEST_ORDER)
|
||||
# if EXHAUSTIVE_TEST_ORDER == 13
|
||||
static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST(
|
||||
0xc3459c3d, 0x35326167, 0xcd86cce8, 0x07a2417f,
|
||||
0x5b8bd567, 0xde8538ee, 0x0d507b0c, 0xd128f5bb,
|
||||
0x8e467fec, 0xcd30000a, 0x6cc1184e, 0x25d382c2,
|
||||
0xa2f4494e, 0x2fbe9abc, 0x8b64abac, 0xd005fb24
|
||||
);
|
||||
static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_13;
|
||||
|
||||
static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST(
|
||||
0x3d3486b2, 0x159a9ca5, 0xc75638be, 0xb23a69bc,
|
||||
0x946a45ab, 0x24801247, 0xb4ed2b8e, 0x26b6a417
|
||||
);
|
||||
# elif EXHAUSTIVE_TEST_ORDER == 199
|
||||
static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST(
|
||||
0x226e653f, 0xc8df7744, 0x9bacbf12, 0x7d1dcbf9,
|
||||
0x87f05b2a, 0xe7edbd28, 0x1f564575, 0xc48dcf18,
|
||||
0xa13872c2, 0xe933bb17, 0x5d9ffd5b, 0xb5b6e10c,
|
||||
0x57fe3c00, 0xbaaaa15a, 0xe003ec3e, 0x9c269bae
|
||||
);
|
||||
static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_199;
|
||||
|
||||
static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST(
|
||||
0x2cca28fa, 0xfc614b80, 0x2a3db42b, 0x00ba00b1,
|
||||
0xbea8d943, 0xdace9ab2, 0x9536daea, 0x0074defb
|
||||
@ -46,15 +59,7 @@ static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST(
|
||||
# error No known generator for the specified exhaustive test group order.
|
||||
# endif
|
||||
#else
|
||||
/** Generator for secp256k1, value 'g' defined in
|
||||
* "Standards for Efficient Cryptography" (SEC2) 2.7.1.
|
||||
*/
|
||||
static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST(
|
||||
0x79BE667EUL, 0xF9DCBBACUL, 0x55A06295UL, 0xCE870B07UL,
|
||||
0x029BFCDBUL, 0x2DCE28D9UL, 0x59F2815BUL, 0x16F81798UL,
|
||||
0x483ADA77UL, 0x26A3C465UL, 0x5DA4FBFCUL, 0x0E1108A8UL,
|
||||
0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL
|
||||
);
|
||||
static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G;
|
||||
|
||||
static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 7);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user