crypto_bigint/uint/
neg.rs1use crate::{ConstChoice, Limb, Uint, WideWord, Word, WrappingNeg};
2
3impl<const LIMBS: usize> Uint<LIMBS> {
4 pub const fn wrapping_neg(&self) -> Self {
6 self.carrying_neg().0
7 }
8
9 pub const fn carrying_neg(&self) -> (Self, ConstChoice) {
14 let mut ret = [Limb::ZERO; LIMBS];
15 let mut carry = 1;
16 let mut i = 0;
17 while i < LIMBS {
18 let r = (!self.limbs[i].0 as WideWord) + carry;
19 ret[i] = Limb(r as Word);
20 carry = r >> Limb::BITS;
21 i += 1;
22 }
23 (Uint::new(ret), ConstChoice::from_word_lsb(carry as Word))
24 }
25
26 pub const fn wrapping_neg_if(&self, negate: ConstChoice) -> Self {
28 Uint::select(self, &self.wrapping_neg(), negate)
29 }
30}
31
32impl<const LIMBS: usize> WrappingNeg for Uint<LIMBS> {
33 #[inline]
34 fn wrapping_neg(&self) -> Self {
35 self.wrapping_neg()
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use crate::{ConstChoice, U256};
42
43 #[test]
44 fn wrapping_neg() {
45 assert_eq!(U256::ZERO.wrapping_neg(), U256::ZERO);
46 assert_eq!(U256::MAX.wrapping_neg(), U256::ONE);
47 assert_eq!(
48 U256::from_u64(13).wrapping_neg(),
49 U256::from_u64(13).not().saturating_add(&U256::ONE)
50 );
51 assert_eq!(
52 U256::from_u64(42).wrapping_neg(),
53 U256::from_u64(42).saturating_sub(&U256::ONE).not()
54 );
55 }
56
57 #[test]
58 fn carrying_neg() {
59 assert_eq!(U256::ZERO.carrying_neg(), (U256::ZERO, ConstChoice::TRUE));
60 assert_eq!(U256::ONE.carrying_neg(), (U256::MAX, ConstChoice::FALSE));
61 assert_eq!(U256::MAX.carrying_neg(), (U256::ONE, ConstChoice::FALSE));
62 }
63
64 #[test]
65 fn wrapping_neg_if() {
66 let negate = ConstChoice::TRUE;
67 assert_eq!(U256::ZERO.wrapping_neg_if(negate), U256::ZERO);
68 assert_eq!(U256::ONE.wrapping_neg_if(negate), U256::MAX);
69 assert_eq!(U256::MAX.wrapping_neg_if(negate), U256::ONE);
70
71 let do_not_negate = ConstChoice::FALSE;
72 assert_eq!(U256::ZERO.wrapping_neg_if(do_not_negate), U256::ZERO);
73 assert_eq!(U256::ONE.wrapping_neg_if(do_not_negate), U256::ONE);
74 assert_eq!(U256::MAX.wrapping_neg_if(do_not_negate), U256::MAX);
75 }
76}