Skip to content

Commit ac2620d

Browse files
Eliminate the use of points and scalars from secp256k1_ecmult_strauss_batch.
We have secp256k1_ecmult_strauss_wnaf invoke the callback itself.
1 parent 4ba9971 commit ac2620d

File tree

1 file changed

+44
-20
lines changed

1 file changed

+44
-20
lines changed

src/ecmult_impl.h

+44-20
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ struct secp256k1_strauss_state {
455455
struct secp256k1_strauss_point_state* ps;
456456
};
457457

458-
static void secp256k1_ecmult_strauss_wnaf(const secp256k1_ecmult_context *ctx, const struct secp256k1_strauss_state *state, secp256k1_gej *r, size_t num, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) {
458+
static int secp256k1_ecmult_strauss_wnaf(const secp256k1_ecmult_context *ctx, const struct secp256k1_strauss_state *state, secp256k1_gej *r, size_t num, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t cb_offset, const secp256k1_fe *cb_z, const secp256k1_scalar *ng) {
459459
secp256k1_ge tmpa;
460460
secp256k1_fe Z;
461461
/* Splitted G factors. */
@@ -471,13 +471,20 @@ static void secp256k1_ecmult_strauss_wnaf(const secp256k1_ecmult_context *ctx, c
471471

472472
secp256k1_fe_set_int(&Z, 1);
473473
for (np = 0; np < num; ++np) {
474-
secp256k1_gej tmp;
475-
secp256k1_scalar na_1, na_lam;
476-
if (secp256k1_scalar_is_zero(&na[np]) || secp256k1_gej_is_infinity(&a[np])) {
474+
secp256k1_gej a;
475+
secp256k1_fe az;
476+
secp256k1_scalar na, na_1, na_lam;
477+
478+
if (!cb(&na, &tmpa, np + cb_offset, cbdata)) return 0;
479+
if (secp256k1_scalar_is_zero(&na) || secp256k1_ge_is_infinity(&tmpa)) {
477480
continue;
478481
}
482+
483+
secp256k1_gej_set_ge(&a, &tmpa);
484+
if (cb_z) a.z = *cb_z;
485+
479486
/* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */
480-
secp256k1_scalar_split_lambda(&na_1, &na_lam, &na[np]);
487+
secp256k1_scalar_split_lambda(&na_1, &na_lam, &na);
481488

482489
/* build wnaf representation for na_1 and na_lam. */
483490
state->ps[no].bits_na_1 = secp256k1_ecmult_wnaf(state->ps[no].wnaf_na_1, 129, &na_1, WINDOW_A);
@@ -501,16 +508,16 @@ static void secp256k1_ecmult_strauss_wnaf(const secp256k1_ecmult_context *ctx, c
501508
* of 1/Z, so we can use secp256k1_gej_add_zinv_var, which uses the same
502509
* isomorphism to efficiently add with a known Z inverse.
503510
*/
504-
tmp = a[np];
511+
az = a.z;
505512
if (no) {
506513
#ifdef VERIFY
507514
secp256k1_fe_normalize_var(&Z);
508515
#endif
509-
secp256k1_gej_rescale(&tmp, &Z);
516+
secp256k1_gej_rescale(&a, &Z);
510517
}
511-
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);
512-
if (no) secp256k1_fe_mul(state->aux + no * ECMULT_TABLE_SIZE(WINDOW_A), state->aux + no * ECMULT_TABLE_SIZE(WINDOW_A), &(a[np].z));
513-
Z = tmp.z;
518+
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);
519+
if (no) secp256k1_fe_mul(state->aux + no * ECMULT_TABLE_SIZE(WINDOW_A), state->aux + no * ECMULT_TABLE_SIZE(WINDOW_A), &az);
520+
Z = a.z;
514521

515522
++no;
516523
}
@@ -569,18 +576,41 @@ static void secp256k1_ecmult_strauss_wnaf(const secp256k1_ecmult_context *ctx, c
569576
if (!r->infinity) {
570577
secp256k1_fe_mul(&r->z, &r->z, &Z);
571578
}
579+
580+
return 1;
581+
}
582+
583+
struct secp256k1_ecmult_cb_data {
584+
const secp256k1_scalar *na;
585+
const secp256k1_ge *a;
586+
};
587+
588+
static int secp256k1_ecmult_array_cb(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data) {
589+
struct secp256k1_ecmult_cb_data *array_data = data;
590+
*sc = array_data->na[idx];
591+
if (array_data->a) *pt = array_data->a[idx];
592+
return 1;
572593
}
573594

574595
static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) {
575596
secp256k1_fe aux[ECMULT_TABLE_SIZE(WINDOW_A)];
576597
secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)];
577598
struct secp256k1_strauss_point_state ps[1];
578599
struct secp256k1_strauss_state state;
600+
struct secp256k1_ecmult_cb_data data;
601+
secp256k1_ge axy;
579602

580603
state.aux = aux;
581604
state.pre_a = pre_a;
582605
state.ps = ps;
583-
secp256k1_ecmult_strauss_wnaf(ctx, &state, r, 1, a, na, ng);
606+
if (a) {
607+
axy.x = a->x;
608+
axy.y = a->y;
609+
axy.infinity = a->infinity;
610+
}
611+
data.na = na;
612+
data.a = a ? &axy : NULL;
613+
secp256k1_ecmult_strauss_wnaf(ctx, &state, r, 1, &secp256k1_ecmult_array_cb, &data, 0, a ? &a->z : NULL, ng);
584614
}
585615

586616
static size_t secp256k1_strauss_scratch_size(size_t n_points) {
@@ -592,7 +622,6 @@ static int secp256k1_ecmult_strauss_batch(const secp256k1_callback* error_callba
592622
secp256k1_gej* points;
593623
secp256k1_scalar* scalars;
594624
struct secp256k1_strauss_state state;
595-
size_t i;
596625
const size_t scratch_checkpoint = secp256k1_scratch_checkpoint(error_callback, scratch);
597626

598627
secp256k1_gej_set_infinity(r);
@@ -611,15 +640,10 @@ static int secp256k1_ecmult_strauss_batch(const secp256k1_callback* error_callba
611640
return 0;
612641
}
613642

614-
for (i = 0; i < n_points; i++) {
615-
secp256k1_ge point;
616-
if (!cb(&scalars[i], &point, i+cb_offset, cbdata)) {
617-
secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint);
618-
return 0;
619-
}
620-
secp256k1_gej_set_ge(&points[i], &point);
643+
if (!secp256k1_ecmult_strauss_wnaf(ctx, &state, r, n_points, cb, cbdata, cb_offset, NULL, inp_g_sc)) {
644+
secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint);
645+
return 0;
621646
}
622-
secp256k1_ecmult_strauss_wnaf(ctx, &state, r, n_points, points, scalars, inp_g_sc);
623647
secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint);
624648
return 1;
625649
}

0 commit comments

Comments
 (0)