crypto_bigint/uint/boxed/
add_mod.rs1use crate::{AddMod, BoxedUint, Limb, Zero};
4
5impl BoxedUint {
6 pub fn add_mod(&self, rhs: &Self, p: &Self) -> Self {
10 debug_assert_eq!(self.bits_precision(), p.bits_precision());
11 debug_assert_eq!(rhs.bits_precision(), p.bits_precision());
12 debug_assert!(self < p);
13 debug_assert!(rhs < p);
14
15 let (mut w, carry) = self.adc(rhs, Limb::ZERO);
16
17 let borrow = w.sbb_assign(p, Limb::ZERO);
19 let (_, borrow) = carry.sbb(Limb::ZERO, borrow);
20
21 w.conditional_adc_assign(p, !borrow.is_zero());
25 w
26 }
27
28 pub fn double_mod(&self, p: &Self) -> Self {
32 let (mut w, carry) = self.overflowing_shl1();
33
34 let borrow = w.sbb_assign(p, Limb::ZERO);
36 let (_, borrow) = carry.sbb(Limb::ZERO, borrow);
37
38 w.conditional_adc_assign(p, !borrow.is_zero());
42 w
43 }
44}
45
46impl AddMod for BoxedUint {
47 type Output = Self;
48
49 fn add_mod(&self, rhs: &Self, p: &Self) -> Self {
50 self.add_mod(rhs, p)
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::BoxedUint;
57 use hex_literal::hex;
58
59 #[test]
62 fn add_mod_nist_p256() {
63 let a = BoxedUint::from_be_slice(
64 &hex!("44acf6b7e36c1342c2c5897204fe09504e1e2efb1a900377dbc4e7a6a133ec56"),
65 256,
66 )
67 .unwrap();
68 let b = BoxedUint::from_be_slice(
69 &hex!("d5777c45019673125ad240f83094d4252d829516fac8601ed01979ec1ec1a251"),
70 256,
71 )
72 .unwrap();
73 let n = BoxedUint::from_be_slice(
74 &hex!("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"),
75 256,
76 )
77 .unwrap();
78
79 let actual = a.add_mod(&b, &n);
80 let expected = BoxedUint::from_be_slice(
81 &hex!("1a2472fde50286541d97ca6a3592dd75beb9c9646e40c511b82496cfc3926956"),
82 256,
83 )
84 .unwrap();
85
86 assert_eq!(expected, actual);
87 }
88
89 #[test]
90 fn double_mod_expected() {
91 let a = BoxedUint::from_be_hex(
92 "44acf6b7e36c1342c2c5897204fe09504e1e2efb1a900377dbc4e7a6a133ec56",
93 256,
94 )
95 .unwrap();
96 let n = BoxedUint::from_be_hex(
97 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
98 256,
99 )
100 .unwrap();
101
102 assert_eq!(a.add_mod(&a, &n), a.double_mod(&n));
103 }
104}