Skip to content

Commit d3e29db

Browse files
Merge bitcoin-core/secp256k1#1450: Add group.h ge/gej equality functions
04af0ba Replace ge_equals_ge[,j] calls with group.h equality calls (Pieter Wuille) 60525f6 Add unit tests for group.h equality functions (Pieter Wuille) a47cd97 Add group.h ge/gej equality functions (Pieter Wuille) Pull request description: This pull requests removes the test-only functions `ge_equals_ge` and `ge_equals_gej`, and replaces them with proper group.h functions `secp256k1_ge_eq_var` and `secp256k1_gej_eq_ge_var` (mimicking the existing `secp256k1_gej_eq_var` function). This drops some of the arbitrary and undocumented magnitude restristrictions these functions have, makes them properly tested on their own, and makes their semantics cleaner (I'm always left checking whether `ge_equals_ge` does a `CHECK` internally or whether it returns a value...). ACKs for top commit: real-or-random: utACK 04af0ba stratospher: ACK 04af0ba. Tree-SHA512: 49bc409ffa980144d1305c9389a846af45f0a97bfec19d016929056aa918c6a9f020dbe8549f5318fa8e6a4108621cc3cce60331aa0634f84619a1104d20a62a
2 parents 10e6d29 + 04af0ba commit d3e29db

File tree

7 files changed

+92
-73
lines changed

7 files changed

+92
-73
lines changed

src/group.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a
102102
*/
103103
static void secp256k1_ge_table_set_globalz(size_t len, secp256k1_ge *a, const secp256k1_fe *zr);
104104

105+
/** Check two group elements (affine) for equality in variable time. */
106+
static int secp256k1_ge_eq_var(const secp256k1_ge *a, const secp256k1_ge *b);
107+
105108
/** Set a group element (affine) equal to the point at infinity. */
106109
static void secp256k1_ge_set_infinity(secp256k1_ge *r);
107110

@@ -114,6 +117,9 @@ static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a);
114117
/** Check two group elements (jacobian) for equality in variable time. */
115118
static int secp256k1_gej_eq_var(const secp256k1_gej *a, const secp256k1_gej *b);
116119

120+
/** Check two group elements (jacobian and affine) for equality in variable time. */
121+
static int secp256k1_gej_eq_ge_var(const secp256k1_gej *a, const secp256k1_ge *b);
122+
117123
/** Compare the X coordinate of a group element (jacobian).
118124
* The magnitude of the group element's X coordinate must not exceed 31. */
119125
static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a);

src/group_impl.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,35 @@ static int secp256k1_gej_eq_var(const secp256k1_gej *a, const secp256k1_gej *b)
354354
return secp256k1_gej_is_infinity(&tmp);
355355
}
356356

357+
static int secp256k1_gej_eq_ge_var(const secp256k1_gej *a, const secp256k1_ge *b) {
358+
secp256k1_gej tmp;
359+
SECP256K1_GEJ_VERIFY(a);
360+
SECP256K1_GE_VERIFY(b);
361+
362+
secp256k1_gej_neg(&tmp, a);
363+
secp256k1_gej_add_ge_var(&tmp, &tmp, b, NULL);
364+
return secp256k1_gej_is_infinity(&tmp);
365+
}
366+
367+
static int secp256k1_ge_eq_var(const secp256k1_ge *a, const secp256k1_ge *b) {
368+
secp256k1_fe tmp;
369+
SECP256K1_GE_VERIFY(a);
370+
SECP256K1_GE_VERIFY(b);
371+
372+
if (a->infinity != b->infinity) return 0;
373+
if (a->infinity) return 1;
374+
375+
tmp = a->x;
376+
secp256k1_fe_normalize_weak(&tmp);
377+
if (!secp256k1_fe_equal(&tmp, &b->x)) return 0;
378+
379+
tmp = a->y;
380+
secp256k1_fe_normalize_weak(&tmp);
381+
if (!secp256k1_fe_equal(&tmp, &b->y)) return 0;
382+
383+
return 1;
384+
}
385+
357386
static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a) {
358387
secp256k1_fe r;
359388
SECP256K1_FE_VERIFY(x);

src/modules/ellswift/tests_exhaustive_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static void test_exhaustive_ellswift(const secp256k1_context *ctx, const secp256
3232
/* Decode ellswift pubkey and check that it matches the precomputed group element. */
3333
secp256k1_ellswift_decode(ctx, &pub_decoded, ell64);
3434
secp256k1_pubkey_load(ctx, &ge_decoded, &pub_decoded);
35-
ge_equals_ge(&ge_decoded, &group[i]);
35+
CHECK(secp256k1_ge_eq_var(&ge_decoded, &group[i]));
3636
}
3737
}
3838

