crypto_bigint/uint/
bit_and.rs1use super::Uint;
4use crate::{BitAnd, BitAndAssign, CtOption, Limb, Wrapping};
5
6impl<const LIMBS: usize> Uint<LIMBS> {
7 #[inline(always)]
9 #[must_use]
10 pub const fn bitand(&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].bitand(rhs.limbs[i]);
16 i += 1;
17 }
18
19 Self { limbs }
20 }
21
22 #[must_use]
25 pub const fn bitand_limb(&self, rhs: Limb) -> Self {
26 let mut limbs = [Limb::ZERO; LIMBS];
27 let mut i = 0;
28
29 while i < LIMBS {
30 limbs[i] = self.limbs[i].bitand(rhs);
31 i += 1;
32 }
33
34 Self { limbs }
35 }
36
37 #[must_use]
42 pub const fn wrapping_and(&self, rhs: &Self) -> Self {
43 self.bitand(rhs)
44 }
45
46 #[must_use]
48 pub const fn checked_and(&self, rhs: &Self) -> CtOption<Self> {
49 CtOption::some(self.bitand(rhs))
50 }
51}
52
53impl<const LIMBS: usize> BitAnd for Uint<LIMBS> {
54 type Output = Self;
55
56 fn bitand(self, rhs: Self) -> Uint<LIMBS> {
57 self.bitand(&rhs)
58 }
59}
60
61impl<const LIMBS: usize> BitAnd<&Uint<LIMBS>> for Uint<LIMBS> {
62 type Output = Uint<LIMBS>;
63
64 #[allow(clippy::needless_borrow)]
65 fn bitand(self, rhs: &Uint<LIMBS>) -> Uint<LIMBS> {
66 (&self).bitand(rhs)
67 }
68}
69
70impl<const LIMBS: usize> BitAnd<Uint<LIMBS>> for &Uint<LIMBS> {
71 type Output = Uint<LIMBS>;
72
73 fn bitand(self, rhs: Uint<LIMBS>) -> Uint<LIMBS> {
74 self.bitand(&rhs)
75 }
76}
77
78impl<const LIMBS: usize> BitAnd<&Uint<LIMBS>> for &Uint<LIMBS> {
79 type Output = Uint<LIMBS>;
80
81 fn bitand(self, rhs: &Uint<LIMBS>) -> Uint<LIMBS> {
82 self.bitand(rhs)
83 }
84}
85
86impl<const LIMBS: usize> BitAndAssign for Uint<LIMBS> {
87 #[allow(clippy::assign_op_pattern)]
88 fn bitand_assign(&mut self, other: Self) {
89 *self = *self & other;
90 }
91}
92
93impl<const LIMBS: usize> BitAndAssign<&Uint<LIMBS>> for Uint<LIMBS> {
94 #[allow(clippy::assign_op_pattern)]
95 fn bitand_assign(&mut self, other: &Self) {
96 *self = *self & other;
97 }
98}
99
100impl<const LIMBS: usize> BitAnd for Wrapping<Uint<LIMBS>> {
101 type Output = Self;
102
103 fn bitand(self, rhs: Self) -> Wrapping<Uint<LIMBS>> {
104 Wrapping(self.0.bitand(&rhs.0))
105 }
106}
107
108impl<const LIMBS: usize> BitAnd<&Wrapping<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
109 type Output = Wrapping<Uint<LIMBS>>;
110
111 fn bitand(self, rhs: &Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
112 Wrapping(self.0.bitand(&rhs.0))
113 }
114}
115
116impl<const LIMBS: usize> BitAnd<Wrapping<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
117 type Output = Wrapping<Uint<LIMBS>>;
118
119 fn bitand(self, rhs: Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
120 Wrapping(self.0.bitand(&rhs.0))
121 }
122}
123
124impl<const LIMBS: usize> BitAnd<&Wrapping<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
125 type Output = Wrapping<Uint<LIMBS>>;
126
127 fn bitand(self, rhs: &Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
128 Wrapping(self.0.bitand(&rhs.0))
129 }
130}
131
132impl<const LIMBS: usize> BitAndAssign for Wrapping<Uint<LIMBS>> {
133 #[allow(clippy::assign_op_pattern)]
134 fn bitand_assign(&mut self, other: Self) {
135 *self = *self & other;
136 }
137}
138
139impl<const LIMBS: usize> BitAndAssign<&Wrapping<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
140 #[allow(clippy::assign_op_pattern)]
141 fn bitand_assign(&mut self, other: &Self) {
142 *self = *self & other;
143 }
144}
145
146#[cfg(test)]
147mod tests {
148 use crate::U128;
149
150 #[test]
151 fn checked_and_ok() {
152 let result = U128::ZERO.checked_and(&U128::ONE);
153 assert_eq!(result.unwrap(), U128::ZERO);
154 }
155
156 #[test]
157 fn overlapping_and_ok() {
158 let result = U128::MAX.wrapping_and(&U128::ONE);
159 assert_eq!(result, U128::ONE);
160 }
161}