crypto_bigint/uint/boxed/mul/
helper.rs1use alloc::vec::Vec;
4
5use crate::{BoxedUint, Choice, Limb, UintRef};
6
7#[derive(Debug, Clone)]
9pub struct BoxedMultiplier {
10 product: Vec<Limb>,
11}
12
13impl BoxedMultiplier {
14 pub fn new() -> Self {
15 Self {
16 product: Vec::new(),
17 }
18 }
19
20 fn get_buffer(&mut self, limbs: usize) -> &mut UintRef {
21 self.product.clear();
22 self.product.resize(limbs, Limb::ZERO);
23 UintRef::new_mut(&mut self.product[..limbs])
24 }
25
26 pub fn overflowing_mul(&mut self, lhs: &BoxedUint, rhs: &BoxedUint) -> (&mut UintRef, Choice) {
27 let buf = self.get_buffer(lhs.nlimbs());
28 let overflow = lhs.as_uint_ref().overflowing_mul(rhs.as_uint_ref(), buf);
29 (buf, overflow)
30 }
31
32 pub fn overflowing_mul_assign(&mut self, lhs: &mut BoxedUint, rhs: &BoxedUint) -> Choice {
33 let (buf, overflow) = self.overflowing_mul(lhs, rhs);
34 lhs.as_mut_uint_ref().copy_from(buf);
35 overflow
36 }
37
38 pub fn overflowing_square(&mut self, lhs: &BoxedUint) -> (&mut UintRef, Choice) {
39 let buf = self.get_buffer(lhs.nlimbs());
40 let overflow = lhs.as_uint_ref().overflowing_square(buf);
41 (buf, overflow)
42 }
43
44 pub fn overflowing_square_assign(&mut self, lhs: &mut BoxedUint) -> Choice {
45 let (buf, overflow) = self.overflowing_square(lhs);
46 lhs.as_mut_uint_ref().copy_from(buf);
47 overflow
48 }
49
50 pub fn wrapping_mul(&mut self, lhs: &BoxedUint, rhs: &BoxedUint) -> &mut UintRef {
51 self.wrapping_mul_with_carry(lhs, rhs).0
52 }
53
54 pub fn wrapping_mul_assign(&mut self, lhs: &mut BoxedUint, rhs: &BoxedUint) {
55 let (buf, _) = self.wrapping_mul_with_carry(lhs, rhs);
56 lhs.as_mut_uint_ref().copy_from(buf);
57 }
58
59 fn wrapping_mul_with_carry(
60 &mut self,
61 lhs: &BoxedUint,
62 rhs: &BoxedUint,
63 ) -> (&mut UintRef, Limb) {
64 let buf = self.get_buffer(lhs.nlimbs());
65 let carry = lhs.as_uint_ref().wrapping_mul(rhs.as_uint_ref(), buf);
66 (buf, carry)
67 }
68
69 pub fn wrapping_square_assign(&mut self, lhs: &mut BoxedUint) {
70 let (buf, _) = self.wrapping_square_with_carry(lhs);
71 lhs.as_mut_uint_ref().copy_from(buf);
72 }
73
74 fn wrapping_square_with_carry(&mut self, lhs: &BoxedUint) -> (&mut UintRef, Limb) {
75 let buf = self.get_buffer(lhs.nlimbs());
76 let carry = lhs.as_uint_ref().wrapping_square(buf);
77 (buf, carry)
78 }
79}