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