crypto_bigint/int/
bit_xor.rs

1//! [`Int`] bitwise XOR operations.
2
3use core::ops::{BitXor, BitXorAssign};
4
5use crate::{ConstCtOption, Uint, Wrapping};
6
7use super::Int;
8
9impl<const LIMBS: usize> Int<LIMBS> {
10    /// Computes bitwise `a ^ b`.
11    #[inline(always)]
12    pub const fn bitxor(&self, rhs: &Self) -> Self {
13        Self(Uint::bitxor(&self.0, &rhs.0))
14    }
15
16    /// Perform wrapping bitwise `XOR`.
17    ///
18    /// There's no way wrapping could ever happen.
19    /// This function exists so that all operations are accounted for in the wrapping operations
20    pub const fn wrapping_xor(&self, rhs: &Self) -> Self {
21        self.bitxor(rhs)
22    }
23
24    /// Perform checked bitwise `XOR`, returning a [`ConstCtOption`] which `is_some` always
25    pub fn checked_xor(&self, rhs: &Self) -> ConstCtOption<Self> {
26        ConstCtOption::some(self.bitxor(rhs))
27    }
28}
29
30impl<const LIMBS: usize> BitXor for Int<LIMBS> {
31    type Output = Self;
32
33    fn bitxor(self, rhs: Self) -> Int<LIMBS> {
34        self.bitxor(&rhs)
35    }
36}
37
38impl<const LIMBS: usize> BitXor<&Int<LIMBS>> for Int<LIMBS> {
39    type Output = Int<LIMBS>;
40
41    #[allow(clippy::needless_borrow)]
42    fn bitxor(self, rhs: &Int<LIMBS>) -> Int<LIMBS> {
43        (&self).bitxor(rhs)
44    }
45}
46
47impl<const LIMBS: usize> BitXor<Int<LIMBS>> for &Int<LIMBS> {
48    type Output = Int<LIMBS>;
49
50    fn bitxor(self, rhs: Int<LIMBS>) -> Int<LIMBS> {
51        self.bitxor(&rhs)
52    }
53}
54
55impl<const LIMBS: usize> BitXor<&Int<LIMBS>> for &Int<LIMBS> {
56    type Output = Int<LIMBS>;
57
58    fn bitxor(self, rhs: &Int<LIMBS>) -> Int<LIMBS> {
59        self.bitxor(rhs)
60    }
61}
62
63impl<const LIMBS: usize> BitXorAssign for Int<LIMBS> {
64    fn bitxor_assign(&mut self, other: Self) {
65        *self = *self ^ other;
66    }
67}
68
69impl<const LIMBS: usize> BitXorAssign<&Int<LIMBS>> for Int<LIMBS> {
70    fn bitxor_assign(&mut self, other: &Self) {
71        *self = *self ^ other;
72    }
73}
74
75impl<const LIMBS: usize> BitXor for Wrapping<Int<LIMBS>> {
76    type Output = Self;
77
78    fn bitxor(self, rhs: Self) -> Wrapping<Int<LIMBS>> {
79        Wrapping(self.0.bitxor(&rhs.0))
80    }
81}
82
83impl<const LIMBS: usize> BitXor<&Wrapping<Int<LIMBS>>> for Wrapping<Int<LIMBS>> {
84    type Output = Wrapping<Int<LIMBS>>;
85
86    fn bitxor(self, rhs: &Wrapping<Int<LIMBS>>) -> Wrapping<Int<LIMBS>> {
87        Wrapping(self.0.bitxor(&rhs.0))
88    }
89}
90
91impl<const LIMBS: usize> BitXor<Wrapping<Int<LIMBS>>> for &Wrapping<Int<LIMBS>> {
92    type Output = Wrapping<Int<LIMBS>>;
93
94    fn bitxor(self, rhs: Wrapping<Int<LIMBS>>) -> Wrapping<Int<LIMBS>> {
95        Wrapping(self.0.bitxor(&rhs.0))
96    }
97}
98
99impl<const LIMBS: usize> BitXor<&Wrapping<Int<LIMBS>>> for &Wrapping<Int<LIMBS>> {
100    type Output = Wrapping<Int<LIMBS>>;
101
102    fn bitxor(self, rhs: &Wrapping<Int<LIMBS>>) -> Wrapping<Int<LIMBS>> {
103        Wrapping(self.0.bitxor(&rhs.0))
104    }
105}
106
107impl<const LIMBS: usize> BitXorAssign for Wrapping<Int<LIMBS>> {
108    fn bitxor_assign(&mut self, other: Self) {
109        *self = *self ^ other;
110    }
111}
112
113impl<const LIMBS: usize> BitXorAssign<&Wrapping<Int<LIMBS>>> for Wrapping<Int<LIMBS>> {
114    fn bitxor_assign(&mut self, other: &Self) {
115        *self = *self ^ other;
116    }
117}
118
119#[cfg(test)]
120mod tests {
121    use crate::I128;
122
123    #[test]
124    fn checked_xor_ok() {
125        assert_eq!(I128::ZERO.checked_xor(&I128::ONE).unwrap(), I128::ONE);
126        assert_eq!(I128::ONE.checked_xor(&I128::ONE).unwrap(), I128::ZERO);
127        assert_eq!(
128            I128::MAX.checked_xor(&I128::ONE).unwrap(),
129            I128::MAX - I128::ONE
130        );
131    }
132
133    #[test]
134    fn wrapping_xor_ok() {
135        assert_eq!(I128::ZERO.wrapping_xor(&I128::ONE), I128::ONE);
136        assert_eq!(I128::ONE.wrapping_xor(&I128::ONE), I128::ZERO);
137        assert_eq!(I128::MAX.wrapping_xor(&I128::ONE), I128::MAX - I128::ONE);
138    }
139}