Skip to main content

crypto_bigint/uint/ref_type/
sub.rs

1use super::UintRef;
2use crate::Limb;
3use ctutils::Choice;
4
5impl UintRef {
6    /// Perform an in-place borrowing sub of a limb, returning the borrowed limb value.
7    #[inline]
8    pub const fn borrowing_sub_assign_limb(&mut self, mut rhs: Limb, mut borrow: Limb) -> Limb {
9        let mut i = 0;
10        while i < self.limbs.len() {
11            (self.limbs[i], borrow) = self.limbs[i].borrowing_sub(rhs, borrow);
12            rhs = Limb::ZERO;
13            i += 1;
14        }
15        borrow
16    }
17
18    /// Perform an in-place borrowing subtraction of another [`UintRef`], returning the carried limb
19    /// value.
20    #[inline]
21    pub const fn borrowing_sub_assign(&mut self, rhs: &Self, borrow: Limb) -> Limb {
22        self.borrowing_sub_assign_slice(&rhs.limbs, borrow)
23    }
24
25    /// Perform an in-place borrowing subtraction of another limb slice, returning the borrowed limb
26    /// value.
27    ///
28    /// # Panics
29    /// If `self` and `rhs` have different lengths.
30    #[inline]
31    pub const fn borrowing_sub_assign_slice(&mut self, rhs: &[Limb], mut borrow: Limb) -> Limb {
32        assert!(self.limbs.len() == rhs.len(), "length mismatch");
33        let mut i = 0;
34        while i < self.limbs.len() {
35            (self.limbs[i], borrow) = self.limbs[i].borrowing_sub(rhs[i], borrow);
36            i += 1;
37        }
38        borrow
39    }
40
41    /// Perform in-place wrapping subtraction, returning the truthy value as the second element of
42    /// the tuple if an underflow has occurred.
43    pub(crate) fn conditional_borrowing_sub_assign(
44        &mut self,
45        rhs: &Self,
46        choice: Choice,
47    ) -> Choice {
48        debug_assert!(self.bits_precision() <= rhs.bits_precision());
49        let mask = Limb::select(Limb::ZERO, Limb::MAX, choice);
50        let mut borrow = Limb::ZERO;
51
52        for i in 0..self.nlimbs() {
53            let masked_rhs = *rhs.limbs.get(i).unwrap_or(&Limb::ZERO) & mask;
54            let (limb, b) = self.limbs[i].borrowing_sub(masked_rhs, borrow);
55            self.limbs[i] = limb;
56            borrow = b;
57        }
58
59        borrow.lsb_to_choice()
60    }
61}