@@ -347,33 +347,58 @@ static void secp256k1_ecmult(secp256k1_gej *r, const secp256k1_gej *a, const sec
347
347
secp256k1_ecmult_strauss_wnaf (& state , r , 1 , a , na , ng );
348
348
}
349
349
350
- static size_t secp256k1_strauss_scratch_size (size_t n_points ) {
351
- static const size_t point_size = (sizeof (secp256k1_ge ) + sizeof (secp256k1_fe )) * ECMULT_TABLE_SIZE (WINDOW_A ) + sizeof (struct secp256k1_strauss_point_state ) + sizeof (secp256k1_gej ) + sizeof (secp256k1_scalar );
352
- return n_points * point_size ;
350
+ /** Allocate strauss state on the scratch space */
351
+ static int secp256k1_strauss_scratch_alloc_state (const secp256k1_callback * error_callback , secp256k1_scratch * scratch , struct secp256k1_strauss_state * state , size_t n_points ) {
352
+ const size_t scratch_checkpoint = secp256k1_scratch_checkpoint (error_callback , scratch );
353
+
354
+ /* We allocate three objects on the scratch space. If these allocations
355
+ * change, make sure to check if this affects STRAUSS_SCRATCH_OBJECTS
356
+ * constant and strauss_scratch_size. */
357
+ state -> aux = (secp256k1_fe * )secp256k1_scratch_alloc (error_callback , scratch , n_points * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_fe ));
358
+ state -> pre_a = (secp256k1_ge * )secp256k1_scratch_alloc (error_callback , scratch , n_points * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_ge ));
359
+ state -> ps = (struct secp256k1_strauss_point_state * )secp256k1_scratch_alloc (error_callback , scratch , n_points * sizeof (struct secp256k1_strauss_point_state ));
360
+
361
+ if (state -> aux == NULL || state -> pre_a == NULL || state -> ps == NULL ) {
362
+ secp256k1_scratch_apply_checkpoint (error_callback , scratch , scratch_checkpoint );
363
+ return 0 ;
364
+ }
365
+ return 1 ;
353
366
}
354
367
355
- static int secp256k1_ecmult_strauss_batch (const secp256k1_callback * error_callback , secp256k1_scratch * scratch , secp256k1_gej * r , const secp256k1_scalar * inp_g_sc , secp256k1_ecmult_multi_callback cb , void * cbdata , size_t n_points , size_t cb_offset ) {
356
- secp256k1_gej * points ;
357
- secp256k1_scalar * scalars ;
368
+ /** Run ecmult_strauss_wnaf on the given points and scalars */
369
+ static int secp256k1_ecmult_strauss_batch_internal (const secp256k1_callback * error_callback , secp256k1_scratch * scratch , secp256k1_gej * r , secp256k1_scalar * scalars , secp256k1_gej * points , const secp256k1_scalar * inp_g_sc , size_t n_points ) {
358
370
struct secp256k1_strauss_state state ;
359
- size_t i ;
360
371
const size_t scratch_checkpoint = secp256k1_scratch_checkpoint (error_callback , scratch );
361
372
362
373
secp256k1_gej_set_infinity (r );
363
374
if (inp_g_sc == NULL && n_points == 0 ) {
364
375
return 1 ;
365
376
}
366
377
367
- /* We allocate STRAUSS_SCRATCH_OBJECTS objects on the scratch space. If these
368
- * allocations change, make sure to update the STRAUSS_SCRATCH_OBJECTS
369
- * constant and strauss_scratch_size accordingly. */
378
+ if (!secp256k1_strauss_scratch_alloc_state (error_callback , scratch , & state , n_points )) {
379
+ return 0 ;
380
+ }
381
+
382
+ secp256k1_ecmult_strauss_wnaf (& state , r , n_points , points , scalars , inp_g_sc );
383
+ secp256k1_scratch_apply_checkpoint (error_callback , scratch , scratch_checkpoint );
384
+ return 1 ;
385
+ }
386
+
387
+ /** Run ecmult_strauss_wnaf on the given points and scalars. Returns 0 if the
388
+ * scratch space is empty. `n_points` number of scalars and points are
389
+ * extracted from `cbdata` using `cb` and stored on the scratch space.
390
+ */
391
+ static int secp256k1_ecmult_strauss_batch (const secp256k1_callback * error_callback , secp256k1_scratch * scratch , secp256k1_gej * r , const secp256k1_scalar * inp_g_sc , secp256k1_ecmult_multi_callback cb , void * cbdata , size_t n_points , size_t cb_offset ) {
392
+ secp256k1_gej * points ;
393
+ secp256k1_scalar * scalars ;
394
+ size_t i ;
395
+ const size_t scratch_checkpoint = secp256k1_scratch_checkpoint (error_callback , scratch );
396
+ /* We allocate STRAUSS_SCRATCH_OBJECTS objects on the scratch space in
397
+ * total. If these allocations change, make sure to update the
398
+ * STRAUSS_SCRATCH_OBJECTS constant and strauss_scratch_size accordingly. */
370
399
points = (secp256k1_gej * )secp256k1_scratch_alloc (error_callback , scratch , n_points * sizeof (secp256k1_gej ));
371
400
scalars = (secp256k1_scalar * )secp256k1_scratch_alloc (error_callback , scratch , n_points * sizeof (secp256k1_scalar ));
372
- state .aux = (secp256k1_fe * )secp256k1_scratch_alloc (error_callback , scratch , n_points * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_fe ));
373
- state .pre_a = (secp256k1_ge * )secp256k1_scratch_alloc (error_callback , scratch , n_points * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_ge ));
374
- state .ps = (struct secp256k1_strauss_point_state * )secp256k1_scratch_alloc (error_callback , scratch , n_points * sizeof (struct secp256k1_strauss_point_state ));
375
-
376
- if (points == NULL || scalars == NULL || state .aux == NULL || state .pre_a == NULL || state .ps == NULL ) {
401
+ if (points == NULL || scalars == NULL ) {
377
402
secp256k1_scratch_apply_checkpoint (error_callback , scratch , scratch_checkpoint );
378
403
return 0 ;
379
404
}
@@ -386,20 +411,30 @@ static int secp256k1_ecmult_strauss_batch(const secp256k1_callback* error_callba
386
411
}
387
412
secp256k1_gej_set_ge (& points [i ], & point );
388
413
}
389
- secp256k1_ecmult_strauss_wnaf (& state , r , n_points , points , scalars , inp_g_sc );
414
+
415
+ secp256k1_ecmult_strauss_batch_internal (error_callback , scratch , r , scalars , points , inp_g_sc , n_points );
390
416
secp256k1_scratch_apply_checkpoint (error_callback , scratch , scratch_checkpoint );
391
417
return 1 ;
392
418
}
393
419
394
- /* Wrapper for secp256k1_ecmult_multi_func interface */
395
- static int secp256k1_ecmult_strauss_batch_single (const secp256k1_callback * error_callback , secp256k1_scratch * scratch , secp256k1_gej * r , const secp256k1_scalar * inp_g_sc , secp256k1_ecmult_multi_callback cb , void * cbdata , size_t n ) {
396
- return secp256k1_ecmult_strauss_batch (error_callback , scratch , r , inp_g_sc , cb , cbdata , n , 0 );
420
+ /** Return the scratch size that is allocated by a call to strauss_batch
421
+ * (ignoring padding required for alignment). */
422
+ static size_t secp256k1_strauss_scratch_size (size_t n_points ) {
423
+ static const size_t point_size = (sizeof (secp256k1_ge ) + sizeof (secp256k1_fe )) * ECMULT_TABLE_SIZE (WINDOW_A ) + sizeof (struct secp256k1_strauss_point_state ) + sizeof (secp256k1_gej ) + sizeof (secp256k1_scalar );
424
+ return n_points * point_size ;
397
425
}
398
426
427
+ /** Return the maximum number of points that can be provided to strauss_batch
428
+ * with a given scratch space. */
399
429
static size_t secp256k1_strauss_max_points (const secp256k1_callback * error_callback , secp256k1_scratch * scratch ) {
400
430
return secp256k1_scratch_max_allocation (error_callback , scratch , STRAUSS_SCRATCH_OBJECTS ) / secp256k1_strauss_scratch_size (1 );
401
431
}
402
432
433
+ /* Wrapper for secp256k1_ecmult_multi_func interface */
434
+ static int secp256k1_ecmult_strauss_batch_single (const secp256k1_callback * error_callback , secp256k1_scratch * scratch , secp256k1_gej * r , const secp256k1_scalar * inp_g_sc , secp256k1_ecmult_multi_callback cb , void * cbdata , size_t n ) {
435
+ return secp256k1_ecmult_strauss_batch (error_callback , scratch , r , inp_g_sc , cb , cbdata , n , 0 );
436
+ }
437
+
403
438
/** Convert a number to WNAF notation.
404
439
* The number becomes represented by sum(2^{wi} * wnaf[i], i=0..WNAF_SIZE(w)+1) - return_val.
405
440
* It has the following guarantees:
0 commit comments