crypto_bigint/uint/
neg.rs1use core::ops::Neg;
2
3use crate::{CtChoice, Limb, Uint, WideWord, Word, Wrapping};
4
5impl<const LIMBS: usize> Neg for Wrapping<Uint<LIMBS>> {
6 type Output = Self;
7
8 fn neg(self) -> Self::Output {
9 Self(self.0.wrapping_neg())
10 }
11}
12
13impl<const LIMBS: usize> Uint<LIMBS> {
14 pub(crate) const fn conditional_wrapping_neg(&self, choice: CtChoice) -> Uint<LIMBS> {
16 Uint::ct_select(self, &self.wrapping_neg(), choice)
17 }
18
19 pub const fn wrapping_neg(&self) -> Self {
21 let mut ret = [Limb::ZERO; LIMBS];
22 let mut carry = 1;
23 let mut i = 0;
24 while i < LIMBS {
25 let r = (!self.limbs[i].0 as WideWord) + carry;
26 ret[i] = Limb(r as Word);
27 carry = r >> Limb::BITS;
28 i += 1;
29 }
30 Uint::new(ret)
31 }
32}
33
34#[cfg(test)]
35mod tests {
36 use crate::U256;
37
38 #[test]
39 fn wrapping_neg() {
40 assert_eq!(U256::ZERO.wrapping_neg(), U256::ZERO);
41 assert_eq!(U256::MAX.wrapping_neg(), U256::ONE);
42 assert_eq!(
43 U256::from_u64(13).wrapping_neg(),
44 U256::from_u64(13).not().saturating_add(&U256::ONE)
45 );
46 assert_eq!(
47 U256::from_u64(42).wrapping_neg(),
48 U256::from_u64(42).saturating_sub(&U256::ONE).not()
49 );
50 }
51}