Merge c06cda3e48 into merged_master (Bitcoin PR bitcoin/bitcoin#23383)

Kept what we already had since it's a newer version of secp256k1-zkp
This commit is contained in:
Byron Hambly 2023-06-13 15:44:13 +00:00
commit ab249ee428
12 changed files with 26682 additions and 284 deletions

View file

@ -1913,7 +1913,7 @@ PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR"
unset PKG_CONFIG_LIBDIR
PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP"
ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --with-bignum=no --enable-module-recovery --enable-module-schnorrsig --enable-experimental --enable-module-whitelist --enable-module-rangeproof --enable-module-generator --enable-module-surjectionproof --enable-module-ecdh --disable-openssl-tests"
ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --with-bignum=no --enable-module-recovery --enable-module-schnorrsig --enable-experimental --enable-module-whitelist --enable-module-rangeproof --enable-module-generator --enable-module-surjectionproof --enable-module-ecdh"
AC_CONFIG_SUBDIRS([src/secp256k1])
AC_OUTPUT

View file

@ -298,7 +298,7 @@ bool CKey::SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint2
uint256 tweak = XOnlyPubKey(pubkey_bytes).ComputeTapTweakHash(merkle_root->IsNull() ? nullptr : merkle_root);
if (!secp256k1_keypair_xonly_tweak_add(GetVerifyContext(), &keypair, tweak.data())) return false;
}
bool ret = secp256k1_schnorrsig_sign(secp256k1_context_sign, sig.data(), hash.data(), &keypair, (unsigned char*)aux.data());
bool ret = secp256k1_schnorrsig_sign(secp256k1_context_sign, sig.data(), hash.data(), &keypair, aux.data());
if (ret) {
// Additional verification step to prevent using a potentially corrupted signature
secp256k1_xonly_pubkey pubkey_verify;

View file

@ -19,9 +19,9 @@ env:
RECOVERY: no
SCHNORRSIG: no
### test options
TEST_ITERS:
SECP256K1_TEST_ITERS:
BENCH: yes
BENCH_ITERS: 2
SECP256K1_BENCH_ITERS: 2
CTIMETEST: yes
cat_logs_snippet: &CAT_LOGS
@ -171,7 +171,7 @@ task:
memory: 1G
env:
WRAPPER_CMD: qemu-s390x
TEST_ITERS: 16
SECP256K1_TEST_ITERS: 16
HOST: s390x-linux-gnu
WITH_VALGRIND: no
ECDH: yes
@ -194,7 +194,7 @@ task:
memory: 1G
env:
WRAPPER_CMD: qemu-arm
TEST_ITERS: 16
SECP256K1_TEST_ITERS: 16
HOST: arm-linux-gnueabihf
WITH_VALGRIND: no
ECDH: yes
@ -218,7 +218,7 @@ task:
memory: 1G
env:
WRAPPER_CMD: qemu-aarch64
TEST_ITERS: 16
SECP256K1_TEST_ITERS: 16
HOST: aarch64-linux-gnu
WITH_VALGRIND: no
ECDH: yes
@ -239,7 +239,7 @@ task:
memory: 1G
env:
WRAPPER_CMD: qemu-ppc64le
TEST_ITERS: 16
SECP256K1_TEST_ITERS: 16
HOST: powerpc64le-linux-gnu
WITH_VALGRIND: no
ECDH: yes
@ -260,7 +260,7 @@ task:
memory: 1G
env:
WRAPPER_CMD: wine64-stable
TEST_ITERS: 16
SECP256K1_TEST_ITERS: 16
HOST: x86_64-w64-mingw32
WITH_VALGRIND: no
ECDH: yes
@ -278,28 +278,26 @@ task:
container:
dockerfile: ci/linux-debian.Dockerfile
cpu: 1
memory: 1G
memory: 2G
env:
ECDH: yes
RECOVERY: yes
EXPERIMENTAL: yes
SCHNORRSIG: yes
CTIMETEST: no
EXTRAFLAGS: "--disable-openssl-tests"
matrix:
- name: "Valgrind (memcheck)"
env:
# The `--error-exitcode` is required to make the test fail if valgrind found errors, otherwise it'll return 0 (https://www.valgrind.org/docs/manual/manual-core.html)
WRAPPER_CMD: "valgrind --error-exitcode=42"
TEST_ITERS: 16
SECP256K1_TEST_ITERS: 2
- name: "UBSan, ASan, LSan"
env:
CFLAGS: "-fsanitize=undefined,address"
CFLAGS_FOR_BUILD: "-fsanitize=undefined,address"
CFLAGS: "-fsanitize=undefined,address -g"
UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1"
ASAN_OPTIONS: "strict_string_checks=1:detect_stack_use_after_return=1:detect_leaks=1"
LSAN_OPTIONS: "use_unaligned=1"
TEST_ITERS: 32
SECP256K1_TEST_ITERS: 32
# Try to cover many configurations with just a tiny matrix.
matrix:
- env:
@ -330,7 +328,7 @@ task:
# ./configure correctly errors out when given CC=g++.
# We hack around this by passing CC=g++ only to make.
CC: gcc
MAKEFLAGS: -j2 CC=g++ CFLAGS=-fpermissive
MAKEFLAGS: -j2 CC=g++ CFLAGS=-fpermissive\ -g
WERROR_CFLAGS:
EXPERIMENTAL: yes
ECDH: yes

View file

@ -1,58 +0,0 @@
/***********************************************************************
* Copyright (c) 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#include "../include/secp256k1.h"
#include "util.h"
#include "bench.h"
typedef struct {
secp256k1_context* ctx;
unsigned char msg[32];
unsigned char key[32];
} bench_sign_data;
static void bench_sign_setup(void* arg) {
int i;
bench_sign_data *data = (bench_sign_data*)arg;
for (i = 0; i < 32; i++) {
data->msg[i] = i + 1;
}
for (i = 0; i < 32; i++) {
data->key[i] = i + 65;
}
}
static void bench_sign_run(void* arg, int iters) {
int i;
bench_sign_data *data = (bench_sign_data*)arg;
unsigned char sig[74];
for (i = 0; i < iters; i++) {
size_t siglen = 74;
int j;
secp256k1_ecdsa_signature signature;
CHECK(secp256k1_ecdsa_sign(data->ctx, &signature, data->msg, data->key, NULL, NULL));
CHECK(secp256k1_ecdsa_signature_serialize_der(data->ctx, sig, &siglen, &signature));
for (j = 0; j < 32; j++) {
data->msg[j] = sig[j];
data->key[j] = sig[j + 32];
}
}
}
int main(void) {
bench_sign_data data;
int iters = get_iters(20000);
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
run_benchmark("ecdsa_sign", bench_sign_run, bench_sign_setup, NULL, &data, 10, iters);
secp256k1_context_destroy(data.ctx);
return 0;
}

View file

@ -1,115 +0,0 @@
/***********************************************************************
* Copyright (c) 2014 Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#include <stdio.h>
#include <string.h>
#include "../include/secp256k1.h"
#include "util.h"
#include "bench.h"
#ifdef ENABLE_OPENSSL_TESTS
#include <openssl/bn.h>
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
#endif
typedef struct {
secp256k1_context *ctx;
unsigned char msg[32];
unsigned char key[32];
unsigned char sig[72];
size_t siglen;
unsigned char pubkey[33];
size_t pubkeylen;
#ifdef ENABLE_OPENSSL_TESTS
EC_GROUP* ec_group;
#endif
} bench_verify_data;
static void bench_verify(void* arg, int iters) {
int i;
bench_verify_data* data = (bench_verify_data*)arg;
for (i = 0; i < iters; i++) {
secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;
data->sig[data->siglen - 1] ^= (i & 0xFF);
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1);
CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1);
CHECK(secp256k1_ecdsa_verify(data->ctx, &sig, data->msg, &pubkey) == (i == 0));
data->sig[data->siglen - 1] ^= (i & 0xFF);
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
}
}
#ifdef ENABLE_OPENSSL_TESTS
static void bench_verify_openssl(void* arg, int iters) {
int i;
bench_verify_data* data = (bench_verify_data*)arg;
for (i = 0; i < iters; i++) {
data->sig[data->siglen - 1] ^= (i & 0xFF);
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
{
EC_KEY *pkey = EC_KEY_new();
const unsigned char *pubkey = &data->pubkey[0];
int result;
CHECK(pkey != NULL);
result = EC_KEY_set_group(pkey, data->ec_group);
CHECK(result);
result = (o2i_ECPublicKey(&pkey, &pubkey, data->pubkeylen)) != NULL;
CHECK(result);
result = ECDSA_verify(0, &data->msg[0], sizeof(data->msg), &data->sig[0], data->siglen, pkey) == (i == 0);
CHECK(result);
EC_KEY_free(pkey);
}
data->sig[data->siglen - 1] ^= (i & 0xFF);
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
}
}
#endif
int main(void) {
int i;
secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;
bench_verify_data data;
int iters = get_iters(20000);
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
for (i = 0; i < 32; i++) {
data.msg[i] = 1 + i;
}
for (i = 0; i < 32; i++) {
data.key[i] = 33 + i;
}
data.siglen = 72;
CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL));
CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig));
CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key));
data.pubkeylen = 33;
CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
run_benchmark("ecdsa_verify", bench_verify, NULL, NULL, &data, 10, iters);
#ifdef ENABLE_OPENSSL_TESTS
data.ec_group = EC_GROUP_new_by_curve_name(NID_secp256k1);
run_benchmark("ecdsa_verify_openssl", bench_verify_openssl, NULL, NULL, &data, 10, iters);
EC_GROUP_free(data.ec_group);
#endif
secp256k1_context_destroy(data.ctx);
return 0;
}

View file

@ -0,0 +1,14 @@
/***********************************************************************
* Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_ECMULT_GEN_PREC_H
#define SECP256K1_ECMULT_GEN_PREC_H
#include "ecmult_gen.h"
static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits);
#endif /* SECP256K1_ECMULT_GEN_PREC_H */

View file

@ -0,0 +1,81 @@
/***********************************************************************
* Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
#ifndef SECP256K1_ECMULT_GEN_PREC_IMPL_H
#define SECP256K1_ECMULT_GEN_PREC_IMPL_H
#include "ecmult_gen_prec.h"
#include "group_impl.h"
#include "field_impl.h"
#include "ecmult_gen.h"
#include "util.h"
static void secp256k1_ecmult_gen_create_prec_table(secp256k1_ge_storage* table, const secp256k1_ge* gen, int bits) {
int g = ECMULT_GEN_PREC_G(bits);
int n = ECMULT_GEN_PREC_N(bits);
secp256k1_ge* prec = checked_malloc(&default_error_callback, n * g * sizeof(*prec));
secp256k1_gej gj;
secp256k1_gej nums_gej;
int i, j;
/* get the generator */
secp256k1_gej_set_ge(&gj, gen);
/* Construct a group element with no known corresponding scalar (nothing up my sleeve). */
{
static const unsigned char nums_b32[33] = "The scalar for this x is unknown";
secp256k1_fe nums_x;
secp256k1_ge nums_ge;
int r;
r = secp256k1_fe_set_b32(&nums_x, nums_b32);
(void)r;
VERIFY_CHECK(r);
r = secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0);
(void)r;
VERIFY_CHECK(r);
secp256k1_gej_set_ge(&nums_gej, &nums_ge);
/* Add G to make the bits in x uniformly distributed. */
secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, gen, NULL);
}
/* compute prec. */
{
secp256k1_gej gbase;
secp256k1_gej numsbase;
secp256k1_gej* precj = checked_malloc(&default_error_callback, n * g * sizeof(*precj)); /* Jacobian versions of prec. */
gbase = gj; /* PREC_G^j * G */
numsbase = nums_gej; /* 2^j * nums. */
for (j = 0; j < n; j++) {
/* Set precj[j*PREC_G .. j*PREC_G+(PREC_G-1)] to (numsbase, numsbase + gbase, ..., numsbase + (PREC_G-1)*gbase). */
precj[j*g] = numsbase;
for (i = 1; i < g; i++) {
secp256k1_gej_add_var(&precj[j*g + i], &precj[j*g + i - 1], &gbase, NULL);
}
/* Multiply gbase by PREC_G. */
for (i = 0; i < bits; i++) {
secp256k1_gej_double_var(&gbase, &gbase, NULL);
}
/* Multiply numbase by 2. */
secp256k1_gej_double_var(&numsbase, &numsbase, NULL);
if (j == n - 2) {
/* In the last iteration, numsbase is (1 - 2^j) * nums instead. */
secp256k1_gej_neg(&numsbase, &numsbase);
secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL);
}
}
secp256k1_ge_set_all_gej_var(prec, precj, n * g);
free(precj);
}
for (j = 0; j < n; j++) {
for (i = 0; i < g; i++) {
secp256k1_ge_to_storage(&table[j*g + i], &prec[j*g + i]);
}
}
free(prec);
}
#endif /* SECP256K1_ECMULT_GEN_PREC_IMPL_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,95 +0,0 @@
/***********************************************************************
* Copyright (c) 2013, 2014, 2015 Thomas Daede, Cory Fields *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/
/* Autotools creates libsecp256k1-config.h, of which ECMULT_GEN_PREC_BITS is needed.
ifndef guard so downstream users can define their own if they do not use autotools. */
#if !defined(ECMULT_GEN_PREC_BITS)
#include "libsecp256k1-config.h"
#endif
/* We can't require the precomputed tables when creating them. */
#undef USE_ECMULT_STATIC_PRECOMPUTATION
/* 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 "scalar_impl.h"
#include "group_impl.h"
#include "ecmult_gen_impl.h"
static void default_error_callback_fn(const char* str, void* data) {
(void)data;
fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str);
abort();
}
static const secp256k1_callback default_error_callback = {
default_error_callback_fn,
NULL
};
int main(int argc, char **argv) {
secp256k1_ecmult_gen_context ctx;
void *prealloc, *base;
int inner;
int outer;
FILE* fp;
(void)argc;
(void)argv;
fp = fopen("src/ecmult_static_context.h","w");
if (fp == NULL) {
fprintf(stderr, "Could not open src/ecmult_static_context.h for writing!\n");
return -1;
}
fprintf(fp, "#ifndef SECP256K1_ECMULT_STATIC_CONTEXT_H\n");
fprintf(fp, "#define SECP256K1_ECMULT_STATIC_CONTEXT_H\n");
fprintf(fp, "#include \"src/group.h\"\n");
fprintf(fp, "#define SC SECP256K1_GE_STORAGE_CONST\n");
fprintf(fp, "#if ECMULT_GEN_PREC_N != %d || ECMULT_GEN_PREC_G != %d\n", ECMULT_GEN_PREC_N, ECMULT_GEN_PREC_G);
fprintf(fp, " #error configuration mismatch, invalid ECMULT_GEN_PREC_N, ECMULT_GEN_PREC_G. Try deleting ecmult_static_context.h before the build.\n");
fprintf(fp, "#endif\n");
fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_static_context[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G] = {\n");
base = checked_malloc(&default_error_callback, SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE);
prealloc = base;
secp256k1_ecmult_gen_context_init(&ctx);
secp256k1_ecmult_gen_context_build(&ctx, &prealloc);
for(outer = 0; outer != ECMULT_GEN_PREC_N; outer++) {
fprintf(fp,"{\n");
for(inner = 0; inner != ECMULT_GEN_PREC_G; inner++) {
fprintf(fp," SC(%uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu)", SECP256K1_GE_STORAGE_CONST_GET((*ctx.prec)[outer][inner]));
if (inner != ECMULT_GEN_PREC_G - 1) {
fprintf(fp,",\n");
} else {
fprintf(fp,"\n");
}
}
if (outer != ECMULT_GEN_PREC_N - 1) {
fprintf(fp,"},\n");
} else {
fprintf(fp,"}\n");
}
}
fprintf(fp,"};\n");
secp256k1_ecmult_gen_context_clear(&ctx);
free(base);
fprintf(fp, "#undef SC\n");
fprintf(fp, "#endif\n");
fclose(fp);
return 0;
}

View file

@ -0,0 +1,83 @@
/***********************************************************************
* Copyright (c) 2013, 2014, 2015 Thomas Daede, Cory Fields *
* 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>
#include "../include/secp256k1.h"
#include "assumptions.h"
#include "util.h"
#include "group.h"
#include "ecmult_gen.h"
#include "ecmult_gen_prec_impl.h"
int main(int argc, char **argv) {
const char outfile[] = "src/ecmult_gen_static_prec_table.h";
FILE* fp;
int bits;
(void)argc;
(void)argv;
fp = fopen(outfile, "w");
if (fp == NULL) {
fprintf(stderr, "Could not open %s for writing!\n", outfile);
return -1;
}
fprintf(fp, "/* This file was automatically generated by gen_ecmult_gen_static_prec_table. */\n");
fprintf(fp, "/* See ecmult_gen_impl.h for details about the contents of this file. */\n");
fprintf(fp, "#ifndef SECP256K1_ECMULT_GEN_STATIC_PREC_TABLE_H\n");
fprintf(fp, "#define SECP256K1_ECMULT_GEN_STATIC_PREC_TABLE_H\n");
fprintf(fp, "#include \"group.h\"\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, "#ifdef EXHAUSTIVE_TEST_ORDER\n");
fprintf(fp, "static secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N(ECMULT_GEN_PREC_BITS)][ECMULT_GEN_PREC_G(ECMULT_GEN_PREC_BITS)];\n");
fprintf(fp, "#else\n");
fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N(ECMULT_GEN_PREC_BITS)][ECMULT_GEN_PREC_G(ECMULT_GEN_PREC_BITS)] = {\n");
for (bits = 2; bits <= 8; bits *= 2) {
int g = ECMULT_GEN_PREC_G(bits);
int n = ECMULT_GEN_PREC_N(bits);
int inner, outer;
secp256k1_ge_storage* table = checked_malloc(&default_error_callback, n * g * sizeof(secp256k1_ge_storage));
secp256k1_ecmult_gen_create_prec_table(table, &secp256k1_ge_const_g, bits);
fprintf(fp, "#if ECMULT_GEN_PREC_BITS == %d\n", bits);
for(outer = 0; outer != n; outer++) {
fprintf(fp,"{");
for(inner = 0; inner != g; inner++) {
fprintf(fp, "S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32
",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")",
SECP256K1_GE_STORAGE_CONST_GET(table[outer * g + inner]));
if (inner != g - 1) {
fprintf(fp,",\n");
}
}
if (outer != n - 1) {
fprintf(fp,"},\n");
} else {
fprintf(fp,"}\n");
}
}
fprintf(fp, "#endif\n");
free(table);
}
fprintf(fp, "};\n");
fprintf(fp, "#endif /* EXHAUSTIVE_TEST_ORDER */\n");
fprintf(fp, "#undef SC\n");
fprintf(fp, "#endif /* SECP256K1_ECMULT_GEN_STATIC_PREC_TABLE_H */\n");
fclose(fp);
return 0;
}

View file

@ -0,0 +1,131 @@
/*****************************************************************************************************
* 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
#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;
}