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