From dc2944ff8eb61f0232a4d02899edcbff88022447 Mon Sep 17 00:00:00 2001 From: siv2r Date: Mon, 16 May 2022 17:12:51 +0530 Subject: [PATCH] batch_interface: refactor to support secp256k1_context secp256k1_context obj is used for its error_callback function --- include/secp256k1_schnorrsig.h | 13 ++++- src/modules/schnorrsig/main_impl.h | 89 +++++++++++++++++++---------- src/modules/schnorrsig/tests_impl.h | 4 +- 3 files changed, 72 insertions(+), 34 deletions(-) diff --git a/include/secp256k1_schnorrsig.h b/include/secp256k1_schnorrsig.h index 6643b2271b..d05bdafab0 100644 --- a/include/secp256k1_schnorrsig.h +++ b/include/secp256k1_schnorrsig.h @@ -180,12 +180,19 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify( typedef struct secp256k1_schnorrsig_batch_context_struct secp256k1_schnorrsig_batch_context; SECP256K1_API secp256k1_schnorrsig_batch_context* secp256k1_schnorrsig_batch_context_create( + secp256k1_context* ctx, size_t n_terms -) SECP256K1_WARN_UNUSED_RESULT; +) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; SECP256K1_API void secp256k1_schnorrsig_batch_context_destroy( - secp256k1_schnorrsig_batch_context* ctx -) SECP256K1_ARG_NONNULL(1); + secp256k1_context* ctx, + secp256k1_schnorrsig_batch_context* batch_ctx +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); + +SECP256K1_API int secp256k1_schnorrsig_batch_context_verify( + secp256k1_context *ctx, + secp256k1_schnorrsig_batch_context *batch_ctx +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); #ifdef __cplusplus } diff --git a/src/modules/schnorrsig/main_impl.h b/src/modules/schnorrsig/main_impl.h index 493abff936..7fb82c6071 100644 --- a/src/modules/schnorrsig/main_impl.h +++ b/src/modules/schnorrsig/main_impl.h @@ -269,15 +269,39 @@ int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned cha /* schnorr batch verification interface */ +/** Opaque data structure. + * + * A schnorrsig_extraparams structure object can be initialized correctly by + * setting it to SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT. + * + * Members: + * data: set to SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC at initialization + * and has no other function than making sure the object is + * initialized. + * scalars: pointer to a nonce generation function. If NULL, + * secp256k1_nonce_function_bip340 is used + * points: pointer to arbitrary data used by the nonce generation function + * (can be NULL). If it is non-NULL and + * secp256k1_nonce_function_bip340 is used, then ndata must be a + * pointer to 32-byte auxiliary randomness as per BIP-340. + * sc_g: pointer to arbitrary data used by the nonce generation function + * (can be NULL). If it is non-NULL and + * len: pointer to arbitrary data used by the nonce generation function + * (can be NULL). If it is non-NULL and + * capacity: pointer to arbitrary data used by the nonce generation function + * (can be NULL). If it is non-NULL and + * result: pointer to arbitrary data used by the nonce generation function + * (can be NULL). If it is non-NULL and + */ struct secp256k1_schnorrsig_batch_context_struct{ - secp256k1_scratch *data; /*(scalar, Point)*/ - secp256k1_scalar *scalars; /* base ptr of scalars */ - secp256k1_gej *points; /* base ptr of Points */ - secp256k1_scalar sc_g; /* scalar of G */ + secp256k1_scratch *data; + secp256k1_scalar *scalars; + secp256k1_gej *points; + secp256k1_scalar sc_g; /* secp256k1_gej res_gej; final result as gej */ - size_t len; /* current len */ - size_t capacity; /* max possible len */ - int result; /* final result as success or fail */ + size_t len; + size_t capacity; + int result; }; size_t secp256k1_schnorrsig_batch_context_scratch_size(int n_terms) { @@ -288,11 +312,11 @@ size_t secp256k1_schnorrsig_batch_context_scratch_size(int n_terms) { return ret; } -secp256k1_schnorrsig_batch_context* secp256k1_schnorrsig_batch_context_create(size_t n_terms) { +secp256k1_schnorrsig_batch_context* secp256k1_schnorrsig_batch_context_create(secp256k1_context* ctx, size_t n_terms) { /* fail for n_terms 0, is this the right way to assert?*/ /* VERIFY_CHECK(n_terms != 0); */ - secp256k1_schnorrsig_batch_context* ctx = (secp256k1_schnorrsig_batch_context*)checked_malloc(&default_error_callback, sizeof(secp256k1_schnorrsig_batch_context)); + secp256k1_schnorrsig_batch_context* batch_ctx = (secp256k1_schnorrsig_batch_context*)checked_malloc(&default_error_callback, sizeof(secp256k1_schnorrsig_batch_context)); /* todo: is sizeof() != 0, check required here?*/ size_t scratch_size = secp256k1_schnorrsig_batch_context_scratch_size(2*n_terms); @@ -300,35 +324,42 @@ secp256k1_schnorrsig_batch_context* secp256k1_schnorrsig_batch_context_create(si /* create scratch for storing `2* n terms`--(point, scalar) and save inital checkpoint */ - ctx->data = secp256k1_scratch_create(NULL, scratch_size); - checkpoint = secp256k1_scratch_checkpoint(NULL, ctx->data); + batch_ctx->data = secp256k1_scratch_create(&ctx->error_callback, scratch_size); + checkpoint = secp256k1_scratch_checkpoint(&ctx->error_callback, batch_ctx->data); - ctx->scalars = (secp256k1_scalar*)secp256k1_scratch_alloc(NULL, ctx->data, 2*n_terms*sizeof(secp256k1_scalar)); - ctx->points = (secp256k1_gej*)secp256k1_scratch_alloc(NULL, ctx->data, 2*n_terms*sizeof(secp256k1_gej)); - if (ctx->scalars == NULL || ctx->points == NULL) { - secp256k1_scratch_apply_checkpoint(NULL, ctx->data, checkpoint); + batch_ctx->scalars = (secp256k1_scalar*)secp256k1_scratch_alloc(&ctx->error_callback, batch_ctx->data, 2*n_terms*sizeof(secp256k1_scalar)); + batch_ctx->points = (secp256k1_gej*)secp256k1_scratch_alloc(&ctx->error_callback, batch_ctx->data, 2*n_terms*sizeof(secp256k1_gej)); + if (batch_ctx->scalars == NULL || batch_ctx->points == NULL) { + secp256k1_scratch_apply_checkpoint(&ctx->error_callback, batch_ctx->data, checkpoint); return NULL; } - secp256k1_scalar_clear(&ctx->sc_g); - ctx->len = 0; - ctx->capacity = n_terms; - ctx->result = 0; + secp256k1_scalar_clear(&batch_ctx->sc_g); + batch_ctx->len = 0; + batch_ctx->capacity = n_terms; + batch_ctx->result = 0; - return ctx; + return batch_ctx; } -void secp256k1_schnorrsig_batch_context_destroy(secp256k1_schnorrsig_batch_context* ctx) { - if (ctx != NULL) { - if(ctx->data != NULL) { - secp256k1_scratch_apply_checkpoint(NULL, ctx->data, 0); - secp256k1_scratch_destroy(NULL, ctx->data); +void secp256k1_schnorrsig_batch_context_destroy(secp256k1_context* ctx, secp256k1_schnorrsig_batch_context* batch_ctx) { + if (batch_ctx != NULL) { + if(batch_ctx->data != NULL) { + secp256k1_scratch_apply_checkpoint(&ctx->error_callback, batch_ctx->data, 0); + secp256k1_scratch_destroy(&ctx->error_callback, batch_ctx->data); } - ctx->scalars = NULL; - ctx->points = NULL; - secp256k1_scalar_clear(&ctx->sc_g); - ctx->len = ctx->capacity = ctx->result = 0; + batch_ctx->scalars = NULL; + batch_ctx->points = NULL; + secp256k1_scalar_clear(&batch_ctx->sc_g); + batch_ctx->len = batch_ctx->capacity = batch_ctx->result = 0; } } +int secp256k1_schnorrsig_batch_context_verify(secp256k1_context* ctx, secp256k1_schnorrsig_batch_context* batch_ctx) { + secp256k1_gej resj; + batch_ctx->result = secp256k1_ecmult_strauss_batch(&ctx->error_callback, batch_ctx->data, &resj, batch_ctx->scalars, batch_ctx->points, &batch_ctx->sc_g, NULL, NULL, batch_ctx->len, 0) && secp256k1_gej_is_infinity(&resj); + + return batch_ctx->result; +} + #endif diff --git a/src/modules/schnorrsig/tests_impl.h b/src/modules/schnorrsig/tests_impl.h index 3f175f87bd..6a981f43ab 100644 --- a/src/modules/schnorrsig/tests_impl.h +++ b/src/modules/schnorrsig/tests_impl.h @@ -889,8 +889,8 @@ void test_schnorrsig_taproot(void) { } void test_schnorrsig_batch(void) { - secp256k1_schnorrsig_batch_context* batch_ctx = secp256k1_schnorrsig_batch_context_create(3); - secp256k1_schnorrsig_batch_context_destroy(batch_ctx); + secp256k1_schnorrsig_batch_context* batch_ctx = secp256k1_schnorrsig_batch_context_create(ctx, 3); + secp256k1_schnorrsig_batch_context_destroy(ctx, batch_ctx); } void run_schnorrsig_tests(void) {