crypto_bigint/modular/boxed_monty_form/
add.rs1use super::BoxedMontyForm;
4use core::ops::{Add, AddAssign};
5
6impl BoxedMontyForm {
7 #[must_use]
9 pub fn add(&self, rhs: &Self) -> Self {
10 debug_assert_eq!(self.params, rhs.params);
11
12 Self {
13 montgomery_form: self
14 .montgomery_form
15 .add_mod(&rhs.montgomery_form, self.params.modulus().as_nz_ref()),
16 params: self.params.clone(),
17 }
18 }
19
20 #[must_use]
22 pub fn double(&self) -> Self {
23 Self {
24 montgomery_form: self
25 .montgomery_form
26 .double_mod(self.params.modulus().as_nz_ref()),
27 params: self.params.clone(),
28 }
29 }
30}
31
32impl Add<&BoxedMontyForm> for &BoxedMontyForm {
33 type Output = BoxedMontyForm;
34 fn add(self, rhs: &BoxedMontyForm) -> BoxedMontyForm {
35 self.add(rhs)
36 }
37}
38
39impl Add<BoxedMontyForm> for &BoxedMontyForm {
40 type Output = BoxedMontyForm;
41 #[allow(clippy::op_ref)]
42 fn add(self, rhs: BoxedMontyForm) -> BoxedMontyForm {
43 self + &rhs
44 }
45}
46
47impl Add<&BoxedMontyForm> for BoxedMontyForm {
48 type Output = BoxedMontyForm;
49 #[allow(clippy::op_ref)]
50 fn add(self, rhs: &BoxedMontyForm) -> BoxedMontyForm {
51 &self + rhs
52 }
53}
54
55impl Add<BoxedMontyForm> for BoxedMontyForm {
56 type Output = BoxedMontyForm;
57 fn add(self, rhs: BoxedMontyForm) -> BoxedMontyForm {
58 &self + &rhs
59 }
60}
61
62impl AddAssign<&BoxedMontyForm> for BoxedMontyForm {
63 fn add_assign(&mut self, rhs: &BoxedMontyForm) {
64 debug_assert_eq!(self.params, rhs.params);
65 self.montgomery_form
66 .add_mod_assign(&rhs.montgomery_form, self.params.modulus().as_nz_ref());
67 }
68}
69
70impl AddAssign<BoxedMontyForm> for BoxedMontyForm {
71 fn add_assign(&mut self, rhs: BoxedMontyForm) {
72 *self += &rhs;
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use crate::{
79 BoxedUint,
80 modular::{BoxedMontyForm, BoxedMontyParams},
81 };
82 use hex_literal::hex;
83
84 #[test]
85 fn add_overflow() {
86 let modulus = BoxedUint::from_be_slice(
87 &hex!("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"),
88 256,
89 )
90 .unwrap();
91 let params = BoxedMontyParams::new(modulus.to_odd().unwrap());
92
93 let x = BoxedUint::from_be_slice(
94 &hex!("44acf6b7e36c1342c2c5897204fe09504e1e2efb1a900377dbc4e7a6a133ec56"),
95 256,
96 )
97 .unwrap();
98 let mut x_mod = BoxedMontyForm::new(x, ¶ms);
99
100 let y = BoxedUint::from_be_slice(
101 &hex!("d5777c45019673125ad240f83094d4252d829516fac8601ed01979ec1ec1a251"),
102 256,
103 )
104 .unwrap();
105 let y_mod = BoxedMontyForm::new(y, ¶ms);
106
107 x_mod += &y_mod;
108
109 let expected = BoxedUint::from_be_slice(
110 &hex!("1a2472fde50286541d97ca6a3592dd75beb9c9646e40c511b82496cfc3926956"),
111 256,
112 )
113 .unwrap();
114
115 assert_eq!(expected, x_mod.retrieve());
116 }
117}