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