@@ -269,15 +269,39 @@ int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned cha
269269
270270/* schnorr batch verification interface */
271271
272+ /** Opaque data structure.
273+ *
274+ * A schnorrsig_extraparams structure object can be initialized correctly by
275+ * setting it to SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT.
276+ *
277+ * Members:
278+ * data: set to SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC at initialization
279+ * and has no other function than making sure the object is
280+ * initialized.
281+ * scalars: pointer to a nonce generation function. If NULL,
282+ * secp256k1_nonce_function_bip340 is used
283+ * points: pointer to arbitrary data used by the nonce generation function
284+ * (can be NULL). If it is non-NULL and
285+ * secp256k1_nonce_function_bip340 is used, then ndata must be a
286+ * pointer to 32-byte auxiliary randomness as per BIP-340.
287+ * sc_g: pointer to arbitrary data used by the nonce generation function
288+ * (can be NULL). If it is non-NULL and
289+ * len: pointer to arbitrary data used by the nonce generation function
290+ * (can be NULL). If it is non-NULL and
291+ * capacity: pointer to arbitrary data used by the nonce generation function
292+ * (can be NULL). If it is non-NULL and
293+ * result: pointer to arbitrary data used by the nonce generation function
294+ * (can be NULL). If it is non-NULL and
295+ */
272296struct secp256k1_schnorrsig_batch_context_struct {
273- secp256k1_scratch * data ; /*(scalar, Point)*/
274- secp256k1_scalar * scalars ; /* base ptr of scalars */
275- secp256k1_gej * points ; /* base ptr of Points */
276- secp256k1_scalar sc_g ; /* scalar of G */
297+ secp256k1_scratch * data ;
298+ secp256k1_scalar * scalars ;
299+ secp256k1_gej * points ;
300+ secp256k1_scalar sc_g ;
277301 /* secp256k1_gej res_gej; final result as gej */
278- size_t len ; /* current len */
279- size_t capacity ; /* max possible len */
280- int result ; /* final result as success or fail */
302+ size_t len ;
303+ size_t capacity ;
304+ int result ;
281305};
282306
283307size_t secp256k1_schnorrsig_batch_context_scratch_size (int n_terms ) {
@@ -288,47 +312,54 @@ size_t secp256k1_schnorrsig_batch_context_scratch_size(int n_terms) {
288312 return ret ;
289313}
290314
291- secp256k1_schnorrsig_batch_context * secp256k1_schnorrsig_batch_context_create (size_t n_terms ) {
315+ secp256k1_schnorrsig_batch_context * secp256k1_schnorrsig_batch_context_create (secp256k1_context * ctx , size_t n_terms ) {
292316 /* fail for n_terms 0, is this the right way to assert?*/
293317 /* VERIFY_CHECK(n_terms != 0); */
294318
295- secp256k1_schnorrsig_batch_context * ctx = (secp256k1_schnorrsig_batch_context * )checked_malloc (& default_error_callback , sizeof (secp256k1_schnorrsig_batch_context ));
319+ secp256k1_schnorrsig_batch_context * batch_ctx = (secp256k1_schnorrsig_batch_context * )checked_malloc (& default_error_callback , sizeof (secp256k1_schnorrsig_batch_context ));
296320 /*
297321 todo: is sizeof() != 0, check required here?*/
298322 size_t scratch_size = secp256k1_schnorrsig_batch_context_scratch_size (2 * n_terms );
299323 size_t checkpoint ;
300324
301325 /* create scratch for storing `2* n terms`--(point, scalar)
302326 and save inital checkpoint */
303- ctx -> data = secp256k1_scratch_create (NULL , scratch_size );
304- checkpoint = secp256k1_scratch_checkpoint (NULL , ctx -> data );
327+ batch_ctx -> data = secp256k1_scratch_create (& ctx -> error_callback , scratch_size );
328+ checkpoint = secp256k1_scratch_checkpoint (& ctx -> error_callback , batch_ctx -> data );
305329
306- ctx -> scalars = (secp256k1_scalar * )secp256k1_scratch_alloc (NULL , ctx -> data , 2 * n_terms * sizeof (secp256k1_scalar ));
307- ctx -> points = (secp256k1_gej * )secp256k1_scratch_alloc (NULL , ctx -> data , 2 * n_terms * sizeof (secp256k1_gej ));
308- if (ctx -> scalars == NULL || ctx -> points == NULL ) {
309- secp256k1_scratch_apply_checkpoint (NULL , ctx -> data , checkpoint );
330+ batch_ctx -> scalars = (secp256k1_scalar * )secp256k1_scratch_alloc (& ctx -> error_callback , batch_ctx -> data , 2 * n_terms * sizeof (secp256k1_scalar ));
331+ batch_ctx -> points = (secp256k1_gej * )secp256k1_scratch_alloc (& ctx -> error_callback , batch_ctx -> data , 2 * n_terms * sizeof (secp256k1_gej ));
332+ if (batch_ctx -> scalars == NULL || batch_ctx -> points == NULL ) {
333+ secp256k1_scratch_apply_checkpoint (& ctx -> error_callback , batch_ctx -> data , checkpoint );
310334 return NULL ;
311335 }
312336
313- secp256k1_scalar_clear (& ctx -> sc_g );
314- ctx -> len = 0 ;
315- ctx -> capacity = n_terms ;
316- ctx -> result = 0 ;
337+ secp256k1_scalar_clear (& batch_ctx -> sc_g );
338+ batch_ctx -> len = 0 ;
339+ batch_ctx -> capacity = n_terms ;
340+ batch_ctx -> result = 0 ;
317341
318- return ctx ;
342+ return batch_ctx ;
319343}
320344
321- void secp256k1_schnorrsig_batch_context_destroy (secp256k1_schnorrsig_batch_context * ctx ) {
322- if (ctx != NULL ) {
323- if (ctx -> data != NULL ) {
324- secp256k1_scratch_apply_checkpoint (NULL , ctx -> data , 0 );
325- secp256k1_scratch_destroy (NULL , ctx -> data );
345+ void secp256k1_schnorrsig_batch_context_destroy (secp256k1_context * ctx , secp256k1_schnorrsig_batch_context * batch_ctx ) {
346+ if (batch_ctx != NULL ) {
347+ if (batch_ctx -> data != NULL ) {
348+ secp256k1_scratch_apply_checkpoint (& ctx -> error_callback , batch_ctx -> data , 0 );
349+ secp256k1_scratch_destroy (& ctx -> error_callback , batch_ctx -> data );
326350 }
327- ctx -> scalars = NULL ;
328- ctx -> points = NULL ;
329- secp256k1_scalar_clear (& ctx -> sc_g );
330- ctx -> len = ctx -> capacity = ctx -> result = 0 ;
351+ batch_ctx -> scalars = NULL ;
352+ batch_ctx -> points = NULL ;
353+ secp256k1_scalar_clear (& batch_ctx -> sc_g );
354+ batch_ctx -> len = batch_ctx -> capacity = batch_ctx -> result = 0 ;
331355 }
332356}
333357
358+ int secp256k1_schnorrsig_batch_context_verify (secp256k1_context * ctx , secp256k1_schnorrsig_batch_context * batch_ctx ) {
359+ secp256k1_gej resj ;
360+ 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 );
361+
362+ return batch_ctx -> result ;
363+ }
364+
334365#endif
0 commit comments