diff --git a/src/ecmult.h b/src/ecmult.h index 17f2ad9772..722294c89d 100644 --- a/src/ecmult.h +++ b/src/ecmult.h @@ -22,7 +22,7 @@ typedef struct { static size_t secp256k1_ecmult_context_prealloc_size(void); static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx); -static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb); +static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, void **prealloc); static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, const secp256k1_ecmult_context *src, const secp256k1_callback *cb); static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx); diff --git a/src/ecmult_gen.h b/src/ecmult_gen.h index 8d95c778f8..2b694fd9e6 100644 --- a/src/ecmult_gen.h +++ b/src/ecmult_gen.h @@ -30,7 +30,7 @@ typedef struct { static size_t secp256k1_ecmult_gen_context_prealloc_size(void); static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context* ctx); -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx, const secp256k1_callback* cb); +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx, void **prealloc); static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, const secp256k1_ecmult_gen_context* src, const secp256k1_callback* cb); static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); diff --git a/src/ecmult_gen_impl.h b/src/ecmult_gen_impl.h index 3c5360329b..c095f5bf7d 100644 --- a/src/ecmult_gen_impl.h +++ b/src/ecmult_gen_impl.h @@ -28,19 +28,20 @@ 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, const secp256k1_callback* cb) { +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx, void **prealloc) { #ifndef USE_ECMULT_STATIC_PRECOMPUTATION secp256k1_ge prec[1024]; secp256k1_gej gj; secp256k1_gej nums_gej; int i, j; + size_t ctx_size = secp256k1_ecmult_gen_context_prealloc_size(); #endif if (ctx->prec != NULL) { return; } #ifndef USE_ECMULT_STATIC_PRECOMPUTATION - ctx->prec = (secp256k1_ge_storage (*)[64][16])checked_malloc(cb, sizeof(*ctx->prec)); + ctx->prec = (secp256k1_ge_storage (*)[64][16])manual_alloc(prealloc, ctx_size, *prealloc, ctx_size); /* get the generator */ secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); @@ -95,7 +96,7 @@ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx } } #else - (void)cb; + (void)prealloc; ctx->prec = (secp256k1_ge_storage (*)[64][16])secp256k1_ecmult_static_context; #endif secp256k1_ecmult_gen_blind(ctx, NULL); @@ -123,9 +124,6 @@ static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst } static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx) { -#ifndef USE_ECMULT_STATIC_PRECOMPUTATION - free(ctx->prec); -#endif secp256k1_scalar_clear(&ctx->blind); secp256k1_gej_clear(&ctx->initial); ctx->prec = NULL; diff --git a/src/ecmult_impl.h b/src/ecmult_impl.h index 7585cb4b44..b4b669880e 100644 --- a/src/ecmult_impl.h +++ b/src/ecmult_impl.h @@ -269,8 +269,10 @@ static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx) { #endif } -static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb) { +static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, void **prealloc) { secp256k1_gej gj; + void* const base = *prealloc; + size_t const prealloc_size = secp256k1_ecmult_context_prealloc_size(); if (ctx->pre_g != NULL) { return; @@ -279,7 +281,7 @@ static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const /* get the generator */ secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); - ctx->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); + ctx->pre_g = (secp256k1_ge_storage (*)[])manual_alloc(prealloc, sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G), base, prealloc_size); /* precompute the tables with odd multiples */ secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g, &gj); @@ -289,7 +291,7 @@ static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_gej g_128j; int i; - ctx->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); + ctx->pre_g_128 = (secp256k1_ge_storage (*)[])manual_alloc(prealloc, sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G), base, prealloc_size); /* calculate 2^128*generator */ g_128j = gj; @@ -326,10 +328,6 @@ static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx } static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx) { - free(ctx->pre_g); -#ifdef USE_ENDOMORPHISM - free(ctx->pre_g_128); -#endif secp256k1_ecmult_context_init(ctx); } diff --git a/src/secp256k1.c b/src/secp256k1.c index 05316bcb10..3f0f7512fc 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -83,15 +83,18 @@ size_t secp256k1_context_prealloc_size(unsigned int flags) { return ret; } -secp256k1_context* secp256k1_context_create(unsigned int flags) { - secp256k1_context* ret = (secp256k1_context*)checked_malloc(&default_error_callback, sizeof(secp256k1_context)); +secp256k1_context* secp256k1_context_prealloc_create(void* prealloc, unsigned int flags) { + void* const base = prealloc; + size_t const ctx_size = secp256k1_context_prealloc_size(flags); + secp256k1_context* ret = (secp256k1_context*)manual_alloc(&prealloc, sizeof(secp256k1_context), base, ctx_size); + ret->illegal_callback = default_illegal_callback; ret->error_callback = default_error_callback; if (EXPECT((flags & SECP256K1_FLAGS_TYPE_MASK) != SECP256K1_FLAGS_TYPE_CONTEXT, 0)) { secp256k1_callback_call(&ret->illegal_callback, "Invalid flags"); - free(ret); + /* Unreachable */ return NULL; } @@ -99,13 +102,24 @@ secp256k1_context* secp256k1_context_create(unsigned int flags) { secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx); if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN) { - secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &ret->error_callback); + secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &prealloc); } if (flags & SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) { - secp256k1_ecmult_context_build(&ret->ecmult_ctx, &ret->error_callback); + secp256k1_ecmult_context_build(&ret->ecmult_ctx, &prealloc); } - return ret; + return (secp256k1_context*) ret; +} + +secp256k1_context* secp256k1_context_create(unsigned int flags) { + size_t ctx_size = secp256k1_context_prealloc_size(flags); + secp256k1_context* ctx = (secp256k1_context*) checked_malloc(&default_error_callback, ctx_size); + if (secp256k1_context_prealloc_create(ctx, flags) == NULL) { + free(ctx); + return NULL; + } + + return ctx; } secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { @@ -117,11 +131,16 @@ secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { return ret; } -void secp256k1_context_destroy(secp256k1_context* ctx) { +void secp256k1_context_prealloc_destroy(secp256k1_context* ctx) { if (ctx != NULL) { secp256k1_ecmult_context_clear(&ctx->ecmult_ctx); secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); + } +} +void secp256k1_context_destroy(secp256k1_context* ctx) { + if (ctx != NULL) { + secp256k1_context_prealloc_destroy(ctx); free(ctx); } }