Abstract out verify logic for fe_negate

This commit is contained in:
Pieter Wuille 2022-01-28 18:27:38 -05:00
parent 144670893e
commit 65d82a3445
4 changed files with 29 additions and 22 deletions

View File

@ -87,6 +87,7 @@ static const secp256k1_fe secp256k1_const_beta = SECP256K1_FE_CONST(
# define secp256k1_fe_cmp_var secp256k1_fe_impl_cmp_var # define secp256k1_fe_cmp_var secp256k1_fe_impl_cmp_var
# define secp256k1_fe_set_b32 secp256k1_fe_impl_set_b32 # define secp256k1_fe_set_b32 secp256k1_fe_impl_set_b32
# define secp256k1_fe_get_b32 secp256k1_fe_impl_get_b32 # define secp256k1_fe_get_b32 secp256k1_fe_impl_get_b32
# define secp256k1_fe_negate secp256k1_fe_impl_negate
#endif /* !defined(VERIFY) */ #endif /* !defined(VERIFY) */
/** Normalize a field element. /** Normalize a field element.
@ -192,8 +193,13 @@ static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a);
*/ */
static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a); static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a);
/** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input /** Negate a field element.
* as an argument. The magnitude of the output is one higher. */ *
* On input, r does not need to be initialized. a must be a valid field element with
* magnitude not exceeding m. m must be an integer in [0,31].
* Performs {r = -a}.
* On output, r will not be normalized, and will have magnitude m+1.
*/
static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m); static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m);
/** Adds a small integer (up to 0x7FFF) to r. The resulting magnitude increases by one. */ /** Adds a small integer (up to 0x7FFF) to r. The resulting magnitude increases by one. */

View File

@ -349,15 +349,15 @@ static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a) {
r[31] = a->n[0] & 0xff; r[31] = a->n[0] & 0xff;
} }
SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { SECP256K1_INLINE static void secp256k1_fe_impl_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) {
#ifdef VERIFY /* For all legal values of m (0..31), the following properties hold: */
VERIFY_CHECK(a->magnitude <= m);
secp256k1_fe_verify(a);
VERIFY_CHECK(0x3FFFC2FUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m); VERIFY_CHECK(0x3FFFC2FUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m);
VERIFY_CHECK(0x3FFFFBFUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m); VERIFY_CHECK(0x3FFFFBFUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m);
VERIFY_CHECK(0x3FFFFFFUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m); VERIFY_CHECK(0x3FFFFFFUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m);
VERIFY_CHECK(0x03FFFFFUL * 2 * (m + 1) >= 0x03FFFFFUL * 2 * m); VERIFY_CHECK(0x03FFFFFUL * 2 * (m + 1) >= 0x03FFFFFUL * 2 * m);
#endif
/* Due to the properties above, the left hand in the subtractions below is never less than
* the right hand. */
r->n[0] = 0x3FFFC2FUL * 2 * (m + 1) - a->n[0]; r->n[0] = 0x3FFFC2FUL * 2 * (m + 1) - a->n[0];
r->n[1] = 0x3FFFFBFUL * 2 * (m + 1) - a->n[1]; r->n[1] = 0x3FFFFBFUL * 2 * (m + 1) - a->n[1];
r->n[2] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[2]; r->n[2] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[2];
@ -368,11 +368,6 @@ SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k
r->n[7] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[7]; r->n[7] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[7];
r->n[8] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[8]; r->n[8] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[8];
r->n[9] = 0x03FFFFFUL * 2 * (m + 1) - a->n[9]; r->n[9] = 0x03FFFFFUL * 2 * (m + 1) - a->n[9];
#ifdef VERIFY
r->magnitude = m + 1;
r->normalized = 0;
secp256k1_fe_verify(r);
#endif
} }
SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) {

View File

@ -318,24 +318,19 @@ static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a) {
r[31] = a->n[0] & 0xFF; r[31] = a->n[0] & 0xFF;
} }
SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { SECP256K1_INLINE static void secp256k1_fe_impl_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) {
#ifdef VERIFY /* For all legal values of m (0..31), the following properties hold: */
VERIFY_CHECK(a->magnitude <= m);
secp256k1_fe_verify(a);
VERIFY_CHECK(0xFFFFEFFFFFC2FULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m); VERIFY_CHECK(0xFFFFEFFFFFC2FULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m);
VERIFY_CHECK(0xFFFFFFFFFFFFFULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m); VERIFY_CHECK(0xFFFFFFFFFFFFFULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m);
VERIFY_CHECK(0x0FFFFFFFFFFFFULL * 2 * (m + 1) >= 0x0FFFFFFFFFFFFULL * 2 * m); VERIFY_CHECK(0x0FFFFFFFFFFFFULL * 2 * (m + 1) >= 0x0FFFFFFFFFFFFULL * 2 * m);
#endif
/* Due to the properties above, the left hand in the subtractions below is never less than
* the right hand. */
r->n[0] = 0xFFFFEFFFFFC2FULL * 2 * (m + 1) - a->n[0]; r->n[0] = 0xFFFFEFFFFFC2FULL * 2 * (m + 1) - a->n[0];
r->n[1] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[1]; r->n[1] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[1];
r->n[2] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[2]; r->n[2] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[2];
r->n[3] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[3]; r->n[3] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[3];
r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * (m + 1) - a->n[4]; r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * (m + 1) - a->n[4];
#ifdef VERIFY
r->magnitude = m + 1;
r->normalized = 0;
secp256k1_fe_verify(r);
#endif
} }
SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) {

View File

@ -253,6 +253,17 @@ SECP256K1_INLINE static void secp256k1_fe_get_b32(unsigned char *r, const secp25
VERIFY_CHECK(a->normalized); VERIFY_CHECK(a->normalized);
secp256k1_fe_impl_get_b32(r, a); secp256k1_fe_impl_get_b32(r, a);
} }
static void secp256k1_fe_impl_negate(secp256k1_fe *r, const secp256k1_fe *a, int m);
SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) {
secp256k1_fe_verify(a);
VERIFY_CHECK(m >= 0 && m <= 31);
VERIFY_CHECK(a->magnitude <= m);
secp256k1_fe_impl_negate(r, a, m);
r->magnitude = m + 1;
r->normalized = 0;
secp256k1_fe_verify(r);
}
#endif /* defined(VERIFY) */ #endif /* defined(VERIFY) */
#endif /* SECP256K1_FIELD_IMPL_H */ #endif /* SECP256K1_FIELD_IMPL_H */