Skip to content

Commit fcd621b

Browse files
authored
Handle even s in Uint::inv_mod (#523)
This is an oversight from #501 which switched to using Bernstein-Yang inversions for `Uint::inv_odd_mod`. The new implementation assumes `s` is always `Odd` but doesn't actually check for that and set the `ConstCtOption` to be "none" accordingly.
1 parent efb267b commit fcd621b

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

src/const_choice.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,13 @@ impl<T> ConstCtOption<T> {
240240
assert!(self.is_some.is_true_vartime());
241241
self.value
242242
}
243+
244+
/// Apply an additional [`ConstChoice`] requirement to `is_some`.
245+
#[inline]
246+
pub(crate) const fn and_choice(mut self, is_some: ConstChoice) -> Self {
247+
self.is_some = self.is_some.and(is_some);
248+
self
249+
}
243250
}
244251

245252
impl<T> From<ConstCtOption<T>> for CtOption<T> {

src/uint/inv_mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ impl<const LIMBS: usize> Uint<LIMBS> {
106106

107107
// Decompose `self` into RNS with moduli `2^k` and `s` and calculate the inverses.
108108
// Using the fact that `(z^{-1} mod (m1 * m2)) mod m1 == z^{-1} mod m1`
109-
let maybe_a = self.inv_odd_mod(&Odd(s));
109+
let s_is_odd = s.is_odd();
110+
let maybe_a = self.inv_odd_mod(&Odd(s)).and_choice(s_is_odd);
111+
110112
let maybe_b = self.inv_mod2k(k);
111113
let is_some = maybe_a.is_some().and(maybe_b.is_some());
112114

0 commit comments

Comments
 (0)