From 1e6894bdd74c0b94224f2891c9f5501ac7a3b87a Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 28 Jan 2022 18:45:42 -0500 Subject: [PATCH] Abstract out verify logic for fe_cmov --- src/field.h | 8 +++++++- src/field_10x26_impl.h | 8 +------- src/field_5x52_impl.h | 8 +------- src/field_impl.h | 13 +++++++++++++ 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/field.h b/src/field.h index eb6c586b4832d..daa2c54066792 100644 --- a/src/field.h +++ b/src/field.h @@ -92,6 +92,7 @@ static const secp256k1_fe secp256k1_const_beta = SECP256K1_FE_CONST( # define secp256k1_fe_add secp256k1_fe_impl_add # define secp256k1_fe_mul secp256k1_fe_impl_mul # define secp256k1_fe_sqr secp256k1_fe_impl_sqr +# define secp256k1_fe_cmov secp256k1_fe_impl_cmov #endif /* !defined(VERIFY) */ /** Normalize a field element. @@ -271,7 +272,12 @@ static void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storag /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag); -/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ +/** Conditionally move a field element in constant time. + * + * 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. + */ static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag); /** Halves the value of a field element modulo the field prime. Constant-time. diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h index f34f27bb3dc83..621915017091c 100644 --- a/src/field_10x26_impl.h +++ b/src/field_10x26_impl.h @@ -1035,7 +1035,7 @@ SECP256K1_INLINE static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp25 secp256k1_fe_sqr_inner(r->n, a->n); } -static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { +SECP256K1_INLINE static void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { uint32_t mask0, mask1; volatile int vflag = flag; SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); @@ -1051,12 +1051,6 @@ static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_ r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1); r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1); -#ifdef VERIFY - if (flag) { - r->magnitude = a->magnitude; - r->normalized = a->normalized; - } -#endif } static SECP256K1_INLINE void secp256k1_fe_half(secp256k1_fe *r) { diff --git a/src/field_5x52_impl.h b/src/field_5x52_impl.h index 5e90218c945e8..6a90ef4c4db27 100644 --- a/src/field_5x52_impl.h +++ b/src/field_5x52_impl.h @@ -369,7 +369,7 @@ SECP256K1_INLINE static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp25 secp256k1_fe_sqr_inner(r->n, a->n); } -static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { +SECP256K1_INLINE static void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { uint64_t mask0, mask1; volatile int vflag = flag; SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); @@ -380,12 +380,6 @@ static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_ r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); -#ifdef VERIFY - if (flag) { - r->magnitude = a->magnitude; - r->normalized = a->normalized; - } -#endif } static SECP256K1_INLINE void secp256k1_fe_half(secp256k1_fe *r) { diff --git a/src/field_impl.h b/src/field_impl.h index 89ffc76cc5d89..bb1608d25cc52 100644 --- a/src/field_impl.h +++ b/src/field_impl.h @@ -323,6 +323,19 @@ SECP256K1_INLINE static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_f r->normalized = 0; secp256k1_fe_verify(r); } + +static void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag); +SECP256K1_INLINE static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { + VERIFY_CHECK(flag == 0 || flag == 1); + 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; + } + secp256k1_fe_verify(r); +} #endif /* defined(VERIFY) */ #endif /* SECP256K1_FIELD_IMPL_H */