From 3b0c2185eab0fe5cb910fffee4c88e134f6d3cad Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Tue, 9 Nov 2021 10:17:02 +0100 Subject: [PATCH] ecmult_gen: Simplify ecmult_gen context after making table static This is a backwards-compatible API change: Before this commit, a context initialized for signing was required to call functions that rely on ecmult_gen. After this commit, this is no longer necessary because the static ecmult_gen table is always present. In practice this means that the corresponding functions will just work instead of calling the illegal callback when given a context which is not (officially) initialized for signing. This is in line with 6815761, which made the analogous change with respect to ecmult and contexts initialized for signing. But as opposed to 681571, which removed the ecmult context entirely, we cannot remove the ecmult_gen context entirely because it is still used for random blinding. Moreover, since the secp256k1_context_no_precomp context is const and cannot meaningfully support random blinding, we refrain (for now) from changing its API, i.e., the illegal callback will still be called when trying to use ecmult_gen operations with the static secp256k1_context_no_precomp context. --- src/ecmult_gen.h | 26 ++++----------- src/ecmult_gen_impl.h | 37 +++++++++++---------- src/gen_context.c | 2 +- src/modules/extrakeys/tests_impl.h | 22 +++++++++---- src/modules/recovery/tests_impl.h | 28 +++++++++------- src/modules/schnorrsig/tests_impl.h | 50 +++++++++++++++++------------ src/secp256k1.c | 13 +------- src/tests.c | 32 +++++++++++------- 8 files changed, 109 insertions(+), 101 deletions(-) diff --git a/src/ecmult_gen.h b/src/ecmult_gen.h index 05cf4d52c..9930b6ac3 100644 --- a/src/ecmult_gen.h +++ b/src/ecmult_gen.h @@ -18,28 +18,16 @@ #define ECMULT_GEN_PREC_N (256 / ECMULT_GEN_PREC_B) typedef struct { - /* For accelerating the computation of a*G: - * To harden against timing attacks, use the following mechanism: - * * Break up the multiplicand into groups of PREC_B bits, called n_0, n_1, n_2, ..., n_(PREC_N-1). - * * Compute sum(n_i * (PREC_G)^i * G + U_i, i=0 ... PREC_N-1), where: - * * U_i = U * 2^i, for i=0 ... PREC_N-2 - * * U_i = U * (1-2^(PREC_N-1)), for i=PREC_N-1 - * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0 ... PREC_N-1) = 0. - * For each i, and each of the PREC_G possible values of n_i, (n_i * (PREC_G)^i * G + U_i) is - * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0 ... PREC_N-1). - * None of the resulting prec group elements have a known scalar, and neither do any of - * the intermediate sums while computing a*G. - */ - secp256k1_ge_storage (*prec)[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G]; /* prec[j][i] = (PREC_G)^j * i * G + U_i */ - secp256k1_scalar blind; - secp256k1_gej initial; + /* Whether the context has been built. */ + int built; + + /* Blinding values used when computing (n-b)G + bG. */ + secp256k1_scalar blind; /* -b */ + secp256k1_gej initial; /* bG */ } secp256k1_ecmult_gen_context; -static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context* ctx); -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx, void **prealloc); -static void secp256k1_ecmult_gen_context_finalize_memcpy(secp256k1_ecmult_gen_context *dst, const secp256k1_ecmult_gen_context* src); +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx); static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); -static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx); /** Multiply with the generator: R = a*G */ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a); diff --git a/src/ecmult_gen_impl.h b/src/ecmult_gen_impl.h index 0a9b5c4b7..b75af0265 100644 --- a/src/ecmult_gen_impl.h +++ b/src/ecmult_gen_impl.h @@ -14,35 +14,34 @@ #include "hash_impl.h" #include "ecmult_static_context.h" -static const size_t SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE = 0; - -static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context *ctx) { - ctx->prec = NULL; -} - -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx, void **prealloc) { - if (ctx->prec != NULL) { - return; - } - (void)prealloc; - ctx->prec = (secp256k1_ge_storage (*)[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G])secp256k1_ecmult_static_context; +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx) { secp256k1_ecmult_gen_blind(ctx, NULL); + ctx->built = 1; } static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx) { - return ctx->prec != NULL; -} - -static void secp256k1_ecmult_gen_context_finalize_memcpy(secp256k1_ecmult_gen_context *dst, const secp256k1_ecmult_gen_context *src) { - (void)dst, (void)src; + return ctx->built; } static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx) { + ctx->built = 0; secp256k1_scalar_clear(&ctx->blind); secp256k1_gej_clear(&ctx->initial); - ctx->prec = NULL; } +/* For accelerating the computation of a*G: + * To harden against timing attacks, use the following mechanism: + * * Break up the multiplicand into groups of PREC_B bits, called n_0, n_1, n_2, ..., n_(PREC_N-1). + * * Compute sum(n_i * (PREC_G)^i * G + U_i, i=0 ... PREC_N-1), where: + * * U_i = U * 2^i, for i=0 ... PREC_N-2 + * * U_i = U * (1-2^(PREC_N-1)), for i=PREC_N-1 + * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0 ... PREC_N-1) = 0. + * For each i, and each of the PREC_G possible values of n_i, (n_i * (PREC_G)^i * G + U_i) is + * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0 ... PREC_N-1). + * None of the resulting prec group elements have a known scalar, and neither do any of + * the intermediate sums while computing a*G. + * The prec values are stored in secp256k1_ecmult_gen_prec_table[j][i] = (PREC_G)^j * i * G + U_i. + */ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *gn) { secp256k1_ge add; secp256k1_ge_storage adds; @@ -67,7 +66,7 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25 * by Dag Arne Osvik, Adi Shamir, and Eran Tromer * (https://www.tau.ac.il/~tromer/papers/cache.pdf) */ - secp256k1_ge_storage_cmov(&adds, &(*ctx->prec)[j][i], i == bits); + secp256k1_ge_storage_cmov(&adds, &secp256k1_ecmult_gen_prec_table[j][i], i == bits); } secp256k1_ge_from_storage(&add, &adds); secp256k1_gej_add_ge(r, r, &add); diff --git a/src/gen_context.c b/src/gen_context.c index 85652aec9..9b770bb83 100644 --- a/src/gen_context.c +++ b/src/gen_context.c @@ -56,7 +56,7 @@ int main(int argc, char **argv) { 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"); + fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G] = {\n"); table = checked_malloc(&default_error_callback, ECMULT_GEN_PREC_TABLE_SIZE); secp256k1_ecmult_gen_create_prec_table(table); diff --git a/src/modules/extrakeys/tests_impl.h b/src/modules/extrakeys/tests_impl.h index dd53f9e12..c8a99f446 100644 --- a/src/modules/extrakeys/tests_impl.h +++ b/src/modules/extrakeys/tests_impl.h @@ -359,6 +359,9 @@ void test_keypair(void) { secp256k1_context *none = api_test_context(SECP256K1_CONTEXT_NONE, &ecount); secp256k1_context *sign = api_test_context(SECP256K1_CONTEXT_SIGN, &ecount); secp256k1_context *verify = api_test_context(SECP256K1_CONTEXT_VERIFY, &ecount); + secp256k1_context *sttc = secp256k1_context_clone(secp256k1_context_no_precomp); + secp256k1_context_set_error_callback(sttc, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(sttc, counting_illegal_callback_fn, &ecount); CHECK(sizeof(zeros96) == sizeof(keypair)); memset(overflows, 0xFF, sizeof(overflows)); @@ -366,18 +369,22 @@ void test_keypair(void) { /* Test keypair_create */ ecount = 0; secp256k1_testrand256(sk); - CHECK(secp256k1_keypair_create(none, &keypair, sk) == 0); - CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0); + CHECK(secp256k1_keypair_create(none, &keypair, sk) == 1); + CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0); + CHECK(ecount == 0); + CHECK(secp256k1_keypair_create(verify, &keypair, sk) == 1); + CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0); + CHECK(ecount == 0); + CHECK(secp256k1_keypair_create(sign, NULL, sk) == 0); CHECK(ecount == 1); - CHECK(secp256k1_keypair_create(verify, &keypair, sk) == 0); + CHECK(secp256k1_keypair_create(sign, &keypair, NULL) == 0); CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0); CHECK(ecount == 2); CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1); - CHECK(secp256k1_keypair_create(sign, NULL, sk) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_keypair_create(sign, &keypair, NULL) == 0); + CHECK(ecount == 2); + CHECK(secp256k1_keypair_create(sttc, &keypair, sk) == 0); CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0); - CHECK(ecount == 4); + CHECK(ecount == 3); /* Invalid secret key */ CHECK(secp256k1_keypair_create(sign, &keypair, zeros96) == 0); @@ -459,6 +466,7 @@ void test_keypair(void) { secp256k1_context_destroy(none); secp256k1_context_destroy(sign); secp256k1_context_destroy(verify); + secp256k1_context_destroy(sttc); } void test_keypair_add(void) { diff --git a/src/modules/recovery/tests_impl.h b/src/modules/recovery/tests_impl.h index 2fcd46d20..abf62f7f3 100644 --- a/src/modules/recovery/tests_impl.h +++ b/src/modules/recovery/tests_impl.h @@ -34,6 +34,7 @@ void test_ecdsa_recovery_api(void) { secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + secp256k1_context *sttc = secp256k1_context_clone(secp256k1_context_no_precomp); secp256k1_pubkey pubkey; secp256k1_pubkey recpubkey; secp256k1_ecdsa_signature normal_sig; @@ -53,10 +54,12 @@ void test_ecdsa_recovery_api(void) { secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount); secp256k1_context_set_error_callback(vrfy, counting_illegal_callback_fn, &ecount); secp256k1_context_set_error_callback(both, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_error_callback(sttc, counting_illegal_callback_fn, &ecount); secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount); secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount); secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount); secp256k1_context_set_illegal_callback(both, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(sttc, counting_illegal_callback_fn, &ecount); /* Construct and verify corresponding public key. */ CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); @@ -64,29 +67,31 @@ void test_ecdsa_recovery_api(void) { /* Check bad contexts and NULLs for signing */ ecount = 0; - CHECK(secp256k1_ecdsa_sign_recoverable(none, &recsig, message, privkey, NULL, NULL) == 0); - CHECK(ecount == 1); + CHECK(secp256k1_ecdsa_sign_recoverable(none, &recsig, message, privkey, NULL, NULL) == 1); + CHECK(ecount == 0); CHECK(secp256k1_ecdsa_sign_recoverable(sign, &recsig, message, privkey, NULL, NULL) == 1); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_sign_recoverable(vrfy, &recsig, message, privkey, NULL, NULL) == 0); - CHECK(ecount == 2); + CHECK(ecount == 0); + CHECK(secp256k1_ecdsa_sign_recoverable(vrfy, &recsig, message, privkey, NULL, NULL) == 1); + CHECK(ecount == 0); CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1); - CHECK(ecount == 2); + CHECK(ecount == 0); CHECK(secp256k1_ecdsa_sign_recoverable(both, NULL, message, privkey, NULL, NULL) == 0); - CHECK(ecount == 3); + CHECK(ecount == 1); CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, NULL, privkey, NULL, NULL) == 0); - CHECK(ecount == 4); + CHECK(ecount == 2); CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, NULL, NULL, NULL) == 0); - CHECK(ecount == 5); + CHECK(ecount == 3); + CHECK(secp256k1_ecdsa_sign_recoverable(sttc, &recsig, message, privkey, NULL, NULL) == 0); + CHECK(ecount == 4); /* This will fail or succeed randomly, and in either case will not ARG_CHECK failure */ secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, recovery_test_nonce_function, NULL); - CHECK(ecount == 5); + CHECK(ecount == 4); /* These will all fail, but not in ARG_CHECK way */ CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, zero_privkey, NULL, NULL) == 0); CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, over_privkey, NULL, NULL) == 0); /* This one will succeed. */ CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1); - CHECK(ecount == 5); + CHECK(ecount == 4); /* Check signing with a goofy nonce function */ @@ -145,6 +150,7 @@ void test_ecdsa_recovery_api(void) { secp256k1_context_destroy(sign); secp256k1_context_destroy(vrfy); secp256k1_context_destroy(both); + secp256k1_context_destroy(sttc); } void test_ecdsa_recovery_end_to_end(void) { diff --git a/src/modules/schnorrsig/tests_impl.h b/src/modules/schnorrsig/tests_impl.h index d301abee5..2efec8a2b 100644 --- a/src/modules/schnorrsig/tests_impl.h +++ b/src/modules/schnorrsig/tests_impl.h @@ -132,16 +132,19 @@ void test_schnorrsig_api(void) { secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + secp256k1_context *sttc = secp256k1_context_clone(secp256k1_context_no_precomp); int ecount; secp256k1_context_set_error_callback(none, counting_illegal_callback_fn, &ecount); secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount); secp256k1_context_set_error_callback(vrfy, counting_illegal_callback_fn, &ecount); secp256k1_context_set_error_callback(both, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_error_callback(sttc, counting_illegal_callback_fn, &ecount); secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount); secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount); secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount); secp256k1_context_set_illegal_callback(both, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(sttc, counting_illegal_callback_fn, &ecount); secp256k1_testrand256(sk1); secp256k1_testrand256(sk2); @@ -157,42 +160,46 @@ void test_schnorrsig_api(void) { /** main test body **/ ecount = 0; - CHECK(secp256k1_schnorrsig_sign(none, sig, msg, &keypairs[0], NULL) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_schnorrsig_sign(vrfy, sig, msg, &keypairs[0], NULL) == 0); - CHECK(ecount == 2); + CHECK(secp256k1_schnorrsig_sign(none, sig, msg, &keypairs[0], NULL) == 1); + CHECK(ecount == 0); + CHECK(secp256k1_schnorrsig_sign(vrfy, sig, msg, &keypairs[0], NULL) == 1); + CHECK(ecount == 0); CHECK(secp256k1_schnorrsig_sign(sign, sig, msg, &keypairs[0], NULL) == 1); - CHECK(ecount == 2); + CHECK(ecount == 0); CHECK(secp256k1_schnorrsig_sign(sign, NULL, msg, &keypairs[0], NULL) == 0); - CHECK(ecount == 3); + CHECK(ecount == 1); CHECK(secp256k1_schnorrsig_sign(sign, sig, NULL, &keypairs[0], NULL) == 0); - CHECK(ecount == 4); + CHECK(ecount == 2); CHECK(secp256k1_schnorrsig_sign(sign, sig, msg, NULL, NULL) == 0); - CHECK(ecount == 5); + CHECK(ecount == 3); CHECK(secp256k1_schnorrsig_sign(sign, sig, msg, &invalid_keypair, NULL) == 0); - CHECK(ecount == 6); + CHECK(ecount == 4); + CHECK(secp256k1_schnorrsig_sign(sttc, sig, msg, &keypairs[0], NULL) == 0); + CHECK(ecount == 5); ecount = 0; - CHECK(secp256k1_schnorrsig_sign_custom(none, sig, msg, sizeof(msg), &keypairs[0], &extraparams) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_schnorrsig_sign_custom(vrfy, sig, msg, sizeof(msg), &keypairs[0], &extraparams) == 0); - CHECK(ecount == 2); + CHECK(secp256k1_schnorrsig_sign_custom(none, sig, msg, sizeof(msg), &keypairs[0], &extraparams) == 1); + CHECK(ecount == 0); + CHECK(secp256k1_schnorrsig_sign_custom(vrfy, sig, msg, sizeof(msg), &keypairs[0], &extraparams) == 1); + CHECK(ecount == 0); CHECK(secp256k1_schnorrsig_sign_custom(sign, sig, msg, sizeof(msg), &keypairs[0], &extraparams) == 1); - CHECK(ecount == 2); + CHECK(ecount == 0); CHECK(secp256k1_schnorrsig_sign_custom(sign, NULL, msg, sizeof(msg), &keypairs[0], &extraparams) == 0); - CHECK(ecount == 3); + CHECK(ecount == 1); CHECK(secp256k1_schnorrsig_sign_custom(sign, sig, NULL, sizeof(msg), &keypairs[0], &extraparams) == 0); - CHECK(ecount == 4); + CHECK(ecount == 2); CHECK(secp256k1_schnorrsig_sign_custom(sign, sig, NULL, 0, &keypairs[0], &extraparams) == 1); - CHECK(ecount == 4); + CHECK(ecount == 2); CHECK(secp256k1_schnorrsig_sign_custom(sign, sig, msg, sizeof(msg), NULL, &extraparams) == 0); - CHECK(ecount == 5); + CHECK(ecount == 3); CHECK(secp256k1_schnorrsig_sign_custom(sign, sig, msg, sizeof(msg), &invalid_keypair, &extraparams) == 0); - CHECK(ecount == 6); + CHECK(ecount == 4); CHECK(secp256k1_schnorrsig_sign_custom(sign, sig, msg, sizeof(msg), &keypairs[0], NULL) == 1); - CHECK(ecount == 6); + CHECK(ecount == 4); CHECK(secp256k1_schnorrsig_sign_custom(sign, sig, msg, sizeof(msg), &keypairs[0], &invalid_extraparams) == 0); - CHECK(ecount == 7); + CHECK(ecount == 5); + CHECK(secp256k1_schnorrsig_sign_custom(sttc, sig, msg, sizeof(msg), &keypairs[0], &extraparams) == 0); + CHECK(ecount == 6); ecount = 0; CHECK(secp256k1_schnorrsig_sign(sign, sig, msg, &keypairs[0], NULL) == 1); @@ -217,6 +224,7 @@ void test_schnorrsig_api(void) { secp256k1_context_destroy(sign); secp256k1_context_destroy(vrfy); secp256k1_context_destroy(both); + secp256k1_context_destroy(sttc); } /* Checks that hash initialized by secp256k1_schnorrsig_sha256_tagged has the diff --git a/src/secp256k1.c b/src/secp256k1.c index 9b1141376..53f35f715 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -98,18 +98,12 @@ size_t secp256k1_context_preallocated_size(unsigned int flags) { return 0; } - if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN) { - ret += SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE; - } return ret; } size_t secp256k1_context_preallocated_clone_size(const secp256k1_context* ctx) { size_t ret = ROUND_TO_ALIGN(sizeof(secp256k1_context)); VERIFY_CHECK(ctx != NULL); - if (secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)) { - ret += SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE; - } return ret; } @@ -131,13 +125,9 @@ secp256k1_context* secp256k1_context_preallocated_create(void* prealloc, unsigne ret->illegal_callback = default_illegal_callback; ret->error_callback = default_error_callback; - secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx); - /* Flags have been checked by secp256k1_context_preallocated_size. */ VERIFY_CHECK((flags & SECP256K1_FLAGS_TYPE_MASK) == SECP256K1_FLAGS_TYPE_CONTEXT); - if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN) { - secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &prealloc); - } + secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx); ret->declassify = !!(flags & SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY); return (secp256k1_context*) ret; @@ -163,7 +153,6 @@ secp256k1_context* secp256k1_context_preallocated_clone(const secp256k1_context* prealloc_size = secp256k1_context_preallocated_clone_size(ctx); ret = (secp256k1_context*)prealloc; memcpy(ret, ctx, prealloc_size); - secp256k1_ecmult_gen_context_finalize_memcpy(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx); return ret; } diff --git a/src/tests.c b/src/tests.c index 6027ebc07..e53eb02d4 100644 --- a/src/tests.c +++ b/src/tests.c @@ -143,10 +143,12 @@ void run_context_tests(int use_prealloc) { secp256k1_context *sign; secp256k1_context *vrfy; secp256k1_context *both; + secp256k1_context *sttc; void *none_prealloc = NULL; void *sign_prealloc = NULL; void *vrfy_prealloc = NULL; void *both_prealloc = NULL; + void *sttc_prealloc = NULL; secp256k1_gej pubj; secp256k1_ge pub; @@ -158,26 +160,30 @@ void run_context_tests(int use_prealloc) { sign_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN)); vrfy_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY)); both_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); + sttc_prealloc = malloc(secp256k1_context_preallocated_clone_size(secp256k1_context_no_precomp)); CHECK(none_prealloc != NULL); CHECK(sign_prealloc != NULL); CHECK(vrfy_prealloc != NULL); CHECK(both_prealloc != NULL); + CHECK(sttc_prealloc != NULL); none = secp256k1_context_preallocated_create(none_prealloc, SECP256K1_CONTEXT_NONE); sign = secp256k1_context_preallocated_create(sign_prealloc, SECP256K1_CONTEXT_SIGN); vrfy = secp256k1_context_preallocated_create(vrfy_prealloc, SECP256K1_CONTEXT_VERIFY); both = secp256k1_context_preallocated_create(both_prealloc, SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + sttc = secp256k1_context_preallocated_clone(secp256k1_context_no_precomp, sttc_prealloc); } else { none = secp256k1_context_create(SECP256K1_CONTEXT_NONE); sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + sttc = secp256k1_context_clone(secp256k1_context_no_precomp); } memset(&zero_pubkey, 0, sizeof(zero_pubkey)); ecount = 0; ecount2 = 10; - secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(sttc, counting_illegal_callback_fn, &ecount); secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount2); /* set error callback (to a function that still aborts in case malloc() fails in secp256k1_context_clone() below) */ secp256k1_context_set_error_callback(sign, secp256k1_default_illegal_callback_fn, NULL); @@ -189,6 +195,7 @@ void run_context_tests(int use_prealloc) { CHECK(secp256k1_context_preallocated_clone_size(sign) == secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN)); CHECK(secp256k1_context_preallocated_clone_size(vrfy) == secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY)); CHECK(secp256k1_context_preallocated_clone_size(both) == secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)); + CHECK(secp256k1_context_preallocated_clone_size(sttc) >= sizeof(secp256k1_context)); /*** clone and destroy all of them to make sure cloning was complete ***/ { @@ -252,12 +259,12 @@ void run_context_tests(int use_prealloc) { /* Verify context-type checking illegal-argument errors. */ memset(ctmp, 1, 32); - CHECK(secp256k1_ec_pubkey_create(vrfy, &pubkey, ctmp) == 0); + CHECK(secp256k1_ec_pubkey_create(sttc, &pubkey, ctmp) == 0); CHECK(ecount == 1); VG_UNDEF(&pubkey, sizeof(pubkey)); CHECK(secp256k1_ec_pubkey_create(sign, &pubkey, ctmp) == 1); VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ecdsa_sign(vrfy, &sig, ctmp, ctmp, NULL, NULL) == 0); + CHECK(secp256k1_ecdsa_sign(sttc, &sig, ctmp, ctmp, NULL, NULL) == 0); CHECK(ecount == 2); VG_UNDEF(&sig, sizeof(sig)); CHECK(secp256k1_ecdsa_sign(sign, &sig, ctmp, ctmp, NULL, NULL) == 1); @@ -265,33 +272,33 @@ void run_context_tests(int use_prealloc) { CHECK(ecount2 == 10); CHECK(secp256k1_ecdsa_verify(sign, &sig, ctmp, &pubkey) == 1); CHECK(ecount2 == 10); - CHECK(secp256k1_ecdsa_verify(vrfy, &sig, ctmp, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(sttc, &sig, ctmp, &pubkey) == 1); CHECK(ecount == 2); CHECK(secp256k1_ec_pubkey_tweak_add(sign, &pubkey, ctmp) == 1); CHECK(ecount2 == 10); - CHECK(secp256k1_ec_pubkey_tweak_add(vrfy, &pubkey, ctmp) == 1); + CHECK(secp256k1_ec_pubkey_tweak_add(sttc, &pubkey, ctmp) == 1); CHECK(ecount == 2); CHECK(secp256k1_ec_pubkey_tweak_mul(sign, &pubkey, ctmp) == 1); CHECK(ecount2 == 10); - CHECK(secp256k1_ec_pubkey_negate(vrfy, &pubkey) == 1); + CHECK(secp256k1_ec_pubkey_negate(sttc, &pubkey) == 1); CHECK(ecount == 2); CHECK(secp256k1_ec_pubkey_negate(sign, &pubkey) == 1); CHECK(ecount == 2); CHECK(secp256k1_ec_pubkey_negate(sign, NULL) == 0); CHECK(ecount2 == 11); - CHECK(secp256k1_ec_pubkey_negate(vrfy, &zero_pubkey) == 0); + CHECK(secp256k1_ec_pubkey_negate(sttc, &zero_pubkey) == 0); CHECK(ecount == 3); - CHECK(secp256k1_ec_pubkey_tweak_mul(vrfy, &pubkey, ctmp) == 1); + CHECK(secp256k1_ec_pubkey_tweak_mul(sttc, &pubkey, ctmp) == 1); CHECK(ecount == 3); - CHECK(secp256k1_context_randomize(vrfy, ctmp) == 1); + CHECK(secp256k1_context_randomize(sttc, ctmp) == 1); CHECK(ecount == 3); - CHECK(secp256k1_context_randomize(vrfy, NULL) == 1); + CHECK(secp256k1_context_randomize(sttc, NULL) == 1); CHECK(ecount == 3); CHECK(secp256k1_context_randomize(sign, ctmp) == 1); CHECK(ecount2 == 11); CHECK(secp256k1_context_randomize(sign, NULL) == 1); CHECK(ecount2 == 11); - secp256k1_context_set_illegal_callback(vrfy, NULL, NULL); + secp256k1_context_set_illegal_callback(sttc, NULL, NULL); secp256k1_context_set_illegal_callback(sign, NULL, NULL); /* obtain a working nonce */ @@ -313,15 +320,18 @@ void run_context_tests(int use_prealloc) { secp256k1_context_preallocated_destroy(sign); secp256k1_context_preallocated_destroy(vrfy); secp256k1_context_preallocated_destroy(both); + secp256k1_context_preallocated_destroy(sttc); free(none_prealloc); free(sign_prealloc); free(vrfy_prealloc); free(both_prealloc); + free(sttc_prealloc); } else { secp256k1_context_destroy(none); secp256k1_context_destroy(sign); secp256k1_context_destroy(vrfy); secp256k1_context_destroy(both); + secp256k1_context_destroy(sttc); } /* Defined as no-op. */ secp256k1_context_destroy(NULL);