Skip to content

Commit e9e4526

Browse files
Merge #1317: Make fe_cmov take max of magnitudes
31b4bbe Make fe_cmov take max of magnitudes (Pieter Wuille) Pull request description: This addresses part of #1001. The magnitude and normalization of the output of `secp256k1_fe_cmov` should not depend on the runtime value of `flag`. ACKs for top commit: real-or-random: utACK 31b4bbe stratospher: ACK 31b4bbe. Tree-SHA512: 08bef9f63797cb8a1f3ea63c716c09aaa267dfee285b74ef5fbb47d614569d2787ec73d21bce080214872dfe70246f73cea42ad3c24e6baccecabe3312f71433
2 parents 83186db + 31b4bbe commit e9e4526

File tree

3 files changed

+19
-17
lines changed

3 files changed

+19
-17
lines changed

src/field.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,9 @@ static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_f
310310
*
311311
* On input, both r and a must be valid field elements. Flag must be 0 or 1.
312312
* Performs {r = flag ? a : r}.
313-
* On output, r's magnitude and normalized will equal a's in case of flag=1, unchanged otherwise.
313+
*
314+
* On output, r's magnitude will be the maximum of both input magnitudes.
315+
* It will be normalized if and only if both inputs were normalized.
314316
*/
315317
static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag);
316318

src/field_impl.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,8 @@ SECP256K1_INLINE static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_
352352
secp256k1_fe_verify(a);
353353
secp256k1_fe_verify(r);
354354
secp256k1_fe_impl_cmov(r, a, flag);
355-
if (flag) {
356-
r->magnitude = a->magnitude;
357-
r->normalized = a->normalized;
358-
}
355+
if (a->magnitude > r->magnitude) r->magnitude = a->magnitude;
356+
if (!a->normalized) r->normalized = 0;
359357
secp256k1_fe_verify(r);
360358
}
361359

src/tests.c

+14-12
Original file line numberDiff line numberDiff line change
@@ -3101,10 +3101,6 @@ static void run_field_be32_overflow(void) {
31013101
/* Returns true if two field elements have the same representation. */
31023102
static int fe_identical(const secp256k1_fe *a, const secp256k1_fe *b) {
31033103
int ret = 1;
3104-
#ifdef VERIFY
3105-
ret &= (a->magnitude == b->magnitude);
3106-
ret &= (a->normalized == b->normalized);
3107-
#endif
31083104
/* Compare the struct member that holds the limbs. */
31093105
ret &= (secp256k1_memcmp_var(a->n, b->n, sizeof(a->n)) == 0);
31103106
return ret;
@@ -3192,16 +3188,22 @@ static void run_field_misc(void) {
31923188
q = x;
31933189
secp256k1_fe_cmov(&x, &z, 0);
31943190
#ifdef VERIFY
3195-
CHECK(x.normalized && x.magnitude == 1);
3191+
CHECK(!x.normalized);
3192+
CHECK((x.magnitude == q.magnitude) || (x.magnitude == z.magnitude));
3193+
CHECK((x.magnitude >= q.magnitude) && (x.magnitude >= z.magnitude));
31963194
#endif
3195+
x = q;
31973196
secp256k1_fe_cmov(&x, &x, 1);
31983197
CHECK(!fe_identical(&x, &z));
31993198
CHECK(fe_identical(&x, &q));
32003199
secp256k1_fe_cmov(&q, &z, 1);
32013200
#ifdef VERIFY
3202-
CHECK(!q.normalized && q.magnitude == z.magnitude);
3201+
CHECK(!q.normalized);
3202+
CHECK((q.magnitude == x.magnitude) || (q.magnitude == z.magnitude));
3203+
CHECK((q.magnitude >= x.magnitude) && (q.magnitude >= z.magnitude));
32033204
#endif
32043205
CHECK(fe_identical(&q, &z));
3206+
q = z;
32053207
secp256k1_fe_normalize_var(&x);
32063208
secp256k1_fe_normalize_var(&z);
32073209
CHECK(!secp256k1_fe_equal_var(&x, &z));
@@ -3215,7 +3217,7 @@ static void run_field_misc(void) {
32153217
secp256k1_fe_normalize_var(&q);
32163218
secp256k1_fe_cmov(&q, &z, (j&1));
32173219
#ifdef VERIFY
3218-
CHECK((q.normalized != (j&1)) && q.magnitude == ((j&1) ? z.magnitude : 1));
3220+
CHECK(!q.normalized && q.magnitude == z.magnitude);
32193221
#endif
32203222
}
32213223
secp256k1_fe_normalize_var(&z);
@@ -7558,23 +7560,23 @@ static void fe_cmov_test(void) {
75587560
secp256k1_fe a = zero;
75597561

75607562
secp256k1_fe_cmov(&r, &a, 0);
7561-
CHECK(secp256k1_memcmp_var(&r, &max, sizeof(r)) == 0);
7563+
CHECK(fe_identical(&r, &max));
75627564

75637565
r = zero; a = max;
75647566
secp256k1_fe_cmov(&r, &a, 1);
7565-
CHECK(secp256k1_memcmp_var(&r, &max, sizeof(r)) == 0);
7567+
CHECK(fe_identical(&r, &max));
75667568

75677569
a = zero;
75687570
secp256k1_fe_cmov(&r, &a, 1);
7569-
CHECK(secp256k1_memcmp_var(&r, &zero, sizeof(r)) == 0);
7571+
CHECK(fe_identical(&r, &zero));
75707572

75717573
a = one;
75727574
secp256k1_fe_cmov(&r, &a, 1);
7573-
CHECK(secp256k1_memcmp_var(&r, &one, sizeof(r)) == 0);
7575+
CHECK(fe_identical(&r, &one));
75747576

75757577
r = one; a = zero;
75767578
secp256k1_fe_cmov(&r, &a, 0);
7577-
CHECK(secp256k1_memcmp_var(&r, &one, sizeof(r)) == 0);
7579+
CHECK(fe_identical(&r, &one));
75787580
}
75797581

75807582
static void fe_storage_cmov_test(void) {

0 commit comments

Comments
 (0)