crypto_bigint/uint/boxed/
neg_mod.rs1use crate::{BoxedUint, CtAssign, Limb, NegMod, NonZero};
4
5impl BoxedUint {
6 #[must_use]
9 pub fn neg_mod(&self, p: &NonZero<Self>) -> Self {
10 debug_assert_eq!(self.bits_precision(), p.bits_precision());
11 let is_zero = self.is_zero();
12 let mut ret = p.borrowing_sub(self, Limb::ZERO).0;
13
14 for i in 0..self.nlimbs() {
15 ret.limbs[i].ct_assign(&Limb::ZERO, is_zero);
18 }
19
20 ret
21 }
22
23 #[must_use]
26 pub fn neg_mod_special(&self, c: Limb) -> Self {
27 Self::zero_with_precision(self.bits_precision()).sub_mod_special(self, c)
28 }
29}
30
31impl NegMod for BoxedUint {
32 type Output = Self;
33
34 fn neg_mod(&self, p: &NonZero<Self>) -> Self {
35 debug_assert!(self < p.as_ref());
36 self.neg_mod(p)
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use crate::BoxedUint;
43 use hex_literal::hex;
44
45 #[test]
46 fn neg_mod_random() {
47 let x = BoxedUint::from_be_slice(
48 &hex!("8d16e171674b4e6d8529edba4593802bf30b8cb161dd30aa8e550d41380007c2"),
49 256,
50 )
51 .unwrap();
52 let p = BoxedUint::from_be_slice(
53 &hex!("928334a4e4be0843ec225a4c9c61df34bdc7a81513e4b6f76f2bfa3148e2e1b5"),
54 256,
55 )
56 .unwrap()
57 .to_nz()
58 .unwrap();
59
60 let actual = x.neg_mod(&p);
61 let expected = BoxedUint::from_be_slice(
62 &hex!("056c53337d72b9d666f86c9256ce5f08cabc1b63b207864ce0d6ecf010e2d9f3"),
63 256,
64 )
65 .unwrap();
66
67 assert_eq!(expected, actual);
68 }
69
70 #[test]
71 fn neg_mod_zero() {
72 let x = BoxedUint::from_be_slice(
73 &hex!("0000000000000000000000000000000000000000000000000000000000000000"),
74 256,
75 )
76 .unwrap();
77 let p = BoxedUint::from_be_slice(
78 &hex!("928334a4e4be0843ec225a4c9c61df34bdc7a81513e4b6f76f2bfa3148e2e1b5"),
79 256,
80 )
81 .unwrap()
82 .to_nz()
83 .unwrap();
84
85 let actual = x.neg_mod(&p);
86 let expected = BoxedUint::from_be_slice(
87 &hex!("0000000000000000000000000000000000000000000000000000000000000000"),
88 256,
89 )
90 .unwrap();
91
92 assert_eq!(expected, actual);
93 }
94}