csecp256k1

secp256k1 bindings.
Log | Files | Refs | README | LICENSE

commit 64cca94882ed78a1b96cb04e2dfd6e724c2d4a28
parent 62f5420de4650f8aa5152dc795a06f7a0399dd04
Author: Jared Tobin <jared@jtobin.io>
Date:   Mon, 12 Feb 2024 17:23:04 +0400

Don't patch out malloc methods.

The Rust implementation does this to support compiling to WASM, but we
don't need to at present.

Diffstat:
Msecp256k1-sys/depend/secp256k1/include/secp256k1.h | 27+++++++++++++++++++++++++++
Msecp256k1-sys/depend/secp256k1/src/scratch_impl.h | 25+++++++++++++++++++++++++
Msecp256k1-sys/depend/secp256k1/src/secp256k1.c | 46++++++++++++++++++++++++++++++++++++++++++++++
Msecp256k1-sys/depend/secp256k1/src/util.h | 8+++++---
Msecp256k1-sys/vendor-libsecp.sh | 8++++----
5 files changed, 107 insertions(+), 7 deletions(-)

diff --git a/secp256k1-sys/depend/secp256k1/include/secp256k1.h b/secp256k1-sys/depend/secp256k1/include/secp256k1.h @@ -233,8 +233,11 @@ typedef int (*haskellsecp256k1_v0_1_0_nonce_function)( * * It is highly recommended to call haskellsecp256k1_v0_1_0_selftest before using this context. */ +SECP256K1_API const haskellsecp256k1_v0_1_0_context *haskellsecp256k1_v0_1_0_context_static; /** Deprecated alias for haskellsecp256k1_v0_1_0_context_static. */ +SECP256K1_API const haskellsecp256k1_v0_1_0_context *haskellsecp256k1_v0_1_0_context_no_precomp +SECP256K1_DEPRECATED("Use haskellsecp256k1_v0_1_0_context_static instead"); /** Perform basic self tests (to be used in conjunction with haskellsecp256k1_v0_1_0_context_static) * @@ -280,6 +283,10 @@ SECP256K1_API void haskellsecp256k1_v0_1_0_selftest(void); * Do not create a new context object for each operation, as construction and * randomization can take non-negligible time. */ +SECP256K1_API haskellsecp256k1_v0_1_0_context *haskellsecp256k1_v0_1_0_context_create( + unsigned int flags +) SECP256K1_WARN_UNUSED_RESULT; + /** Copy a secp256k1 context object (into dynamically allocated memory). * * This function uses malloc to allocate memory. It is guaranteed that malloc is @@ -292,6 +299,10 @@ SECP256K1_API void haskellsecp256k1_v0_1_0_selftest(void); * Returns: pointer to a newly created context object. * Args: ctx: pointer to a context to copy (not haskellsecp256k1_v0_1_0_context_static). */ +SECP256K1_API haskellsecp256k1_v0_1_0_context *haskellsecp256k1_v0_1_0_context_clone( + const haskellsecp256k1_v0_1_0_context *ctx +) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; + /** Destroy a secp256k1 context object (created in dynamically allocated memory). * * The context pointer may not be used afterwards. @@ -306,6 +317,10 @@ SECP256K1_API void haskellsecp256k1_v0_1_0_selftest(void); * haskellsecp256k1_v0_1_0_context_create or haskellsecp256k1_v0_1_0_context_clone * (i.e., not haskellsecp256k1_v0_1_0_context_static). */ +SECP256K1_API void haskellsecp256k1_v0_1_0_context_destroy( + haskellsecp256k1_v0_1_0_context *ctx +) SECP256K1_ARG_NONNULL(1); + /** Set a callback function to be called when an illegal argument is passed to * an API call. It will only trigger for violations that are mentioned * explicitly in the header. @@ -384,12 +399,22 @@ SECP256K1_API void haskellsecp256k1_v0_1_0_context_set_error_callback( * In: size: amount of memory to be available as scratch space. Some extra * (<100 bytes) will be allocated for extra accounting. */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT haskellsecp256k1_v0_1_0_scratch_space *haskellsecp256k1_v0_1_0_scratch_space_create( + const haskellsecp256k1_v0_1_0_context *ctx, + size_t size +) SECP256K1_ARG_NONNULL(1); + /** Destroy a secp256k1 scratch space. * * The pointer may not be used afterwards. * Args: ctx: pointer to a context object. * scratch: space to destroy */ +SECP256K1_API void haskellsecp256k1_v0_1_0_scratch_space_destroy( + const haskellsecp256k1_v0_1_0_context *ctx, + haskellsecp256k1_v0_1_0_scratch_space *scratch +) SECP256K1_ARG_NONNULL(1); + /** Parse a variable-length public key into the pubkey object. * * Returns: 1 if the public key was fully valid. @@ -608,8 +633,10 @@ SECP256K1_API int haskellsecp256k1_v0_1_0_ecdsa_signature_normalize( * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of * extra entropy. */ +SECP256K1_API const haskellsecp256k1_v0_1_0_nonce_function haskellsecp256k1_v0_1_0_nonce_function_rfc6979; /** A default safe nonce generation function (currently equal to haskellsecp256k1_v0_1_0_nonce_function_rfc6979). */ +SECP256K1_API const haskellsecp256k1_v0_1_0_nonce_function haskellsecp256k1_v0_1_0_nonce_function_default; /** Create an ECDSA signature. * diff --git a/secp256k1-sys/depend/secp256k1/src/scratch_impl.h b/secp256k1-sys/depend/secp256k1/src/scratch_impl.h @@ -10,6 +10,31 @@ #include "util.h" #include "scratch.h" +static haskellsecp256k1_v0_1_0_scratch* haskellsecp256k1_v0_1_0_scratch_create(const haskellsecp256k1_v0_1_0_callback* error_callback, size_t size) { + const size_t base_alloc = ROUND_TO_ALIGN(sizeof(haskellsecp256k1_v0_1_0_scratch)); + void *alloc = checked_malloc(error_callback, base_alloc + size); + haskellsecp256k1_v0_1_0_scratch* ret = (haskellsecp256k1_v0_1_0_scratch *)alloc; + if (ret != NULL) { + memset(ret, 0, sizeof(*ret)); + memcpy(ret->magic, "scratch", 8); + ret->data = (void *) ((char *) alloc + base_alloc); + ret->max_size = size; + } + return ret; +} + +static void haskellsecp256k1_v0_1_0_scratch_destroy(const haskellsecp256k1_v0_1_0_callback* error_callback, haskellsecp256k1_v0_1_0_scratch* scratch) { + if (scratch != NULL) { + if (haskellsecp256k1_v0_1_0_memcmp_var(scratch->magic, "scratch", 8) != 0) { + haskellsecp256k1_v0_1_0_callback_call(error_callback, "invalid scratch space"); + return; + } + VERIFY_CHECK(scratch->alloc_size == 0); /* all checkpoints should be applied */ + memset(scratch->magic, 0, sizeof(scratch->magic)); + free(scratch); + } +} + static size_t haskellsecp256k1_v0_1_0_scratch_checkpoint(const haskellsecp256k1_v0_1_0_callback* error_callback, const haskellsecp256k1_v0_1_0_scratch* scratch) { if (haskellsecp256k1_v0_1_0_memcmp_var(scratch->magic, "scratch", 8) != 0) { haskellsecp256k1_v0_1_0_callback_call(error_callback, "invalid scratch space"); diff --git a/secp256k1-sys/depend/secp256k1/src/secp256k1.c b/secp256k1-sys/depend/secp256k1/src/secp256k1.c @@ -137,6 +137,17 @@ haskellsecp256k1_v0_1_0_context* haskellsecp256k1_v0_1_0_context_preallocated_cr return ret; } +haskellsecp256k1_v0_1_0_context* haskellsecp256k1_v0_1_0_context_create(unsigned int flags) { + size_t const prealloc_size = haskellsecp256k1_v0_1_0_context_preallocated_size(flags); + haskellsecp256k1_v0_1_0_context* ctx = (haskellsecp256k1_v0_1_0_context*)checked_malloc(&default_error_callback, prealloc_size); + if (EXPECT(haskellsecp256k1_v0_1_0_context_preallocated_create(ctx, flags) == NULL, 0)) { + free(ctx); + return NULL; + } + + return ctx; +} + haskellsecp256k1_v0_1_0_context* haskellsecp256k1_v0_1_0_context_preallocated_clone(const haskellsecp256k1_v0_1_0_context* ctx, void* prealloc) { haskellsecp256k1_v0_1_0_context* ret; VERIFY_CHECK(ctx != NULL); @@ -148,6 +159,19 @@ haskellsecp256k1_v0_1_0_context* haskellsecp256k1_v0_1_0_context_preallocated_cl return ret; } +haskellsecp256k1_v0_1_0_context* haskellsecp256k1_v0_1_0_context_clone(const haskellsecp256k1_v0_1_0_context* ctx) { + haskellsecp256k1_v0_1_0_context* ret; + size_t prealloc_size; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(haskellsecp256k1_v0_1_0_context_is_proper(ctx)); + + prealloc_size = haskellsecp256k1_v0_1_0_context_preallocated_clone_size(ctx); + ret = (haskellsecp256k1_v0_1_0_context*)checked_malloc(&ctx->error_callback, prealloc_size); + ret = haskellsecp256k1_v0_1_0_context_preallocated_clone(ctx, ret); + return ret; +} + void haskellsecp256k1_v0_1_0_context_preallocated_destroy(haskellsecp256k1_v0_1_0_context* ctx) { ARG_CHECK_VOID(ctx == NULL || haskellsecp256k1_v0_1_0_context_is_proper(ctx)); @@ -159,6 +183,18 @@ void haskellsecp256k1_v0_1_0_context_preallocated_destroy(haskellsecp256k1_v0_1_ haskellsecp256k1_v0_1_0_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); } +void haskellsecp256k1_v0_1_0_context_destroy(haskellsecp256k1_v0_1_0_context* ctx) { + ARG_CHECK_VOID(ctx == NULL || haskellsecp256k1_v0_1_0_context_is_proper(ctx)); + + /* Defined as noop */ + if (ctx == NULL) { + return; + } + + haskellsecp256k1_v0_1_0_context_preallocated_destroy(ctx); + free(ctx); +} + void haskellsecp256k1_v0_1_0_context_set_illegal_callback(haskellsecp256k1_v0_1_0_context* ctx, void (*fun)(const char* message, void* data), const void* data) { /* We compare pointers instead of checking haskellsecp256k1_v0_1_0_context_is_proper() here because setting callbacks is allowed on *copies* of the static context: @@ -183,6 +219,16 @@ void haskellsecp256k1_v0_1_0_context_set_error_callback(haskellsecp256k1_v0_1_0_ ctx->error_callback.data = data; } +haskellsecp256k1_v0_1_0_scratch_space* haskellsecp256k1_v0_1_0_scratch_space_create(const haskellsecp256k1_v0_1_0_context* ctx, size_t max_size) { + VERIFY_CHECK(ctx != NULL); + return haskellsecp256k1_v0_1_0_scratch_create(&ctx->error_callback, max_size); +} + +void haskellsecp256k1_v0_1_0_scratch_space_destroy(const haskellsecp256k1_v0_1_0_context *ctx, haskellsecp256k1_v0_1_0_scratch_space* scratch) { + VERIFY_CHECK(ctx != NULL); + haskellsecp256k1_v0_1_0_scratch_destroy(&ctx->error_callback, scratch); +} + /* Mark memory as no-longer-secret for the purpose of analysing constant-time behaviour * of the software. */ diff --git a/secp256k1-sys/depend/secp256k1/src/util.h b/secp256k1-sys/depend/secp256k1/src/util.h @@ -154,9 +154,11 @@ static const haskellsecp256k1_v0_1_0_callback default_error_callback = { #endif static SECP256K1_INLINE void *checked_malloc(const haskellsecp256k1_v0_1_0_callback* cb, size_t size) { - (void) cb; - (void) size; - return NULL; + void *ret = malloc(size); + if (ret == NULL) { + haskellsecp256k1_v0_1_0_callback_call(cb, "Out of memory"); + } + return ret; } #if defined(__BIGGEST_ALIGNMENT__) diff --git a/secp256k1-sys/vendor-libsecp.sh b/secp256k1-sys/vendor-libsecp.sh @@ -96,10 +96,10 @@ echo "$SOURCE_REV" >> ./secp256k1-HEAD-revision.txt # Remove all methods that use malloc. # To compensate, the secp_context_create and _destroy methods are redefined in Haskell. -patch "$DIR/include/secp256k1.h" "./secp256k1.h.patch" -patch "$DIR/src/secp256k1.c" "./secp256k1.c.patch" -patch "$DIR/src/scratch_impl.h" "./scratch_impl.h.patch" -patch "$DIR/src/util.h" "./util.h.patch" +# patch "$DIR/include/secp256k1.h" "./secp256k1.h.patch" +# patch "$DIR/src/secp256k1.c" "./secp256k1.c.patch" +# patch "$DIR/src/scratch_impl.h" "./scratch_impl.h.patch" +# patch "$DIR/src/util.h" "./util.h.patch" # Fix a linking error while cross-compiling to windowns with mingw patch "$DIR/contrib/lax_der_parsing.c" "./lax_der_parsing.c.patch"