crypto_bigint/modular/monty_form/
add.rs1use super::MontyForm;
4use crate::modular::add::{add_montgomery_form, double_montgomery_form};
5use core::ops::{Add, AddAssign};
6
7impl<const LIMBS: usize> MontyForm<LIMBS> {
8 pub const fn add(&self, rhs: &Self) -> Self {
10 Self {
11 montgomery_form: add_montgomery_form(
12 &self.montgomery_form,
13 &rhs.montgomery_form,
14 &self.params.modulus,
15 ),
16 params: self.params,
17 }
18 }
19
20 pub const fn double(&self) -> Self {
22 Self {
23 montgomery_form: double_montgomery_form(&self.montgomery_form, &self.params.modulus),
24 params: self.params,
25 }
26 }
27}
28
29impl<const LIMBS: usize> Add<&MontyForm<LIMBS>> for &MontyForm<LIMBS> {
30 type Output = MontyForm<LIMBS>;
31 fn add(self, rhs: &MontyForm<LIMBS>) -> MontyForm<LIMBS> {
32 debug_assert_eq!(self.params, rhs.params);
33 self.add(rhs)
34 }
35}
36
37impl<const LIMBS: usize> Add<MontyForm<LIMBS>> for &MontyForm<LIMBS> {
38 type Output = MontyForm<LIMBS>;
39 #[allow(clippy::op_ref)]
40 fn add(self, rhs: MontyForm<LIMBS>) -> MontyForm<LIMBS> {
41 self + &rhs
42 }
43}
44
45impl<const LIMBS: usize> Add<&MontyForm<LIMBS>> for MontyForm<LIMBS> {
46 type Output = MontyForm<LIMBS>;
47 #[allow(clippy::op_ref)]
48 fn add(self, rhs: &MontyForm<LIMBS>) -> MontyForm<LIMBS> {
49 &self + rhs
50 }
51}
52
53impl<const LIMBS: usize> Add<MontyForm<LIMBS>> for MontyForm<LIMBS> {
54 type Output = MontyForm<LIMBS>;
55 fn add(self, rhs: MontyForm<LIMBS>) -> MontyForm<LIMBS> {
56 &self + &rhs
57 }
58}
59
60impl<const LIMBS: usize> AddAssign<&MontyForm<LIMBS>> for MontyForm<LIMBS> {
61 fn add_assign(&mut self, rhs: &MontyForm<LIMBS>) {
62 *self = *self + rhs;
63 }
64}
65
66impl<const LIMBS: usize> AddAssign<MontyForm<LIMBS>> for MontyForm<LIMBS> {
67 fn add_assign(&mut self, rhs: MontyForm<LIMBS>) {
68 *self += &rhs;
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use crate::{
75 modular::{MontyForm, MontyParams},
76 Odd, U256,
77 };
78
79 #[test]
80 fn add_overflow() {
81 let params = MontyParams::new_vartime(Odd::<U256>::from_be_hex(
82 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
83 ));
84
85 let x =
86 U256::from_be_hex("44acf6b7e36c1342c2c5897204fe09504e1e2efb1a900377dbc4e7a6a133ec56");
87 let mut x_mod = MontyForm::new(&x, params);
88
89 let y =
90 U256::from_be_hex("d5777c45019673125ad240f83094d4252d829516fac8601ed01979ec1ec1a251");
91 let y_mod = MontyForm::new(&y, params);
92
93 x_mod += &y_mod;
94
95 let expected =
96 U256::from_be_hex("1a2472fde50286541d97ca6a3592dd75beb9c9646e40c511b82496cfc3926956");
97
98 assert_eq!(expected, x_mod.retrieve());
99 }
100}