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