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