crypto_bigint/boxed/uint/
add.rs1use crate::{BoxedUint, CheckedAdd, Limb, Zero};
4use subtle::CtOption;
5
6impl BoxedUint {
7 #[inline(always)]
9 pub fn adc(&self, rhs: &Self, carry: Limb) -> (Self, Limb) {
10 Self::chain(self, rhs, carry, |a, b, c| a.adc(b, c))
11 }
12
13 pub fn wrapping_add(&self, rhs: &Self) -> Self {
15 self.adc(rhs, Limb::ZERO).0
16 }
17}
18
19impl CheckedAdd<&BoxedUint> for BoxedUint {
20 type Output = Self;
21
22 fn checked_add(&self, rhs: &Self) -> CtOption<Self> {
23 let (result, carry) = self.adc(rhs, Limb::ZERO);
24 CtOption::new(result, carry.is_zero())
25 }
26}
27
28#[cfg(test)]
29#[allow(clippy::unwrap_used)]
30mod tests {
31 use super::{BoxedUint, CheckedAdd, Limb};
32
33 #[test]
34 fn adc_no_carry() {
35 let (res, carry) = BoxedUint::zero().adc(&BoxedUint::one(), Limb::ZERO);
36 assert_eq!(res, BoxedUint::one());
37 assert_eq!(carry, Limb::ZERO);
38 }
39
40 #[test]
41 fn adc_with_carry() {
42 let (res, carry) = BoxedUint::max(Limb::BITS)
43 .unwrap()
44 .adc(&BoxedUint::one(), Limb::ZERO);
45 assert_eq!(res, BoxedUint::zero());
46 assert_eq!(carry, Limb::ONE);
47 }
48
49 #[test]
50 fn checked_add_ok() {
51 let result = BoxedUint::zero().checked_add(&BoxedUint::one());
52 assert_eq!(result.unwrap(), BoxedUint::one());
53 }
54
55 #[test]
56 fn checked_add_overflow() {
57 let result = BoxedUint::max(Limb::BITS)
58 .unwrap()
59 .checked_add(&BoxedUint::one());
60 assert!(!bool::from(result.is_some()));
61 }
62}