From 2216ade8c4d98fab12d249b4f7517d556a8fa4a0 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Thu, 4 Sep 2025 20:47:59 -0400 Subject: [PATCH] Tweak how `prime-field` normalizes to the even square root --- crypto/prime-field/src/lib.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crypto/prime-field/src/lib.rs b/crypto/prime-field/src/lib.rs index 6733fc85..ff4f36f3 100644 --- a/crypto/prime-field/src/lib.rs +++ b/crypto/prime-field/src/lib.rs @@ -419,7 +419,7 @@ macro_rules! odd_prime_field_with_specific_repr { const ONE_MOD_EIGHT: bool = (MODULUS.as_words()[0] % 8) == 1; const FIVE_MOD_EIGHT: bool = (MODULUS.as_words()[0] % 8) == 5; - let sqrt = if THREE_MOD_FOUR { + let mut sqrt = if THREE_MOD_FOUR { const SQRT_EXP: UnderlyingUint = MODULUS.shr_vartime(2).wrapping_add(&UnderlyingUint::ONE); Self(self.0.pow(&SQRT_EXP)) @@ -449,7 +449,10 @@ macro_rules! odd_prime_field_with_specific_repr { Self(upsilon * self.0 * (i - Self::ONE.0)) }; - let sqrt = <_>::conditional_select(&sqrt, &-sqrt, sqrt.0.retrieve().is_odd()); + // Normalize to the even choice of square root + // `let ()` is used to assert how `conditional_negate` operates in-place + let () = sqrt.conditional_negate(sqrt.is_odd()); + CtOption::new(sqrt, sqrt.square().ct_eq(self)) } fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {