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