From 31b4bbee1e115865a8a3aff6ccf04f6108371c5d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 15 May 2023 09:36:55 -0400 Subject: [PATCH] Make fe_cmov take max of magnitudes --- src/field.h | 4 +++- src/field_impl.h | 6 ++---- src/tests.c | 26 ++++++++++++++------------ 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/field.h b/src/field.h index bbc836b199..ee51188ef4 100644 --- a/src/field.h +++ b/src/field.h @@ -310,7 +310,9 @@ static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_f * * On input, both r and a must be valid field elements. Flag must be 0 or 1. * Performs {r = flag ? a : r}. - * On output, r's magnitude and normalized will equal a's in case of flag=1, unchanged otherwise. + * + * On output, r's magnitude will be the maximum of both input magnitudes. + * It will be normalized if and only if both inputs were normalized. */ static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag); diff --git a/src/field_impl.h b/src/field_impl.h index 7270375007..f9769a4a39 100644 --- a/src/field_impl.h +++ b/src/field_impl.h @@ -352,10 +352,8 @@ SECP256K1_INLINE static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_ secp256k1_fe_verify(a); secp256k1_fe_verify(r); secp256k1_fe_impl_cmov(r, a, flag); - if (flag) { - r->magnitude = a->magnitude; - r->normalized = a->normalized; - } + if (a->magnitude > r->magnitude) r->magnitude = a->magnitude; + if (!a->normalized) r->normalized = 0; secp256k1_fe_verify(r); } diff --git a/src/tests.c b/src/tests.c index 70cee3176b..43ce73ec96 100644 --- a/src/tests.c +++ b/src/tests.c @@ -3101,10 +3101,6 @@ static void run_field_be32_overflow(void) { /* Returns true if two field elements have the same representation. */ static int fe_identical(const secp256k1_fe *a, const secp256k1_fe *b) { int ret = 1; -#ifdef VERIFY - ret &= (a->magnitude == b->magnitude); - ret &= (a->normalized == b->normalized); -#endif /* Compare the struct member that holds the limbs. */ ret &= (secp256k1_memcmp_var(a->n, b->n, sizeof(a->n)) == 0); return ret; @@ -3192,16 +3188,22 @@ static void run_field_misc(void) { q = x; secp256k1_fe_cmov(&x, &z, 0); #ifdef VERIFY - CHECK(x.normalized && x.magnitude == 1); + CHECK(!x.normalized); + CHECK((x.magnitude == q.magnitude) || (x.magnitude == z.magnitude)); + CHECK((x.magnitude >= q.magnitude) && (x.magnitude >= z.magnitude)); #endif + x = q; secp256k1_fe_cmov(&x, &x, 1); CHECK(!fe_identical(&x, &z)); CHECK(fe_identical(&x, &q)); secp256k1_fe_cmov(&q, &z, 1); #ifdef VERIFY - CHECK(!q.normalized && q.magnitude == z.magnitude); + CHECK(!q.normalized); + CHECK((q.magnitude == x.magnitude) || (q.magnitude == z.magnitude)); + CHECK((q.magnitude >= x.magnitude) && (q.magnitude >= z.magnitude)); #endif CHECK(fe_identical(&q, &z)); + q = z; secp256k1_fe_normalize_var(&x); secp256k1_fe_normalize_var(&z); CHECK(!secp256k1_fe_equal_var(&x, &z)); @@ -3215,7 +3217,7 @@ static void run_field_misc(void) { secp256k1_fe_normalize_var(&q); secp256k1_fe_cmov(&q, &z, (j&1)); #ifdef VERIFY - CHECK((q.normalized != (j&1)) && q.magnitude == ((j&1) ? z.magnitude : 1)); + CHECK(!q.normalized && q.magnitude == z.magnitude); #endif } secp256k1_fe_normalize_var(&z); @@ -7558,23 +7560,23 @@ static void fe_cmov_test(void) { secp256k1_fe a = zero; secp256k1_fe_cmov(&r, &a, 0); - CHECK(secp256k1_memcmp_var(&r, &max, sizeof(r)) == 0); + CHECK(fe_identical(&r, &max)); r = zero; a = max; secp256k1_fe_cmov(&r, &a, 1); - CHECK(secp256k1_memcmp_var(&r, &max, sizeof(r)) == 0); + CHECK(fe_identical(&r, &max)); a = zero; secp256k1_fe_cmov(&r, &a, 1); - CHECK(secp256k1_memcmp_var(&r, &zero, sizeof(r)) == 0); + CHECK(fe_identical(&r, &zero)); a = one; secp256k1_fe_cmov(&r, &a, 1); - CHECK(secp256k1_memcmp_var(&r, &one, sizeof(r)) == 0); + CHECK(fe_identical(&r, &one)); r = one; a = zero; secp256k1_fe_cmov(&r, &a, 0); - CHECK(secp256k1_memcmp_var(&r, &one, sizeof(r)) == 0); + CHECK(fe_identical(&r, &one)); } static void fe_storage_cmov_test(void) {