crypto_bigint/uint/ref_type/
mul.rs1use crate::{Choice, Limb, UintRef, uint::mul::karatsuba};
4
5impl UintRef {
6 #[inline(always)]
9 pub fn overflowing_mul(&self, rhs: &UintRef, out: &mut UintRef) -> Choice {
10 let carry = self.wrapping_mul(rhs, out);
11 self.check_mul_overflow(rhs, carry.is_nonzero())
12 }
13
14 #[inline(always)]
17 pub fn overflowing_square(&self, out: &mut UintRef) -> Choice {
18 let carry = self.wrapping_square(out);
19 self.check_square_overflow(carry.is_nonzero())
20 }
21
22 #[inline(always)]
25 pub fn wrapping_mul(&self, rhs: &UintRef, out: &mut UintRef) -> Limb {
26 karatsuba::wrapping_mul(self, rhs, out, false)
27 }
28
29 #[inline(always)]
32 pub fn wrapping_square(&self, out: &mut UintRef) -> Limb {
33 karatsuba::wrapping_square(self, out)
34 }
35
36 #[inline(always)]
43 pub(crate) const fn check_mul_overflow(&self, rhs: &UintRef, mut carry: Choice) -> Choice {
44 let mut rhs_tail = Limb::ZERO;
45 let mut i = 0;
46 let mut j = self.nlimbs();
47 let mut k = rhs.nlimbs().saturating_sub(1);
48 while k > j {
49 rhs_tail = rhs_tail.bitor(rhs.limbs[k]);
50 k -= 1;
51 }
52 while i < self.nlimbs() {
53 j = self.nlimbs() - i;
54 if j < rhs.nlimbs() {
55 rhs_tail = rhs_tail.bitor(rhs.limbs[j]);
56 carry = carry.or(self.limbs[i].is_nonzero().and(rhs_tail.is_nonzero()));
57 }
58 i += 1;
59 }
60 carry
61 }
62
63 #[inline(always)]
65 pub(crate) const fn check_square_overflow(&self, carry: Choice) -> Choice {
66 self.check_mul_overflow(self, carry)
67 }
68}