@@ -229,7 +229,9 @@ struct secp256k1_strauss_state {
229
229
struct secp256k1_strauss_point_state * ps ;
230
230
};
231
231
232
- static void secp256k1_ecmult_strauss_wnaf (const struct secp256k1_strauss_state * state , secp256k1_gej * r , size_t num , const secp256k1_gej * a , const secp256k1_scalar * na , const secp256k1_scalar * ng ) {
232
+ typedef int (secp256k1_ecmult_strauss_multi_callback )(secp256k1_scalar * sc , secp256k1_gej * pt , size_t idx , void * data );
233
+
234
+ static int secp256k1_ecmult_strauss_wnaf (const struct secp256k1_strauss_state * state , secp256k1_gej * r , size_t num , secp256k1_ecmult_strauss_multi_callback cb , void * cbdata , size_t cb_offset , const secp256k1_scalar * ng ) {
233
235
secp256k1_ge tmpa ;
234
236
secp256k1_fe Z ;
235
237
/* Splitted G factors. */
@@ -245,13 +247,17 @@ static void secp256k1_ecmult_strauss_wnaf(const struct secp256k1_strauss_state *
245
247
246
248
secp256k1_fe_set_int (& Z , 1 );
247
249
for (np = 0 ; np < num ; ++ np ) {
248
- secp256k1_gej tmp ;
249
- secp256k1_scalar na_1 , na_lam ;
250
- if (secp256k1_scalar_is_zero (& na [np ]) || secp256k1_gej_is_infinity (& a [np ])) {
250
+ secp256k1_gej a ;
251
+ secp256k1_fe az ;
252
+ secp256k1_scalar na , na_1 , na_lam ;
253
+
254
+ if (!cb (& na , & a , np + cb_offset , cbdata )) return 0 ;
255
+ if (secp256k1_scalar_is_zero (& na ) || secp256k1_gej_is_infinity (& a )) {
251
256
continue ;
252
257
}
258
+
253
259
/* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */
254
- secp256k1_scalar_split_lambda (& na_1 , & na_lam , & na [ np ] );
260
+ secp256k1_scalar_split_lambda (& na_1 , & na_lam , & na );
255
261
256
262
/* build wnaf representation for na_1 and na_lam. */
257
263
state -> ps [no ].bits_na_1 = secp256k1_ecmult_wnaf (state -> ps [no ].wnaf_na_1 , 129 , & na_1 , WINDOW_A );
@@ -275,16 +281,16 @@ static void secp256k1_ecmult_strauss_wnaf(const struct secp256k1_strauss_state *
275
281
* of 1/Z, so we can use secp256k1_gej_add_zinv_var, which uses the same
276
282
* isomorphism to efficiently add with a known Z inverse.
277
283
*/
278
- tmp = a [ np ] ;
284
+ az = a . z ;
279
285
if (no ) {
280
286
#ifdef VERIFY
281
287
secp256k1_fe_normalize_var (& Z );
282
288
#endif
283
- secp256k1_gej_rescale (& tmp , & Z );
289
+ secp256k1_gej_rescale (& a , & Z );
284
290
}
285
- secp256k1_ecmult_odd_multiples_table (ECMULT_TABLE_SIZE (WINDOW_A ), state -> pre_a + no * ECMULT_TABLE_SIZE (WINDOW_A ), state -> aux + no * ECMULT_TABLE_SIZE (WINDOW_A ), & tmp );
286
- if (no ) secp256k1_fe_mul (state -> aux + no * ECMULT_TABLE_SIZE (WINDOW_A ), state -> aux + no * ECMULT_TABLE_SIZE (WINDOW_A ), & ( a [ np ]. z ) );
287
- Z = tmp .z ;
291
+ secp256k1_ecmult_odd_multiples_table (ECMULT_TABLE_SIZE (WINDOW_A ), state -> pre_a + no * ECMULT_TABLE_SIZE (WINDOW_A ), state -> aux + no * ECMULT_TABLE_SIZE (WINDOW_A ), & a );
292
+ if (no ) secp256k1_fe_mul (state -> aux + no * ECMULT_TABLE_SIZE (WINDOW_A ), state -> aux + no * ECMULT_TABLE_SIZE (WINDOW_A ), & az );
293
+ Z = a .z ;
288
294
289
295
++ no ;
290
296
}
@@ -343,30 +349,68 @@ static void secp256k1_ecmult_strauss_wnaf(const struct secp256k1_strauss_state *
343
349
if (!r -> infinity ) {
344
350
secp256k1_fe_mul (& r -> z , & r -> z , & Z );
345
351
}
352
+
353
+ return 1 ;
354
+ }
355
+
356
+ struct secp256k1_ecmult_array_cb_data {
357
+ const secp256k1_scalar * na ;
358
+ const secp256k1_gej * a ;
359
+ };
360
+
361
+ static int secp256k1_ecmult_array_cb (secp256k1_scalar * sc , secp256k1_gej * pt , size_t idx , void * data ) {
362
+ struct secp256k1_ecmult_array_cb_data * array_data = data ;
363
+ * sc = array_data -> na [idx ];
364
+ if (array_data -> a ) {
365
+ * pt = array_data -> a [idx ];
366
+ return 1 ;
367
+ } else {
368
+ return secp256k1_scalar_is_zero (sc );
369
+ }
346
370
}
347
371
348
372
static void secp256k1_ecmult (secp256k1_gej * r , const secp256k1_gej * a , const secp256k1_scalar * na , const secp256k1_scalar * ng ) {
349
373
secp256k1_fe aux [ECMULT_TABLE_SIZE (WINDOW_A )];
350
374
secp256k1_ge pre_a [ECMULT_TABLE_SIZE (WINDOW_A )];
351
375
struct secp256k1_strauss_point_state ps [1 ];
352
376
struct secp256k1_strauss_state state ;
377
+ struct secp256k1_ecmult_array_cb_data data ;
353
378
354
379
state .aux = aux ;
355
380
state .pre_a = pre_a ;
356
381
state .ps = ps ;
357
- secp256k1_ecmult_strauss_wnaf (& state , r , 1 , a , na , ng );
382
+ data .na = na ;
383
+ data .a = a ;
384
+ secp256k1_ecmult_strauss_wnaf (& state , r , 1 , & secp256k1_ecmult_array_cb , & data , 0 , ng );
358
385
}
359
386
360
387
static size_t secp256k1_strauss_scratch_size (size_t n_points ) {
361
388
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 );
362
389
return n_points * point_size ;
363
390
}
364
391
392
+ struct secp256k1_ecmult_adaptor_cb_data {
393
+ secp256k1_ecmult_multi_callback * cb ;
394
+ void * data ;
395
+ };
396
+
397
+ static int secp256k1_ecmult_adaptor_cb (secp256k1_scalar * sc , secp256k1_gej * pt , size_t idx , void * data ) {
398
+ secp256k1_ge tmp ;
399
+ struct secp256k1_ecmult_adaptor_cb_data * adaptor_data = data ;
400
+ int result = adaptor_data -> cb (sc , & tmp , idx , adaptor_data -> data );
401
+
402
+ if (result ) {
403
+ secp256k1_gej_set_ge (pt , & tmp );
404
+ }
405
+
406
+ return result ;
407
+ }
408
+
365
409
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 ) {
366
410
secp256k1_gej * points ;
367
411
secp256k1_scalar * scalars ;
412
+ struct secp256k1_ecmult_adaptor_cb_data adaptor_data ;
368
413
struct secp256k1_strauss_state state ;
369
- size_t i ;
370
414
const size_t scratch_checkpoint = secp256k1_scratch_checkpoint (error_callback , scratch );
371
415
372
416
secp256k1_gej_set_infinity (r );
@@ -376,6 +420,8 @@ static int secp256k1_ecmult_strauss_batch(const secp256k1_callback* error_callba
376
420
377
421
points = (secp256k1_gej * )secp256k1_scratch_alloc (error_callback , scratch , n_points * sizeof (secp256k1_gej ));
378
422
scalars = (secp256k1_scalar * )secp256k1_scratch_alloc (error_callback , scratch , n_points * sizeof (secp256k1_scalar ));
423
+ adaptor_data .cb = cb ;
424
+ adaptor_data .data = cbdata ;
379
425
state .aux = (secp256k1_fe * )secp256k1_scratch_alloc (error_callback , scratch , n_points * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_fe ));
380
426
state .pre_a = (secp256k1_ge * )secp256k1_scratch_alloc (error_callback , scratch , n_points * ECMULT_TABLE_SIZE (WINDOW_A ) * sizeof (secp256k1_ge ));
381
427
state .ps = (struct secp256k1_strauss_point_state * )secp256k1_scratch_alloc (error_callback , scratch , n_points * sizeof (struct secp256k1_strauss_point_state ));
@@ -385,15 +431,10 @@ static int secp256k1_ecmult_strauss_batch(const secp256k1_callback* error_callba
385
431
return 0 ;
386
432
}
387
433
388
- for (i = 0 ; i < n_points ; i ++ ) {
389
- secp256k1_ge point ;
390
- if (!cb (& scalars [i ], & point , i + cb_offset , cbdata )) {
391
- secp256k1_scratch_apply_checkpoint (error_callback , scratch , scratch_checkpoint );
392
- return 0 ;
393
- }
394
- secp256k1_gej_set_ge (& points [i ], & point );
434
+ if (!secp256k1_ecmult_strauss_wnaf (& state , r , n_points , & secp256k1_ecmult_adaptor_cb , & adaptor_data , cb_offset , inp_g_sc )) {
435
+ secp256k1_scratch_apply_checkpoint (error_callback , scratch , scratch_checkpoint );
436
+ return 0 ;
395
437
}
396
- secp256k1_ecmult_strauss_wnaf (& state , r , n_points , points , scalars , inp_g_sc );
397
438
secp256k1_scratch_apply_checkpoint (error_callback , scratch , scratch_checkpoint );
398
439
return 1 ;
399
440
}
0 commit comments