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