From 1b33c16326f02d98d15f15a728c71cbf53daf516 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Wed, 15 Aug 2018 21:27:25 +0000 Subject: [PATCH] add static context object which has no capabilities Summary: * prevent attempts to modify `secp256k1_context_no_precomp` This is a backport of secp256k1's PR553 Test Plan: ninja check-secp256k1 Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D4971 --- src/secp256k1/include/secp256k1.h | 7 +++++++ src/secp256k1/src/secp256k1.c | 12 ++++++++++++ src/secp256k1/src/tests.c | 1 + 3 files changed, 20 insertions(+) diff --git a/src/secp256k1/include/secp256k1.h b/src/secp256k1/include/secp256k1.h index 3c4a311a056..f1f78ab7d08 100644 --- a/src/secp256k1/include/secp256k1.h +++ b/src/secp256k1/include/secp256k1.h @@ -179,6 +179,13 @@ typedef int (*secp256k1_nonce_function)( #define SECP256K1_TAG_PUBKEY_HYBRID_EVEN 0x06 #define SECP256K1_TAG_PUBKEY_HYBRID_ODD 0x07 +/** A simple secp256k1 context object with no precomputed tables. These are useful for + * type serialization/parsing functions which require a context object to maintain + * API consistency, but currently do not require expensive precomputations or dynamic + * allocations. + */ +SECP256K1_API extern const secp256k1_context *secp256k1_context_no_precomp; + /** Create a secp256k1 context object. * * Returns: a newly created context object. diff --git a/src/secp256k1/src/secp256k1.c b/src/secp256k1/src/secp256k1.c index 3af4d5d8bf9..8529e4dc0a5 100644 --- a/src/secp256k1/src/secp256k1.c +++ b/src/secp256k1/src/secp256k1.c @@ -56,6 +56,14 @@ struct secp256k1_context_struct { secp256k1_callback error_callback; }; +static const secp256k1_context secp256k1_context_no_precomp_ = { + { 0 }, + { 0 }, + { default_illegal_callback_fn, 0 }, + { default_error_callback_fn, 0 } +}; +const secp256k1_context *secp256k1_context_no_precomp = &secp256k1_context_no_precomp_; + secp256k1_context* secp256k1_context_create(unsigned int flags) { secp256k1_context* ret = (secp256k1_context*)checked_malloc(&default_error_callback, sizeof(secp256k1_context)); ret->illegal_callback = default_illegal_callback; @@ -91,6 +99,7 @@ secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { } void secp256k1_context_destroy(secp256k1_context* ctx) { + CHECK(ctx != secp256k1_context_no_precomp); if (ctx != NULL) { secp256k1_ecmult_context_clear(&ctx->ecmult_ctx); secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); @@ -100,6 +109,7 @@ void secp256k1_context_destroy(secp256k1_context* ctx) { } void secp256k1_context_set_illegal_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { + CHECK(ctx != secp256k1_context_no_precomp); if (fun == NULL) { fun = default_illegal_callback_fn; } @@ -108,6 +118,7 @@ void secp256k1_context_set_illegal_callback(secp256k1_context* ctx, void (*fun)( } void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { + CHECK(ctx != secp256k1_context_no_precomp); if (fun == NULL) { fun = default_error_callback_fn; } @@ -560,6 +571,7 @@ int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context* ctx, secp256k1_pubkey int secp256k1_context_randomize(secp256k1_context* ctx, const unsigned char *seed32) { VERIFY_CHECK(ctx != NULL); + CHECK(ctx != secp256k1_context_no_precomp); ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); return 1; diff --git a/src/secp256k1/src/tests.c b/src/secp256k1/src/tests.c index 0a12d108475..046c0eb1ddb 100644 --- a/src/secp256k1/src/tests.c +++ b/src/secp256k1/src/tests.c @@ -3599,6 +3599,7 @@ void run_ec_pubkey_parse_test(void) { ecount = 0; VG_UNDEF(&pubkey, sizeof(pubkey)); CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 65) == 1); + CHECK(secp256k1_ec_pubkey_parse(secp256k1_context_no_precomp, &pubkey, pubkeyc, 65) == 1); VG_CHECK(&pubkey, sizeof(pubkey)); CHECK(ecount == 0); VG_UNDEF(&ge, sizeof(ge));