diff --git a/src/boxed/uint.rs b/src/boxed/uint.rs index 0eb88a1ee..1ae097df2 100644 --- a/src/boxed/uint.rs +++ b/src/boxed/uint.rs @@ -172,11 +172,11 @@ impl BoxedUint { /// Sort two [`BoxedUint`]s by precision, returning a tuple of the shorter /// followed by the longer, or the original order if their precision is /// equal. - fn sort_by_precision<'a>(a: &'a Self, b: &'a Self) -> (&'a Self, &'a Self) { + fn sort_by_precision<'a>(a: &'a Self, b: &'a Self) -> (&'a Self, &'a Self, bool) { if a.limbs.len() <= b.limbs.len() { - (a, b) + (a, b, false) } else { - (b, a) + (b, a, true) } } @@ -189,13 +189,17 @@ impl BoxedUint { where F: Fn(Limb, Limb, Limb) -> (Limb, Limb), { - let (shorter, longer) = Self::sort_by_precision(a, b); + let (shorter, longer, swapped) = Self::sort_by_precision(a, b); let mut limbs = Vec::with_capacity(longer.limbs.len()); for i in 0..longer.limbs.len() { let &a = shorter.limbs.get(i).unwrap_or(&Limb::ZERO); let &b = longer.limbs.get(i).unwrap_or(&Limb::ZERO); - let (limb, c) = f(a, b, carry); + let (limb, c) = if swapped { + f(b, a, carry) + } else { + f(a, b, carry) + }; limbs.push(limb); carry = c; } diff --git a/src/boxed/uint/cmp.rs b/src/boxed/uint/cmp.rs index d850fc7d4..1a320523d 100644 --- a/src/boxed/uint/cmp.rs +++ b/src/boxed/uint/cmp.rs @@ -4,17 +4,18 @@ use super::BoxedUint; use crate::Limb; +use core::cmp; use subtle::{Choice, ConstantTimeEq}; impl ConstantTimeEq for BoxedUint { #[inline] fn ct_eq(&self, other: &Self) -> Choice { - let (shorter, longer) = Self::sort_by_precision(self, other); + let limbs = cmp::max(self.nlimbs(), other.nlimbs()); let mut ret = Choice::from(1u8); - for i in 0..longer.limbs.len() { - let a = shorter.limbs.get(i).unwrap_or(&Limb::ZERO); - let b = longer.limbs.get(i).unwrap_or(&Limb::ZERO); + for i in 0..limbs { + let a = self.limbs.get(i).unwrap_or(&Limb::ZERO); + let b = other.limbs.get(i).unwrap_or(&Limb::ZERO); ret &= a.ct_eq(b); } diff --git a/src/boxed/uint/sub.rs b/src/boxed/uint/sub.rs index aee976f77..c459b156b 100644 --- a/src/boxed/uint/sub.rs +++ b/src/boxed/uint/sub.rs @@ -6,8 +6,8 @@ use subtle::CtOption; impl BoxedUint { /// Computes `a + b + carry`, returning the result along with the new carry. #[inline(always)] - pub fn sbb(&self, rhs: &Self, carry: Limb) -> (Self, Limb) { - Self::chain(self, rhs, carry, |a, b, c| a.sbb(b, c)) + pub fn sbb(&self, rhs: &Self, borrow: Limb) -> (Self, Limb) { + Self::chain(self, rhs, borrow, |a, b, c| a.sbb(b, c)) } /// Perform wrapping subition, discarding overflow. @@ -31,10 +31,14 @@ mod tests { use super::{BoxedUint, CheckedSub, Limb}; #[test] - fn sbb_no_carry() { + fn sbb_no_borrow() { let (res, carry) = BoxedUint::one().sbb(&BoxedUint::one(), Limb::ZERO); assert_eq!(res, BoxedUint::zero()); assert_eq!(carry, Limb::ZERO); + + let (res, carry) = BoxedUint::one().sbb(&BoxedUint::zero(), Limb::ZERO); + assert_eq!(res, BoxedUint::one()); + assert_eq!(carry, Limb::ZERO); } #[test]