crypto_bigint/uint/boxed/
bit_and.rs1use super::BoxedUint;
4use crate::{Limb, Wrapping};
5use core::ops::{BitAnd, BitAndAssign};
6use subtle::{Choice, CtOption};
7
8impl BoxedUint {
9 #[inline(always)]
11 pub fn bitand(&self, rhs: &Self) -> Self {
12 Self::map_limbs(self, rhs, |a, b| a.bitand(b))
13 }
14
15 pub fn bitand_limb(&self, rhs: Limb) -> Self {
18 Self {
19 limbs: self.limbs.iter().map(|limb| limb.bitand(rhs)).collect(),
20 }
21 }
22
23 pub fn wrapping_and(&self, rhs: &Self) -> Self {
28 self.bitand(rhs)
29 }
30
31 pub fn checked_and(&self, rhs: &Self) -> CtOption<Self> {
33 let result = self.bitand(rhs);
34 CtOption::new(result, Choice::from(1))
35 }
36}
37
38impl BitAnd for BoxedUint {
39 type Output = Self;
40
41 fn bitand(self, rhs: Self) -> BoxedUint {
42 self.bitand(&rhs)
43 }
44}
45
46impl BitAnd<&BoxedUint> for BoxedUint {
47 type Output = BoxedUint;
48
49 #[allow(clippy::needless_borrow)]
50 fn bitand(self, rhs: &BoxedUint) -> BoxedUint {
51 (&self).bitand(rhs)
52 }
53}
54
55impl BitAnd<BoxedUint> for &BoxedUint {
56 type Output = BoxedUint;
57
58 fn bitand(self, rhs: BoxedUint) -> BoxedUint {
59 self.bitand(&rhs)
60 }
61}
62
63impl BitAnd<&BoxedUint> for &BoxedUint {
64 type Output = BoxedUint;
65
66 fn bitand(self, rhs: &BoxedUint) -> BoxedUint {
67 self.bitand(rhs)
68 }
69}
70
71impl BitAndAssign for BoxedUint {
72 #[allow(clippy::assign_op_pattern)]
73 fn bitand_assign(&mut self, other: Self) {
74 *self = BoxedUint::bitand(self, &other);
75 }
76}
77
78impl BitAndAssign<&BoxedUint> for BoxedUint {
79 #[allow(clippy::assign_op_pattern)]
80 fn bitand_assign(&mut self, other: &Self) {
81 *self = BoxedUint::bitand(self, other);
82 }
83}
84
85impl BitAnd for Wrapping<BoxedUint> {
86 type Output = Self;
87
88 fn bitand(self, rhs: Self) -> Wrapping<BoxedUint> {
89 Wrapping(self.0.bitand(&rhs.0))
90 }
91}
92
93impl BitAnd<&Wrapping<BoxedUint>> for Wrapping<BoxedUint> {
94 type Output = Wrapping<BoxedUint>;
95
96 fn bitand(self, rhs: &Wrapping<BoxedUint>) -> Wrapping<BoxedUint> {
97 Wrapping(self.0.bitand(&rhs.0))
98 }
99}
100
101impl BitAnd<Wrapping<BoxedUint>> for &Wrapping<BoxedUint> {
102 type Output = Wrapping<BoxedUint>;
103
104 fn bitand(self, rhs: Wrapping<BoxedUint>) -> Wrapping<BoxedUint> {
105 Wrapping(BoxedUint::bitand(&self.0, &rhs.0))
106 }
107}
108
109impl BitAnd<&Wrapping<BoxedUint>> for &Wrapping<BoxedUint> {
110 type Output = Wrapping<BoxedUint>;
111
112 fn bitand(self, rhs: &Wrapping<BoxedUint>) -> Wrapping<BoxedUint> {
113 Wrapping(BoxedUint::bitand(&self.0, &rhs.0))
114 }
115}
116
117impl BitAndAssign for Wrapping<BoxedUint> {
118 #[allow(clippy::assign_op_pattern)]
119 fn bitand_assign(&mut self, other: Self) {
120 *self = Wrapping(BoxedUint::bitand(&self.0, &other.0))
121 }
122}
123
124impl BitAndAssign<&Wrapping<BoxedUint>> for Wrapping<BoxedUint> {
125 #[allow(clippy::assign_op_pattern)]
126 fn bitand_assign(&mut self, other: &Self) {
127 *self = Wrapping(BoxedUint::bitand(&self.0, &other.0))
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use crate::BoxedUint;
134
135 #[test]
136 fn checked_and_ok() {
137 let result = BoxedUint::zero().checked_and(&BoxedUint::one());
138 assert_eq!(result.unwrap(), BoxedUint::zero());
139 }
140
141 #[test]
142 fn overlapping_and_ok() {
143 let result = BoxedUint::max(128).wrapping_and(&BoxedUint::one());
144 assert_eq!(result, BoxedUint::one());
145 }
146}