diff options
Diffstat (limited to 'vendor/crypto-bigint/src/uint/sub_mod.rs')
-rw-r--r-- | vendor/crypto-bigint/src/uint/sub_mod.rs | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/vendor/crypto-bigint/src/uint/sub_mod.rs b/vendor/crypto-bigint/src/uint/sub_mod.rs index 728a92760..b32babb89 100644 --- a/vendor/crypto-bigint/src/uint/sub_mod.rs +++ b/vendor/crypto-bigint/src/uint/sub_mod.rs @@ -7,21 +7,31 @@ impl<const LIMBS: usize> Uint<LIMBS> { /// /// Assumes `self - rhs` as unbounded signed integer is in `[-p, p)`. pub const fn sub_mod(&self, rhs: &Uint<LIMBS>, p: &Uint<LIMBS>) -> Uint<LIMBS> { - let (mut out, borrow) = self.sbb(rhs, Limb::ZERO); + let (out, borrow) = self.sbb(rhs, Limb::ZERO); // If underflow occurred on the final limb, borrow = 0xfff...fff, otherwise // borrow = 0x000...000. Thus, we use it as a mask to conditionally add the modulus. - let mut carry = Limb::ZERO; - let mut i = 0; + let mask = Uint::from_words([borrow.0; LIMBS]); + + out.wrapping_add(&p.bitand(&mask)) + } - while i < LIMBS { - let (l, c) = out.limbs[i].adc(p.limbs[i].bitand(borrow), carry); - out.limbs[i] = l; - carry = c; - i += 1; - } + /// Returns `(self..., carry) - (rhs...) mod (p...)`, where `carry <= 1`. + /// Assumes `-(p...) <= (self..., carry) - (rhs...) < (p...)`. + #[inline(always)] + pub(crate) const fn sub_mod_with_carry(&self, carry: Limb, rhs: &Self, p: &Self) -> Self { + debug_assert!(carry.0 <= 1); + + let (out, borrow) = self.sbb(rhs, Limb::ZERO); + + // The new `borrow = Word::MAX` iff `carry == 0` and `borrow == Word::MAX`. + let borrow = (!carry.0.wrapping_neg()) & borrow.0; + + // If underflow occurred on the final limb, borrow = 0xfff...fff, otherwise + // borrow = 0x000...000. Thus, we use it as a mask to conditionally add the modulus. + let mask = Uint::from_words([borrow; LIMBS]); - out + out.wrapping_add(&p.bitand(&mask)) } /// Computes `self - rhs mod p` in constant time for the special modulus @@ -35,8 +45,7 @@ impl<const LIMBS: usize> Uint<LIMBS> { // the underflow. This cannot underflow due to the assumption // `self - rhs >= -p`. let l = borrow.0 & c.0; - let (out, _) = out.sbb(&Uint::from_word(l), Limb::ZERO); - out + out.wrapping_sub(&Uint::from_word(l)) } } |