Skip to content

Commit 3186082

Browse files
Merge #1614: Add _ge_set_all_gej and use it in musig for own public nonces
64228a6 musig: Use _ge_set_all_gej for own public nonces (Tim Ruffing) 300aab1 tests: Improve _ge_set_all_gej(_var) tests (Tim Ruffing) 365f274 group: Simplify secp256k1_ge_set_all_gej (Tim Ruffing) d3082dd group: Add constant-time secp256k1_ge_set_all_gej (Tim Ruffing) Pull request description: As suggested in #1479 (comment) ACKs for top commit: theStack: re-ACK 64228a6 sipa: ACK 64228a6 Tree-SHA512: f62a95e44dc09bb55a64da0640ad323e7ef5acc262d3c2aea6787eae0918769ea97da466b7d602e59693e4fb85c5ec9a67fdfba8b890624467855b6d1e1596c0
2 parents 6c2a39d + 64228a6 commit 3186082

File tree

4 files changed

+74
-6
lines changed

4 files changed

+74
-6
lines changed

src/group.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a);
8080
/** Set a group element equal to another which is given in jacobian coordinates. */
8181
static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a);
8282

83-
/** Set a batch of group elements equal to the inputs given in jacobian coordinates */
83+
/** Set group elements r[0:len] (affine) equal to group elements a[0:len] (jacobian).
84+
* None of the group elements in a[0:len] may be infinity. Constant time. */
85+
static void secp256k1_ge_set_all_gej(secp256k1_ge *r, const secp256k1_gej *a, size_t len);
86+
87+
/** Set group elements r[0:len] (affine) equal to group elements a[0:len] (jacobian). */
8488
static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len);
8589

