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