Skip to content

Commit d3082dd

Browse files
group: Add constant-time secp256k1_ge_set_all_gej
This is a dump mechanical translation of secp256k1_ge_set_all_gej_var that assumes that inputs are not infinity.
1 parent 9b7c59c commit d3082dd

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

src/group.h

Lines changed: 5 additions & 1 deletion
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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,52 @@ 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+
size_t last_i = SIZE_MAX;
202+
#ifdef VERIFY
203+
for (i = 0; i < len; i++) {
204+
SECP256K1_GEJ_VERIFY(&a[i]);
205+
VERIFY_CHECK(!secp256k1_gej_is_infinity(&a[i]));
206+
}
207+
#endif
208+
209+
for (i = 0; i < len; i++) {
210+
/* Use destination's x coordinates as scratch space */
211+
if (last_i == SIZE_MAX) {
212+
r[i].x = a[i].z;
213+
} else {
214+
secp256k1_fe_mul(&r[i].x, &r[last_i].x, &a[i].z);
215+
}
216+
last_i = i;
217+
}
218+
if (last_i == SIZE_MAX) {
219+
return;
220+
}
221+
secp256k1_fe_inv(&u, &r[last_i].x);
222+
223+
i = last_i;
224+
while (i > 0) {
225+
i--;
226+
secp256k1_fe_mul(&r[last_i].x, &r[i].x, &u);
227+
secp256k1_fe_mul(&u, &u, &a[last_i].z);
228+
last_i = i;
229+
}
230+
VERIFY_CHECK(!a[last_i].infinity);
231+
r[last_i].x = u;
232+
233+
for (i = 0; i < len; i++) {
234+
secp256k1_ge_set_gej_zinv(&r[i], &a[i], &r[i].x);
235+
}
236+
237+
#ifdef VERIFY
238+
for (i = 0; i < len; i++) {
239+
SECP256K1_GE_VERIFY(&r[i]);
240+
}
241+
#endif
242+
}
243+
198244
static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len) {
199245
secp256k1_fe u;
200246
size_t i;

src/tests.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3822,14 +3822,27 @@ static void test_ge(void) {
38223822

38233823
/* Test batch gej -> ge conversion without known z ratios. */
38243824
{
3825+
secp256k1_ge *ge_set_all_var = (secp256k1_ge *)checked_malloc(&CTX->error_callback, (4 * runs + 1) * sizeof(secp256k1_ge));
38253826
secp256k1_ge *ge_set_all = (secp256k1_ge *)checked_malloc(&CTX->error_callback, (4 * runs + 1) * sizeof(secp256k1_ge));
3826-
secp256k1_ge_set_all_gej_var(ge_set_all, gej, 4 * runs + 1);
3827+
secp256k1_ge_set_all_gej_var(&ge_set_all_var[0], &gej[0], 4 * runs + 1);
38273828
for (i = 0; i < 4 * runs + 1; i++) {
3829+
secp256k1_fe s;
3830+
testutil_random_fe_non_zero(&s);
3831+
secp256k1_gej_rescale(&gej[i], &s);
3832+
CHECK(secp256k1_gej_eq_ge_var(&gej[i], &ge_set_all_var[i]));
3833+
}
3834+
3835+
/* Skip infinity at &gej[0]. */
3836+
secp256k1_ge_set_all_gej(&ge_set_all[1], &gej[1], 4 * runs);
3837+
for (i = 1; i < 4 * runs + 1; i++) {
38283838
secp256k1_fe s;
38293839
testutil_random_fe_non_zero(&s);
38303840
secp256k1_gej_rescale(&gej[i], &s);
38313841
CHECK(secp256k1_gej_eq_ge_var(&gej[i], &ge_set_all[i]));
3842+
CHECK(secp256k1_ge_eq_var(&ge_set_all_var[i], &ge_set_all[i]));
38323843
}
3844+
3845+
free(ge_set_all_var);
38333846
free(ge_set_all);
38343847
}
38353848

0 commit comments

Comments
 (0)