diff --git a/src/secp256k1.c b/src/secp256k1.c index 9055f7b6cf06a..4898cf5e878b4 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -82,6 +82,17 @@ size_t secp256k1_context_preallocated_size(unsigned int flags) { return ret; } +size_t secp256k1_context_preallocated_clone_size(const secp256k1_context* ctx) { + size_t ret = ROUND_TO_ALIGN(sizeof(secp256k1_context)); + if (secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)) { + ret += SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE; + } + if (secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)) { + ret += SECP256K1_ECMULT_CONTEXT_PREALLOCATED_SIZE; + } + return ret; +} + secp256k1_context* secp256k1_context_preallocated_create(void* prealloc, unsigned int flags) { void* const base = prealloc; size_t prealloc_size = secp256k1_context_preallocated_size(flags); @@ -120,22 +131,22 @@ secp256k1_context* secp256k1_context_create(unsigned int flags) { return ctx; } -secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { - secp256k1_context* ret; - size_t prealloc_size = ROUND_TO_ALIGN(sizeof(secp256k1_context)); - if (secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)) { - prealloc_size += SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE; - } - if (secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)) { - prealloc_size += SECP256K1_ECMULT_CONTEXT_PREALLOCATED_SIZE; - } - ret = checked_malloc(&ctx->error_callback, prealloc_size); +secp256k1_context* secp256k1_context_preallocated_clone(const secp256k1_context* ctx, void* prealloc) { + size_t prealloc_size = secp256k1_context_preallocated_clone_size(ctx); + secp256k1_context* ret = (secp256k1_context*)prealloc; memcpy(ret, ctx, prealloc_size); secp256k1_ecmult_gen_context_finalize_memcpy(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx); secp256k1_ecmult_context_finalize_memcpy(&ret->ecmult_ctx, &ctx->ecmult_ctx); return ret; } +secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { + size_t prealloc_size = secp256k1_context_preallocated_clone_size(ctx); + secp256k1_context* ret = (secp256k1_context*)checked_malloc(&ctx->error_callback, prealloc_size); + ret = secp256k1_context_preallocated_clone(ctx, ret); + return ret; +} + void secp256k1_context_preallocated_destroy(secp256k1_context* ctx) { CHECK(ctx != secp256k1_context_no_precomp); if (ctx != NULL) {