crypto_bigint/uint/
bit_xor.rs1use super::Uint;
4use crate::{BitXor, BitXorAssign, CtOption, Limb};
5
6impl<const LIMBS: usize> Uint<LIMBS> {
7 #[inline(always)]
9 #[must_use]
10 pub const fn bitxor(&self, rhs: &Self) -> Self {
11 let mut limbs = [Limb::ZERO; LIMBS];
12 let mut i = 0;
13
14 while i < LIMBS {
15 limbs[i] = self.limbs[i].bitxor(rhs.limbs[i]);
16 i += 1;
17 }
18
19 Self { limbs }
20 }
21
22 #[must_use]
27 pub const fn wrapping_xor(&self, rhs: &Self) -> Self {
28 self.bitxor(rhs)
29 }
30
31 #[must_use]
33 pub const fn checked_xor(&self, rhs: &Self) -> CtOption<Self> {
34 CtOption::some(self.bitxor(rhs))
35 }
36}
37
38impl<const LIMBS: usize> BitXor for Uint<LIMBS> {
39 type Output = Self;
40
41 fn bitxor(self, rhs: Self) -> Uint<LIMBS> {
42 self.bitxor(&rhs)
43 }
44}
45
46impl<const LIMBS: usize> BitXor<&Uint<LIMBS>> for Uint<LIMBS> {
47 type Output = Uint<LIMBS>;
48
49 #[allow(clippy::needless_borrow)]
50 fn bitxor(self, rhs: &Uint<LIMBS>) -> Uint<LIMBS> {
51 (&self).bitxor(rhs)
52 }
53}
54
55impl<const LIMBS: usize> BitXor<Uint<LIMBS>> for &Uint<LIMBS> {
56 type Output = Uint<LIMBS>;
57
58 fn bitxor(self, rhs: Uint<LIMBS>) -> Uint<LIMBS> {
59 self.bitxor(&rhs)
60 }
61}
62
63impl<const LIMBS: usize> BitXor<&Uint<LIMBS>> for &Uint<LIMBS> {
64 type Output = Uint<LIMBS>;
65
66 fn bitxor(self, rhs: &Uint<LIMBS>) -> Uint<LIMBS> {
67 self.bitxor(rhs)
68 }
69}
70
71impl<const LIMBS: usize> BitXorAssign for Uint<LIMBS> {
72 fn bitxor_assign(&mut self, other: Self) {
73 *self = *self ^ other;
74 }
75}
76
77impl<const LIMBS: usize> BitXorAssign<&Uint<LIMBS>> for Uint<LIMBS> {
78 fn bitxor_assign(&mut self, other: &Self) {
79 *self = *self ^ other;
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use crate::U128;
86
87 #[test]
88 fn checked_xor_ok() {
89 let result = U128::ZERO.checked_xor(&U128::ONE);
90 assert_eq!(result.unwrap(), U128::ONE);
91 }
92
93 #[test]
94 fn overlapping_xor_ok() {
95 let result = U128::ZERO.wrapping_xor(&U128::ONE);
96 assert_eq!(result, U128::ONE);
97 }
98}