Add trivial ecmult_multi algorithm. It is selected when no scratch space is given and just multiplies and adds the points.
This commit is contained in:
parent
53ad841caf
commit
ed59fbe8b7
@ -37,7 +37,8 @@ typedef int (secp256k1_ecmult_multi_callback)(secp256k1_scalar *sc, secp256k1_ge
|
|||||||
* Chooses the right algorithm for a given number of points and scratch space
|
* Chooses the right algorithm for a given number of points and scratch space
|
||||||
* size. Resets and overwrites the given scratch space. If the points do not
|
* size. Resets and overwrites the given scratch space. If the points do not
|
||||||
* fit in the scratch space the algorithm is repeatedly run with batches of
|
* fit in the scratch space the algorithm is repeatedly run with batches of
|
||||||
* points.
|
* points. If no scratch space is given then a simple algorithm is used that
|
||||||
|
* simply multiplies the points with the corresponding scalars and adds them up.
|
||||||
* Returns: 1 on success (including when inp_g_sc is NULL and n is 0)
|
* Returns: 1 on success (including when inp_g_sc is NULL and n is 0)
|
||||||
* 0 if there is not enough scratch space for a single point or
|
* 0 if there is not enough scratch space for a single point or
|
||||||
* callback returns 0
|
* callback returns 0
|
||||||
|
@ -1083,6 +1083,32 @@ static size_t secp256k1_pippenger_max_points(secp256k1_scratch *scratch) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Computes ecmult_multi by simply multiplying and adding each point. Does not
|
||||||
|
* require a scratch space */
|
||||||
|
static int secp256k1_ecmult_multi_var_simple(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n_points) {
|
||||||
|
size_t point_idx;
|
||||||
|
secp256k1_scalar szero;
|
||||||
|
secp256k1_gej tmpj;
|
||||||
|
|
||||||
|
secp256k1_scalar_set_int(&szero, 0);
|
||||||
|
/* r = inp_g_sc*G */
|
||||||
|
secp256k1_gej_set_infinity(r);
|
||||||
|
secp256k1_ecmult(ctx, r, &tmpj, &szero, inp_g_sc);
|
||||||
|
for (point_idx = 0; point_idx < n_points; point_idx++) {
|
||||||
|
secp256k1_ge point;
|
||||||
|
secp256k1_gej pointj;
|
||||||
|
secp256k1_scalar scalar;
|
||||||
|
if (!cb(&scalar, &point, point_idx, cbdata)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* r += scalar*point */
|
||||||
|
secp256k1_gej_set_ge(&pointj, &point);
|
||||||
|
secp256k1_ecmult(ctx, &tmpj, &pointj, &scalar, NULL);
|
||||||
|
secp256k1_gej_add_var(r, r, &tmpj, NULL);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
typedef int (*secp256k1_ecmult_multi_func)(const secp256k1_ecmult_context*, secp256k1_scratch*, secp256k1_gej*, const secp256k1_scalar*, secp256k1_ecmult_multi_callback cb, void*, size_t);
|
typedef int (*secp256k1_ecmult_multi_func)(const secp256k1_ecmult_context*, secp256k1_scratch*, secp256k1_gej*, const secp256k1_scalar*, secp256k1_ecmult_multi_callback cb, void*, size_t);
|
||||||
static int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n) {
|
static int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n) {
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -1101,6 +1127,9 @@ static int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp2
|
|||||||
secp256k1_ecmult(ctx, r, r, &szero, inp_g_sc);
|
secp256k1_ecmult(ctx, r, r, &szero, inp_g_sc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (scratch == NULL) {
|
||||||
|
return secp256k1_ecmult_multi_var_simple(ctx, r, inp_g_sc, cb, cbdata, n);
|
||||||
|
}
|
||||||
|
|
||||||
max_points = secp256k1_pippenger_max_points(scratch);
|
max_points = secp256k1_pippenger_max_points(scratch);
|
||||||
if (max_points == 0) {
|
if (max_points == 0) {
|
||||||
|
@ -2968,6 +2968,7 @@ void run_ecmult_multi_tests(void) {
|
|||||||
test_ecmult_multi_pippenger_max_points();
|
test_ecmult_multi_pippenger_max_points();
|
||||||
scratch = secp256k1_scratch_create(&ctx->error_callback, 819200);
|
scratch = secp256k1_scratch_create(&ctx->error_callback, 819200);
|
||||||
test_ecmult_multi(scratch, secp256k1_ecmult_multi_var);
|
test_ecmult_multi(scratch, secp256k1_ecmult_multi_var);
|
||||||
|
test_ecmult_multi(NULL, secp256k1_ecmult_multi_var);
|
||||||
test_ecmult_multi(scratch, secp256k1_ecmult_pippenger_batch_single);
|
test_ecmult_multi(scratch, secp256k1_ecmult_pippenger_batch_single);
|
||||||
test_ecmult_multi(scratch, secp256k1_ecmult_strauss_batch_single);
|
test_ecmult_multi(scratch, secp256k1_ecmult_strauss_batch_single);
|
||||||
secp256k1_scratch_destroy(scratch);
|
secp256k1_scratch_destroy(scratch);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user