Skip to content

Commit b6e1409

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 1cd7ab2 commit b6e1409

File tree

1 file changed

+61
-20
lines changed

1 file changed

+61
-20
lines changed

src/ecmult_impl.h

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,9 @@ struct secp256k1_strauss_state {
229229
struct secp256k1_strauss_point_state* ps;
230230
};
231231

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) {
233235
secp256k1_ge tmpa;
234236
secp256k1_fe Z;
235237
/* Splitted G factors. */
@@ -245,13 +247,17 @@ static void secp256k1_ecmult_strauss_wnaf(const struct secp256k1_strauss_state *
245247

246248
secp256k1_fe_set_int(&Z, 1);
247249
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)) {
251256
continue;
252257
}
258+
253259
/* 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);
255261

256262
/* build wnaf representation for na_1 and na_lam. */
257263
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 *
275281
* of 1/Z, so we can use secp256k1_gej_add_zinv_var, which uses the same
276282
* isomorphism to efficiently add with a known Z inverse.
277283
*/
278-
tmp = a[np];
284+
az = a.z;
279285
if (no) {
280286
#ifdef VERIFY
281287
secp256k1_fe_normalize_var(&Z);
282288
#endif
283-
secp256k1_gej_rescale(&tmp, &Z);
289+
secp256k1_gej_rescale(&a, &Z);
284290
}
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;
288294

289295
++no;
290296
}
@@ -343,30 +349,68 @@ static void secp256k1_ecmult_strauss_wnaf(const struct secp256k1_strauss_state *
343349
if (!r->infinity) {
344350
secp256k1_fe_mul(&r->z, &r->z, &Z);
345351
}
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+
}
346370
}
347371

348372
static void secp256k1_ecmult(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) {
349373
secp256k1_fe aux[ECMULT_TABLE_SIZE(WINDOW_A)];
350374
secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)];
351375
struct secp256k1_strauss_point_state ps[1];
352376
struct secp256k1_strauss_state state;
377+
struct secp256k1_ecmult_array_cb_data data;
353378

354379
state.aux = aux;
355380
state.pre_a = pre_a;
356381
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);
358385
}
359386

360387
static size_t secp256k1_strauss_scratch_size(size_t n_points) {
361388
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);
362389
return n_points*point_size;
363390
}
364391

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+
365409
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) {
366410
secp256k1_gej* points;
367411
secp256k1_scalar* scalars;
412+
struct secp256k1_ecmult_adaptor_cb_data adaptor_data;
368413
struct secp256k1_strauss_state state;
369-
size_t i;
370414
const size_t scratch_checkpoint = secp256k1_scratch_checkpoint(error_callback, scratch);
371415

372416
secp256k1_gej_set_infinity(r);
@@ -376,6 +420,8 @@ static int secp256k1_ecmult_strauss_batch(const secp256k1_callback* error_callba
376420

377421
points = (secp256k1_gej*)secp256k1_scratch_alloc(error_callback, scratch, n_points * sizeof(secp256k1_gej));
378422
scalars = (secp256k1_scalar*)secp256k1_scratch_alloc(error_callback, scratch, n_points * sizeof(secp256k1_scalar));
423+
adaptor_data.cb = cb;
424+
adaptor_data.data = cbdata;
379425
state.aux = (secp256k1_fe*)secp256k1_scratch_alloc(error_callback, scratch, n_points * ECMULT_TABLE_SIZE(WINDOW_A) * sizeof(secp256k1_fe));
380426
state.pre_a = (secp256k1_ge*)secp256k1_scratch_alloc(error_callback, scratch, n_points * ECMULT_TABLE_SIZE(WINDOW_A) * sizeof(secp256k1_ge));
381427
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
385431
return 0;
386432
}
387433

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;
395437
}
396-
secp256k1_ecmult_strauss_wnaf(&state, r, n_points, points, scalars, inp_g_sc);
397438
secp256k1_scratch_apply_checkpoint(error_callback, scratch, scratch_checkpoint);
398439
return 1;
399440
}

0 commit comments

Comments
 (0)