8690
/** Bring a batch of inputs to the same global z "denominator", based on ratios between

src/group_impl.h

+38
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,44 @@ static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) {
195195
SECP256K1_GE_VERIFY(r);
196196
}
197197

198+
static void secp256k1_ge_set_all_gej(secp256k1_ge *r, const secp256k1_gej *a, size_t len) {
199+
secp256k1_fe u;
200+
size_t i;
201+
#ifdef VERIFY
202+
for (i = 0; i < len; i++) {
203+
SECP256K1_GEJ_VERIFY(&a[i]);
204+
VERIFY_CHECK(!secp256k1_gej_is_infinity(&a[i]));
205+
}
206+
#endif
207+
208+
if (len == 0) {
209+
return;
210+
}
211+
212+
/* Use destination's x coordinates as scratch space */
213+
r[0].x = a[0].z;
214+
for (i = 1; i < len; i++) {
215+
secp256k1_fe_mul(&r[i].x, &r[i - 1].x, &a[i].z);
216+
}
217+
secp256k1_fe_inv(&u, &r[len - 1].x);
218+
219+
for (i = len - 1; i > 0; i--) {
220+
secp256k1_fe_mul(&r[i].x, &r[i - 1].x, &u);
221+
secp256k1_fe_mul(&u, &u, &a[i].z);
222+
}
223+
r[0].x = u;
224+
225+
for (i = 0; i < len; i++) {
226+
secp256k1_ge_set_gej_zinv(&r[i], &a[i], &r[i].x);
227+
}
228+
229+
#ifdef VERIFY
230+
for (i = 0; i < len; i++) {
231+
SECP256K1_GE_VERIFY(&r[i]);
232+
}
233+
#endif
234+
}
235+
198236
static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len) {
199237
secp256k1_fe u;
200238
size_t i;

src/modules/musig/session_impl.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ static void secp256k1_nonce_function_musig(secp256k1_scalar *k, const unsigned c
395395
static int secp256k1_musig_nonce_gen_internal(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, secp256k1_musig_pubnonce *pubnonce, const unsigned char *input_nonce, const unsigned char *seckey, const secp256k1_pubkey *pubkey, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *extra_input32) {
396396
secp256k1_scalar k[2];
397397
secp256k1_ge nonce_pts[2];
398+
secp256k1_gej nonce_ptj[2];
398399
int i;
399400
unsigned char pk_ser[33];
400401
size_t pk_ser_len = sizeof(pk_ser);
@@ -445,13 +446,14 @@ static int secp256k1_musig_nonce_gen_internal(const secp256k1_context* ctx, secp
445446
secp256k1_musig_secnonce_invalidate(ctx, secnonce, !ret);
446447

447448
for (i = 0; i < 2; i++) {
448-
secp256k1_gej nonce_ptj;
449-
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &nonce_ptj, &k[i]);
450-
secp256k1_ge_set_gej(&nonce_pts[i], &nonce_ptj);
451-
secp256k1_declassify(ctx, &nonce_pts[i], sizeof(nonce_pts[i]));
449+
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &nonce_ptj[i], &k[i]);
452450
secp256k1_scalar_clear(&k[i]);
453451
secp256k1_gej_clear(&nonce_ptj);
454452
}
453+
secp256k1_ge_set_all_gej(nonce_pts, nonce_ptj, 2);
454+
for (i = 0; i < 2; i++) {
455+
secp256k1_declassify(ctx, &nonce_pts[i], sizeof(nonce_pts[i]));
456+
}
455457
/* None of the nonce_pts will be infinity because k != 0 with overwhelming
456458
* probability */
457459
secp256k1_musig_pubnonce_save(pubnonce, nonce_pts);

src/tests.c

+25-1
Original file line numberDiff line numberDiff line change
@@ -3821,14 +3821,38 @@ static void test_ge(void) {
38213821

38223822
/* Test batch gej -> ge conversion without known z ratios. */
38233823
{
3824+
secp256k1_ge *ge_set_all_var = (secp256k1_ge *)checked_malloc(&CTX->error_callback, (4 * runs + 1) * sizeof(secp256k1_ge));
38243825
secp256k1_ge *ge_set_all = (secp256k1_ge *)checked_malloc(&CTX->error_callback, (4 * runs + 1) * sizeof(secp256k1_ge));
3825-
secp256k1_ge_set_all_gej_var(ge_set_all, gej, 4 * runs + 1);
3826+
secp256k1_ge_set_all_gej_var(&ge_set_all_var[0], &gej[0], 4 * runs + 1);
38263827
for (i = 0; i < 4 * runs + 1; i++) {
3828+
secp256k1_fe s;
3829+
testutil_random_fe_non_zero(&s);
3830+
secp256k1_gej_rescale(&gej[i], &s);
3831+
CHECK(secp256k1_gej_eq_ge_var(&gej[i], &ge_set_all_var[i]));
3832+
}
3833+
3834+
/* Skip infinity at &gej[0]. */
3835+
secp256k1_ge_set_all_gej(&ge_set_all[1], &gej[1], 4 * runs);
3836+
for (i = 1; i < 4 * runs + 1; i++) {
38273837
secp256k1_fe s;
38283838
testutil_random_fe_non_zero(&s);
38293839
secp256k1_gej_rescale(&gej[i], &s);
38303840
CHECK(secp256k1_gej_eq_ge_var(&gej[i], &ge_set_all[i]));
3841+
CHECK(secp256k1_ge_eq_var(&ge_set_all_var[i], &ge_set_all[i]));
38313842
}
3843+
3844+
/* Test with an array of length 1. */
3845+
secp256k1_ge_set_all_gej_var(ge_set_all_var, &gej[1], 1);
3846+
secp256k1_ge_set_all_gej(ge_set_all, &gej[1], 1);
3847+
CHECK(secp256k1_gej_eq_ge_var(&gej[1], &ge_set_all_var[1]));
3848+
CHECK(secp256k1_gej_eq_ge_var(&gej[1], &ge_set_all[1]));
3849+
CHECK(secp256k1_ge_eq_var(&ge_set_all_var[1], &ge_set_all[1]));
3850+
3851+
/* Test with an array of length 0. */
3852+
secp256k1_ge_set_all_gej_var(NULL, NULL, 0);
3853+
secp256k1_ge_set_all_gej(NULL, NULL, 0);
3854+
3855+
free(ge_set_all_var);
38323856
free(ge_set_all);
38333857
}
38343858

0 commit comments

Comments
 (0)