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