src/modules/ellswift/tests_impl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ void run_ellswift_tests(void) {
237237
secp256k1_ellswift_decode(CTX, &pubkey2, ell64);
238238
secp256k1_pubkey_load(CTX, &g2, &pubkey2);
239239
/* Compare with original. */
240-
ge_equals_ge(&g, &g2);
240+
CHECK(secp256k1_ge_eq_var(&g, &g2));
241241
}
242242
/* Verify the behavior of secp256k1_ellswift_create */
243243
for (i = 0; i < 400 * COUNT; i++) {
@@ -259,7 +259,7 @@ void run_ellswift_tests(void) {
259259
secp256k1_ellswift_decode(CTX, &pub, ell64);
260260
secp256k1_pubkey_load(CTX, &dec, &pub);
261261
secp256k1_ecmult(&res, NULL, &secp256k1_scalar_zero, &sec);
262-
ge_equals_gej(&dec, &res);
262+
CHECK(secp256k1_gej_eq_ge_var(&res, &dec));
263263
}
264264
/* Verify that secp256k1_ellswift_xdh computes the right shared X coordinate. */
265265
for (i = 0; i < 800 * COUNT; i++) {

src/tests.c

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3706,11 +3706,12 @@ static void test_ge(void) {
37063706
secp256k1_ge_clear(&ge[0]);
37073707
secp256k1_ge_set_gej_var(&ge[0], &gej[0]);
37083708
for (i = 0; i < runs; i++) {
3709-
int j;
3709+
int j, k;
37103710
secp256k1_ge g;
37113711
random_group_element_test(&g);
37123712
if (i >= runs - 2) {
37133713
secp256k1_ge_mul_lambda(&g, &ge[1]);
3714+
CHECK(!secp256k1_ge_eq_var(&g, &ge[1]));
37143715
}
37153716
if (i >= runs - 1) {
37163717
secp256k1_ge_mul_lambda(&g, &g);
@@ -3730,6 +3731,16 @@ static void test_ge(void) {
37303731
random_gej_y_magnitude(&gej[1 + j + 4 * i]);
37313732
random_gej_z_magnitude(&gej[1 + j + 4 * i]);
37323733
}
3734+
3735+
for (j = 0; j < 4; ++j) {
3736+
for (k = 0; k < 4; ++k) {
3737+
int expect_equal = (j >> 1) == (k >> 1);
3738+
CHECK(secp256k1_ge_eq_var(&ge[1 + j + 4 * i], &ge[1 + k + 4 * i]) == expect_equal);
3739+
CHECK(secp256k1_gej_eq_var(&gej[1 + j + 4 * i], &gej[1 + k + 4 * i]) == expect_equal);
3740+
CHECK(secp256k1_gej_eq_ge_var(&gej[1 + j + 4 * i], &ge[1 + k + 4 * i]) == expect_equal);
3741+
CHECK(secp256k1_gej_eq_ge_var(&gej[1 + k + 4 * i], &ge[1 + j + 4 * i]) == expect_equal);
3742+
}
3743+
}
37333744
}
37343745

37353746
/* Generate random zf, and zfi2 = 1/zf^2, zfi3 = 1/zf^3 */
@@ -3759,7 +3770,7 @@ static void test_ge(void) {
37593770

37603771
/* Test gej + ge with Z ratio result (var). */
37613772
secp256k1_gej_add_ge_var(&resj, &gej[i1], &ge[i2], secp256k1_gej_is_infinity(&gej[i1]) ? NULL : &zr);
3762-
ge_equals_gej(&ref, &resj);
3773+
CHECK(secp256k1_gej_eq_ge_var(&resj, &ref));
37633774
if (!secp256k1_gej_is_infinity(&gej[i1]) && !secp256k1_gej_is_infinity(&resj)) {
37643775
secp256k1_fe zrz; secp256k1_fe_mul(&zrz, &zr, &gej[i1].z);
37653776
CHECK(secp256k1_fe_equal(&zrz, &resj.z));
@@ -3773,31 +3784,31 @@ static void test_ge(void) {
37733784
random_ge_x_magnitude(&ge2_zfi);
37743785
random_ge_y_magnitude(&ge2_zfi);
37753786
secp256k1_gej_add_zinv_var(&resj, &gej[i1], &ge2_zfi, &zf);
3776-
ge_equals_gej(&ref, &resj);
3787+
CHECK(secp256k1_gej_eq_ge_var(&resj, &ref));
37773788
}
37783789

37793790
/* Test gej + ge (const). */
37803791
if (i2 != 0) {
37813792
/* secp256k1_gej_add_ge does not support its second argument being infinity. */
37823793
secp256k1_gej_add_ge(&resj, &gej[i1], &ge[i2]);
3783-
ge_equals_gej(&ref, &resj);
3794+
CHECK(secp256k1_gej_eq_ge_var(&resj, &ref));
37843795
}
37853796

37863797
/* Test doubling (var). */
37873798
if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 == ((i2 + 3)%4)/2)) {
37883799
secp256k1_fe zr2;
37893800
/* Normal doubling with Z ratio result. */
37903801
secp256k1_gej_double_var(&resj, &gej[i1], &zr2);
3791-
ge_equals_gej(&ref, &resj);
3802+
CHECK(secp256k1_gej_eq_ge_var(&resj, &ref));
37923803
/* Check Z ratio. */
37933804
secp256k1_fe_mul(&zr2, &zr2, &gej[i1].z);
37943805
CHECK(secp256k1_fe_equal(&zr2, &resj.z));
37953806
/* Normal doubling. */
37963807
secp256k1_gej_double_var(&resj, &gej[i2], NULL);
3797-
ge_equals_gej(&ref, &resj);
3808+
CHECK(secp256k1_gej_eq_ge_var(&resj, &ref));
37983809
/* Constant-time doubling. */
37993810
secp256k1_gej_double(&resj, &gej[i2]);
3800-
ge_equals_gej(&ref, &resj);
3811+
CHECK(secp256k1_gej_eq_ge_var(&resj, &ref));
38013812
}
38023813

38033814
/* Test adding opposites. */
@@ -3809,12 +3820,12 @@ static void test_ge(void) {
38093820
if (i1 == 0) {
38103821
CHECK(secp256k1_ge_is_infinity(&ge[i1]));
38113822
CHECK(secp256k1_gej_is_infinity(&gej[i1]));
3812-
ge_equals_gej(&ref, &gej[i2]);
3823+
CHECK(secp256k1_gej_eq_ge_var(&gej[i2], &ref));
38133824
}
38143825
if (i2 == 0) {
38153826
CHECK(secp256k1_ge_is_infinity(&ge[i2]));
38163827
CHECK(secp256k1_gej_is_infinity(&gej[i2]));
3817-
ge_equals_gej(&ref, &gej[i1]);
3828+
CHECK(secp256k1_gej_eq_ge_var(&gej[i1], &ref));
38183829
}
38193830
}
38203831
}
@@ -3849,7 +3860,7 @@ static void test_ge(void) {
38493860
secp256k1_fe s;
38503861
random_fe_non_zero(&s);
38513862
secp256k1_gej_rescale(&gej[i], &s);
3852-
ge_equals_gej(&ge_set_all[i], &gej[i]);
3863+
CHECK(secp256k1_gej_eq_ge_var(&gej[i], &ge_set_all[i]));
38533864
}
38543865
free(ge_set_all);
38553866
}
@@ -3893,7 +3904,7 @@ static void test_ge(void) {
38933904
secp256k1_ge_set_all_gej_var(ge, gej, 4 * runs + 1);
38943905
/* check result */
38953906
for (i = 0; i < 4 * runs + 1; i++) {
3896-
ge_equals_gej(&ge[i], &gej[i]);
3907+
CHECK(secp256k1_gej_eq_ge_var(&gej[i], &ge[i]));
38973908
}
38983909

38993910
/* Test batch gej -> ge conversion with all infinities. */
@@ -3992,15 +4003,15 @@ static void test_add_neg_y_diff_x(void) {
39924003

39934004
secp256k1_gej_add_var(&resj, &aj, &bj, NULL);
39944005
secp256k1_ge_set_gej(&res, &resj);
3995-
ge_equals_gej(&res, &sumj);
4006+
CHECK(secp256k1_gej_eq_ge_var(&sumj, &res));
39964007

39974008
secp256k1_gej_add_ge(&resj, &aj, &b);
39984009
secp256k1_ge_set_gej(&res, &resj);
3999-
ge_equals_gej(&res, &sumj);
4010+
CHECK(secp256k1_gej_eq_ge_var(&sumj, &res));
40004011

40014012
secp256k1_gej_add_ge_var(&resj, &aj, &b, NULL);
40024013
secp256k1_ge_set_gej(&res, &resj);
4003-
ge_equals_gej(&res, &sumj);
4014+
CHECK(secp256k1_gej_eq_ge_var(&sumj, &res));
40044015
}
40054016

40064017
static void run_ge(void) {
@@ -4293,10 +4304,10 @@ static void test_point_times_order(const secp256k1_gej *point) {
42934304
CHECK(secp256k1_ge_is_infinity(&res3));
42944305
secp256k1_ecmult(&res1, point, &secp256k1_scalar_one, &secp256k1_scalar_zero);
42954306
secp256k1_ge_set_gej(&res3, &res1);
4296-
ge_equals_gej(&res3, point);
4307+
CHECK(secp256k1_gej_eq_ge_var(point, &res3));
42974308
secp256k1_ecmult(&res1, point, &secp256k1_scalar_zero, &secp256k1_scalar_one);
42984309
secp256k1_ge_set_gej(&res3, &res1);
4299-
ge_equals_ge(&res3, &secp256k1_ge_const_g);
4310+
CHECK(secp256k1_ge_eq_var(&secp256k1_ge_const_g, &res3));
43004311
}
43014312

43024313
/* These scalars reach large (in absolute value) outputs when fed to secp256k1_scalar_split_lambda.
@@ -4424,7 +4435,7 @@ static void ecmult_const_random_mult(void) {
44244435
secp256k1_ecmult_const(&b, &a, &xn);
44254436

44264437
CHECK(secp256k1_ge_is_valid_var(&a));
4427-
ge_equals_gej(&expected_b, &b);
4438+
CHECK(secp256k1_gej_eq_ge_var(&b, &expected_b));
44284439
}
44294440

44304441
static void ecmult_const_commutativity(void) {
@@ -4445,7 +4456,7 @@ static void ecmult_const_commutativity(void) {
44454456
secp256k1_ecmult_const(&res2, &mid2, &a);
44464457
secp256k1_ge_set_gej(&mid1, &res1);
44474458
secp256k1_ge_set_gej(&mid2, &res2);
4448-
ge_equals_ge(&mid1, &mid2);
4459+
CHECK(secp256k1_ge_eq_var(&mid1, &mid2));
44494460
}
44504461

44514462
static void ecmult_const_mult_zero_one(void) {
@@ -4472,13 +4483,13 @@ static void ecmult_const_mult_zero_one(void) {
44724483
/* 1*point */
44734484
secp256k1_ecmult_const(&res1, &point, &secp256k1_scalar_one);
44744485
secp256k1_ge_set_gej(&res2, &res1);
4475-
ge_equals_ge(&res2, &point);
4486+
CHECK(secp256k1_ge_eq_var(&res2, &point));
44764487

44774488
/* -1*point */
44784489
secp256k1_ecmult_const(&res1, &point, &negone);
44794490
secp256k1_gej_neg(&res1, &res1);
44804491
secp256k1_ge_set_gej(&res2, &res1);
4481-
ge_equals_ge(&res2, &point);
4492+
CHECK(secp256k1_ge_eq_var(&res2, &point));
44824493
}
44834494

44844495
static void ecmult_const_check_result(const secp256k1_ge *A, const secp256k1_scalar* q, const secp256k1_gej *res) {
@@ -4487,7 +4498,7 @@ static void ecmult_const_check_result(const secp256k1_ge *A, const secp256k1_sca
44874498
secp256k1_gej_set_ge(&pointj, A);
44884499
secp256k1_ecmult(&res2j, &pointj, q, &secp256k1_scalar_zero);
44894500
secp256k1_ge_set_gej(&res2, &res2j);
4490-
ge_equals_gej(&res2, res);
4501+
CHECK(secp256k1_gej_eq_ge_var(res, &res2));
44914502
}
44924503

44934504
static void ecmult_const_edges(void) {
@@ -4595,7 +4606,7 @@ static void ecmult_const_chain_multiply(void) {
45954606
secp256k1_ecmult_const(&point, &tmp, &scalar);
45964607
}
45974608
secp256k1_ge_set_gej(&res, &point);
4598-
ge_equals_gej(&res, &expected_point);
4609+
CHECK(secp256k1_gej_eq_ge_var(&expected_point, &res));
45994610
}
46004611

46014612
static void run_ecmult_const_tests(void) {
@@ -5403,11 +5414,11 @@ static void test_ecmult_accumulate(secp256k1_sha256* acc, const secp256k1_scalar
54035414
secp256k1_ecmult_multi_var(NULL, scratch, &rj5, &secp256k1_scalar_zero, test_ecmult_accumulate_cb, (void*)x, 1);
54045415
secp256k1_ecmult_const(&rj6, &secp256k1_ge_const_g, x);
54055416
secp256k1_ge_set_gej_var(&r, &rj1);
5406-
ge_equals_gej(&r, &rj2);
5407-
ge_equals_gej(&r, &rj3);
5408-
ge_equals_gej(&r, &rj4);
5409-
ge_equals_gej(&r, &rj5);
5410-
ge_equals_gej(&r, &rj6);
5417+
CHECK(secp256k1_gej_eq_ge_var(&rj2, &r));
5418+
CHECK(secp256k1_gej_eq_ge_var(&rj3, &r));
5419+
CHECK(secp256k1_gej_eq_ge_var(&rj4, &r));
5420+
CHECK(secp256k1_gej_eq_ge_var(&rj5, &r));
5421+
CHECK(secp256k1_gej_eq_ge_var(&rj6, &r));
54115422
if (secp256k1_ge_is_infinity(&r)) {
54125423
/* Store infinity as 0x00 */
54135424
const unsigned char zerobyte[1] = {0};
@@ -5561,7 +5572,7 @@ static void test_ecmult_gen_blind(void) {
55615572
CHECK(!gej_xyz_equals_gej(&pgej, &pgej2));
55625573
CHECK(!gej_xyz_equals_gej(&i, &CTX->ecmult_gen_ctx.initial));
55635574
secp256k1_ge_set_gej(&pge, &pgej);
5564-
ge_equals_gej(&pge, &pgej2);
5575+
CHECK(secp256k1_gej_eq_ge_var(&pgej2, &pge));
55655576
}
55665577

55675578
static void test_ecmult_gen_blind_reset(void) {
@@ -5952,7 +5963,7 @@ static void run_ec_pubkey_parse_test(void) {
59525963
SECP256K1_CHECKMEM_CHECK(&ge.x, sizeof(ge.x));
59535964
SECP256K1_CHECKMEM_CHECK(&ge.y, sizeof(ge.y));
59545965
SECP256K1_CHECKMEM_CHECK(&ge.infinity, sizeof(ge.infinity));
5955-
ge_equals_ge(&secp256k1_ge_const_g, &ge);
5966+
CHECK(secp256k1_ge_eq_var(&ge, &secp256k1_ge_const_g));
59565967
/* secp256k1_ec_pubkey_serialize illegal args. */
59575968
len = 65;
59585969
CHECK_ILLEGAL(CTX, secp256k1_ec_pubkey_serialize(CTX, NULL, &len, &pubkey, SECP256K1_EC_UNCOMPRESSED));
@@ -6521,7 +6532,7 @@ static void test_random_pubkeys(void) {
65216532
CHECK(secp256k1_eckey_pubkey_serialize(&elem, in, &size, 0));
65226533
CHECK(size == 65);
65236534
CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size));
6524-
ge_equals_ge(&elem,&elem2);
6535+
CHECK(secp256k1_ge_eq_var(&elem2, &elem));
65256536
/* Check that the X9.62 hybrid type is checked. */
65266537
in[0] = secp256k1_testrand_bits(1) ? 6 : 7;
65276538
res = secp256k1_eckey_pubkey_parse(&elem2, in, size);
@@ -6533,7 +6544,7 @@ static void test_random_pubkeys(void) {
65336544
}
65346545
}
65356546
if (res) {
6536-
ge_equals_ge(&elem,&elem2);
6547+
CHECK(secp256k1_ge_eq_var(&elem, &elem2));
65376548
CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, 0));
65386549
CHECK(secp256k1_memcmp_var(&in[1], &out[1], 64) == 0);
65396550
}

0 commit comments

Comments
 (0)