From ed7c08417a957c91f3e8148fe7c828a9cc1f5211 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Wed, 15 Aug 2018 21:27:25 +0000 Subject: [PATCH 1/2] add static context object which has no capabilities --- include/secp256k1.h | 7 +++++++ src/secp256k1.c | 8 ++++++++ src/tests.c | 1 + 3 files changed, 16 insertions(+) diff --git a/include/secp256k1.h b/include/secp256k1.h index 3c4a311a05681..f1f78ab7d084d 100644 --- a/include/secp256k1.h +++ b/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.c b/src/secp256k1.c index cd0972dfaf464..972fee50f6e73 100644 --- a/src/secp256k1.c +++ b/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; diff --git a/src/tests.c b/src/tests.c index 15f44914b2e5d..c72a742d87f8d 100644 --- a/src/tests.c +++ b/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)); From 40fde611bd145bdafb78a52af6d197489101bafb Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Thu, 20 Sep 2018 17:50:43 +0000 Subject: [PATCH 2/2] prevent attempts to modify `secp256k1_context_no_precomp` --- src/secp256k1.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/secp256k1.c b/src/secp256k1.c index 972fee50f6e73..a1e3908071a5e 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -99,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); @@ -108,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; } @@ -116,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; } @@ -567,6 +570,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;