From d5aa2f035802047c45605bfa69fb467000e9288f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 28 Jan 2022 19:20:51 -0500 Subject: [PATCH] Abstract out verify logic for fe_inv{,_var} --- src/field.h | 16 +++++++++++++--- src/field_10x26_impl.h | 28 ++++------------------------ src/field_5x52_impl.h | 28 ++++------------------------ src/field_impl.h | 22 ++++++++++++++++++++++ 4 files changed, 43 insertions(+), 51 deletions(-) diff --git a/src/field.h b/src/field.h index cb330635d..953919d9a 100644 --- a/src/field.h +++ b/src/field.h @@ -95,6 +95,8 @@ static const secp256k1_fe secp256k1_const_beta = SECP256K1_FE_CONST( # define secp256k1_fe_cmov secp256k1_fe_impl_cmov # define secp256k1_fe_to_storage secp256k1_fe_impl_to_storage # define secp256k1_fe_from_storage secp256k1_fe_impl_from_storage +# define secp256k1_fe_inv secp256k1_fe_impl_inv +# define secp256k1_fe_inv_var secp256k1_fe_impl_inv_var #endif /* !defined(VERIFY) */ /** Normalize a field element. @@ -258,11 +260,19 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a); */ static int secp256k1_fe_sqrt(secp256k1_fe * SECP256K1_RESTRICT r, const secp256k1_fe * SECP256K1_RESTRICT a); -/** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be - * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */ +/** Compute the modular inverse of a field element. + * + * On input, a must be a valid field element; r need not be initialized. + * Performs {r = a**(p-2)} (which maps 0 to 0, and every other element to its + * inverse). + * On output, r will have magnitude (a.magnitude != 0) and be normalized. + */ static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a); -/** Potentially faster version of secp256k1_fe_inv, without constant-time guarantee. */ +/** Compute the modular inverse of a field element, without constant-time guarantee. + * + * Behaves identically to secp256k1_fe_inv, but is not constant-time in a. + */ static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a); /** Convert a field element to secp256k1_fe_storage. diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h index 55d152ec2..d7b30cc87 100644 --- a/src/field_10x26_impl.h +++ b/src/field_10x26_impl.h @@ -1197,12 +1197,6 @@ static void secp256k1_fe_from_signed30(secp256k1_fe *r, const secp256k1_modinv32 r->n[7] = (a6 >> 2 ) & M26; r->n[8] = (a6 >> 28 | a7 << 2) & M26; r->n[9] = (a7 >> 24 | a8 << 6); - -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif } static void secp256k1_fe_to_signed30(secp256k1_modinv32_signed30 *r, const secp256k1_fe *a) { @@ -1210,10 +1204,6 @@ static void secp256k1_fe_to_signed30(secp256k1_modinv32_signed30 *r, const secp2 const uint64_t a0 = a->n[0], a1 = a->n[1], a2 = a->n[2], a3 = a->n[3], a4 = a->n[4], a5 = a->n[5], a6 = a->n[6], a7 = a->n[7], a8 = a->n[8], a9 = a->n[9]; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); -#endif - r->v[0] = (a0 | a1 << 26) & M30; r->v[1] = (a1 >> 4 | a2 << 22) & M30; r->v[2] = (a2 >> 8 | a3 << 18) & M30; @@ -1231,34 +1221,24 @@ static const secp256k1_modinv32_modinfo secp256k1_const_modinfo_fe = { 0x2DDACACFL }; -static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *x) { - secp256k1_fe tmp; +static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x) { + secp256k1_fe tmp = *x; secp256k1_modinv32_signed30 s; - tmp = *x; secp256k1_fe_normalize(&tmp); secp256k1_fe_to_signed30(&s, &tmp); secp256k1_modinv32(&s, &secp256k1_const_modinfo_fe); secp256k1_fe_from_signed30(r, &s); - -#ifdef VERIFY - VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp)); -#endif } -static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) { - secp256k1_fe tmp; +static void secp256k1_fe_impl_inv_var(secp256k1_fe *r, const secp256k1_fe *x) { + secp256k1_fe tmp = *x; secp256k1_modinv32_signed30 s; - tmp = *x; secp256k1_fe_normalize_var(&tmp); secp256k1_fe_to_signed30(&s, &tmp); secp256k1_modinv32_var(&s, &secp256k1_const_modinfo_fe); secp256k1_fe_from_signed30(r, &s); - -#ifdef VERIFY - VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp)); -#endif } static int secp256k1_fe_is_square_var(const secp256k1_fe *x) { diff --git a/src/field_5x52_impl.h b/src/field_5x52_impl.h index 1946fbb88..e056cc262 100644 --- a/src/field_5x52_impl.h +++ b/src/field_5x52_impl.h @@ -492,22 +492,12 @@ static void secp256k1_fe_from_signed62(secp256k1_fe *r, const secp256k1_modinv64 r->n[2] = (a1 >> 42 | a2 << 20) & M52; r->n[3] = (a2 >> 32 | a3 << 30) & M52; r->n[4] = (a3 >> 22 | a4 << 40); - -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif } static void secp256k1_fe_to_signed62(secp256k1_modinv64_signed62 *r, const secp256k1_fe *a) { const uint64_t M62 = UINT64_MAX >> 2; const uint64_t a0 = a->n[0], a1 = a->n[1], a2 = a->n[2], a3 = a->n[3], a4 = a->n[4]; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); -#endif - r->v[0] = (a0 | a1 << 52) & M62; r->v[1] = (a1 >> 10 | a2 << 42) & M62; r->v[2] = (a2 >> 20 | a3 << 32) & M62; @@ -520,34 +510,24 @@ static const secp256k1_modinv64_modinfo secp256k1_const_modinfo_fe = { 0x27C7F6E22DDACACFLL }; -static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *x) { - secp256k1_fe tmp; +static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x) { + secp256k1_fe tmp = *x; secp256k1_modinv64_signed62 s; - tmp = *x; secp256k1_fe_normalize(&tmp); secp256k1_fe_to_signed62(&s, &tmp); secp256k1_modinv64(&s, &secp256k1_const_modinfo_fe); secp256k1_fe_from_signed62(r, &s); - -#ifdef VERIFY - VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp)); -#endif } -static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) { - secp256k1_fe tmp; +static void secp256k1_fe_impl_inv_var(secp256k1_fe *r, const secp256k1_fe *x) { + secp256k1_fe tmp = *x; secp256k1_modinv64_signed62 s; - tmp = *x; secp256k1_fe_normalize_var(&tmp); secp256k1_fe_to_signed62(&s, &tmp); secp256k1_modinv64_var(&s, &secp256k1_const_modinfo_fe); secp256k1_fe_from_signed62(r, &s); - -#ifdef VERIFY - VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp)); -#endif } static int secp256k1_fe_is_square_var(const secp256k1_fe *x) { diff --git a/src/field_impl.h b/src/field_impl.h index 0e1c7630b..3c03e2635 100644 --- a/src/field_impl.h +++ b/src/field_impl.h @@ -351,6 +351,28 @@ SECP256K1_INLINE static void secp256k1_fe_from_storage(secp256k1_fe *r, const se r->normalized = 1; secp256k1_fe_verify(r); } + +static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x); +SECP256K1_INLINE static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *x) { + int input_is_zero = secp256k1_fe_normalizes_to_zero(x); + secp256k1_fe_verify(x); + secp256k1_fe_impl_inv(r, x); + r->magnitude = x->magnitude > 0; + r->normalized = 1; + VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == input_is_zero); + secp256k1_fe_verify(r); +} + +static void secp256k1_fe_impl_inv_var(secp256k1_fe *r, const secp256k1_fe *x); +SECP256K1_INLINE static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) { + int input_is_zero = secp256k1_fe_normalizes_to_zero(x); + secp256k1_fe_verify(x); + secp256k1_fe_impl_inv_var(r, x); + r->magnitude = x->magnitude > 0; + r->normalized = 1; + VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == input_is_zero); + secp256k1_fe_verify(r); +} #endif /* defined(VERIFY) */ #endif /* SECP256K1_FIELD_IMPL_H */