1use super::*;
17
18impl<E: Environment> BitAnd<Boolean<E>> for Boolean<E> {
19 type Output = Boolean<E>;
20
21 fn bitand(self, other: Boolean<E>) -> Self::Output {
23 self & &other
24 }
25}
26
27impl<E: Environment> BitAnd<Boolean<E>> for &Boolean<E> {
28 type Output = Boolean<E>;
29
30 fn bitand(self, other: Boolean<E>) -> Self::Output {
32 self & &other
33 }
34}
35
36impl<E: Environment> BitAnd<&Boolean<E>> for Boolean<E> {
37 type Output = Boolean<E>;
38
39 fn bitand(self, other: &Boolean<E>) -> Self::Output {
41 &self & other
42 }
43}
44
45impl<E: Environment> BitAnd<&Boolean<E>> for &Boolean<E> {
46 type Output = Boolean<E>;
47
48 fn bitand(self, other: &Boolean<E>) -> Self::Output {
50 let mut output = self.clone();
51 output &= other;
52 output
53 }
54}
55
56impl<E: Environment> BitAndAssign<Boolean<E>> for Boolean<E> {
57 fn bitand_assign(&mut self, other: Boolean<E>) {
59 *self &= &other;
60 }
61}
62
63impl<E: Environment> BitAndAssign<&Boolean<E>> for Boolean<E> {
64 fn bitand_assign(&mut self, other: &Boolean<E>) {
66 *self =
68 if self.is_constant() {
70 match self.eject_value() {
71 true => other.clone(),
72 false => self.clone(),
73 }
74 }
75 else if other.is_constant() {
77 match other.eject_value() {
78 true => self.clone(),
79 false => other.clone(),
80 }
81 }
82 else {
84 let output = Boolean(
88 E::new_variable(Mode::Private, match self.eject_value() & other.eject_value() {
89 true => E::BaseField::one(),
90 false => E::BaseField::zero(),
91 })
92 .into(),
93 );
94
95 E::enforce(|| (&*self, other, &output));
98
99 output
100 }
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107 use snarkvm_circuit_environment::Circuit;
108
109 fn check_and(
110 name: &str,
111 expected: bool,
112 a: Boolean<Circuit>,
113 b: Boolean<Circuit>,
114 num_constants: u64,
115 num_public: u64,
116 num_private: u64,
117 num_constraints: u64,
118 ) {
119 Circuit::scope(name, || {
120 let candidate = &a & &b;
121 assert_eq!(expected, candidate.eject_value(), "({} AND {})", a.eject_value(), b.eject_value());
122 assert_scope!(num_constants, num_public, num_private, num_constraints);
123 });
124 }
125
126 #[test]
127 fn test_constant_and_constant() {
128 let expected = false;
130 let a = Boolean::<Circuit>::new(Mode::Constant, false);
131 let b = Boolean::<Circuit>::new(Mode::Constant, false);
132 check_and("false AND false", expected, a, b, 0, 0, 0, 0);
133
134 let expected = false;
136 let a = Boolean::<Circuit>::new(Mode::Constant, false);
137 let b = Boolean::<Circuit>::new(Mode::Constant, true);
138 check_and("false AND true", expected, a, b, 0, 0, 0, 0);
139
140 let expected = false;
142 let a = Boolean::<Circuit>::new(Mode::Constant, true);
143 let b = Boolean::<Circuit>::new(Mode::Constant, false);
144 check_and("true AND false", expected, a, b, 0, 0, 0, 0);
145
146 let expected = true;
148 let a = Boolean::<Circuit>::new(Mode::Constant, true);
149 let b = Boolean::<Circuit>::new(Mode::Constant, true);
150 check_and("true AND true", expected, a, b, 0, 0, 0, 0);
151 }
152
153 #[test]
154 fn test_constant_and_public() {
155 let expected = false;
157 let a = Boolean::<Circuit>::new(Mode::Constant, false);
158 let b = Boolean::<Circuit>::new(Mode::Public, false);
159 check_and("false AND false", expected, a, b, 0, 0, 0, 0);
160
161 let expected = false;
163 let a = Boolean::<Circuit>::new(Mode::Constant, false);
164 let b = Boolean::<Circuit>::new(Mode::Public, true);
165 check_and("false AND true", expected, a, b, 0, 0, 0, 0);
166
167 let expected = false;
169 let a = Boolean::<Circuit>::new(Mode::Constant, true);
170 let b = Boolean::<Circuit>::new(Mode::Public, false);
171 check_and("true AND false", expected, a, b, 0, 0, 0, 0);
172
173 let expected = true;
175 let a = Boolean::<Circuit>::new(Mode::Constant, true);
176 let b = Boolean::<Circuit>::new(Mode::Public, true);
177 check_and("true AND true", expected, a, b, 0, 0, 0, 0);
178 }
179
180 #[test]
181 fn test_constant_and_private() {
182 let expected = false;
184 let a = Boolean::<Circuit>::new(Mode::Constant, false);
185 let b = Boolean::<Circuit>::new(Mode::Private, false);
186 check_and("false AND false", expected, a, b, 0, 0, 0, 0);
187
188 let expected = false;
190 let a = Boolean::<Circuit>::new(Mode::Constant, false);
191 let b = Boolean::<Circuit>::new(Mode::Private, true);
192 check_and("false AND true", expected, a, b, 0, 0, 0, 0);
193
194 let expected = false;
196 let a = Boolean::<Circuit>::new(Mode::Constant, true);
197 let b = Boolean::<Circuit>::new(Mode::Private, false);
198 check_and("true AND false", expected, a, b, 0, 0, 0, 0);
199
200 let expected = true;
202 let a = Boolean::<Circuit>::new(Mode::Constant, true);
203 let b = Boolean::<Circuit>::new(Mode::Private, true);
204 check_and("true AND true", expected, a, b, 0, 0, 0, 0);
205 }
206
207 #[test]
208 fn test_public_and_constant() {
209 let expected = false;
211 let a = Boolean::<Circuit>::new(Mode::Public, false);
212 let b = Boolean::<Circuit>::new(Mode::Constant, false);
213 check_and("false AND false", expected, a, b, 0, 0, 0, 0);
214
215 let expected = false;
217 let a = Boolean::<Circuit>::new(Mode::Public, false);
218 let b = Boolean::<Circuit>::new(Mode::Constant, true);
219 check_and("false AND true", expected, a, b, 0, 0, 0, 0);
220
221 let expected = false;
223 let a = Boolean::<Circuit>::new(Mode::Public, true);
224 let b = Boolean::<Circuit>::new(Mode::Constant, false);
225 check_and("true AND false", expected, a, b, 0, 0, 0, 0);
226
227 let expected = true;
229 let a = Boolean::<Circuit>::new(Mode::Public, true);
230 let b = Boolean::<Circuit>::new(Mode::Constant, true);
231 check_and("true AND true", expected, a, b, 0, 0, 0, 0);
232 }
233
234 #[test]
235 fn test_public_and_public() {
236 let expected = false;
238 let a = Boolean::<Circuit>::new(Mode::Public, false);
239 let b = Boolean::<Circuit>::new(Mode::Public, false);
240 check_and("false AND false", expected, a, b, 0, 0, 1, 1);
241
242 let expected = false;
244 let a = Boolean::<Circuit>::new(Mode::Public, false);
245 let b = Boolean::<Circuit>::new(Mode::Public, true);
246 check_and("false AND true", expected, a, b, 0, 0, 1, 1);
247
248 let expected = false;
250 let a = Boolean::<Circuit>::new(Mode::Public, true);
251 let b = Boolean::<Circuit>::new(Mode::Public, false);
252 check_and("true AND false", expected, a, b, 0, 0, 1, 1);
253
254 let expected = true;
256 let a = Boolean::<Circuit>::new(Mode::Public, true);
257 let b = Boolean::<Circuit>::new(Mode::Public, true);
258 check_and("true AND true", expected, a, b, 0, 0, 1, 1);
259 }
260
261 #[test]
262 fn test_public_and_private() {
263 let expected = false;
265 let a = Boolean::<Circuit>::new(Mode::Public, false);
266 let b = Boolean::<Circuit>::new(Mode::Private, false);
267 check_and("false AND false", expected, a, b, 0, 0, 1, 1);
268
269 let expected = false;
271 let a = Boolean::<Circuit>::new(Mode::Public, false);
272 let b = Boolean::<Circuit>::new(Mode::Private, true);
273 check_and("false AND true", expected, a, b, 0, 0, 1, 1);
274
275 let expected = false;
277 let a = Boolean::<Circuit>::new(Mode::Public, true);
278 let b = Boolean::<Circuit>::new(Mode::Private, false);
279 check_and("true AND false", expected, a, b, 0, 0, 1, 1);
280
281 let expected = true;
283 let a = Boolean::<Circuit>::new(Mode::Public, true);
284 let b = Boolean::<Circuit>::new(Mode::Private, true);
285 check_and("true AND true", expected, a, b, 0, 0, 1, 1);
286 }
287
288 #[test]
289 fn test_private_and_constant() {
290 let expected = false;
292 let a = Boolean::<Circuit>::new(Mode::Private, false);
293 let b = Boolean::<Circuit>::new(Mode::Constant, false);
294 check_and("false AND false", expected, a, b, 0, 0, 0, 0);
295
296 let expected = false;
298 let a = Boolean::<Circuit>::new(Mode::Private, false);
299 let b = Boolean::<Circuit>::new(Mode::Constant, true);
300 check_and("false AND true", expected, a, b, 0, 0, 0, 0);
301
302 let expected = false;
304 let a = Boolean::<Circuit>::new(Mode::Private, true);
305 let b = Boolean::<Circuit>::new(Mode::Constant, false);
306 check_and("true AND false", expected, a, b, 0, 0, 0, 0);
307
308 let expected = true;
310 let a = Boolean::<Circuit>::new(Mode::Private, true);
311 let b = Boolean::<Circuit>::new(Mode::Constant, true);
312 check_and("true AND true", expected, a, b, 0, 0, 0, 0);
313 }
314
315 #[test]
316 fn test_private_and_public() {
317 let expected = false;
319 let a = Boolean::<Circuit>::new(Mode::Public, false);
320 let b = Boolean::<Circuit>::new(Mode::Private, false);
321 check_and("false AND false", expected, a, b, 0, 0, 1, 1);
322
323 let expected = false;
325 let a = Boolean::<Circuit>::new(Mode::Public, false);
326 let b = Boolean::<Circuit>::new(Mode::Private, true);
327 check_and("false AND true", expected, a, b, 0, 0, 1, 1);
328
329 let expected = false;
331 let a = Boolean::<Circuit>::new(Mode::Public, true);
332 let b = Boolean::<Circuit>::new(Mode::Private, false);
333 check_and("true AND false", expected, a, b, 0, 0, 1, 1);
334
335 let expected = true;
337 let a = Boolean::<Circuit>::new(Mode::Public, true);
338 let b = Boolean::<Circuit>::new(Mode::Private, true);
339 check_and("true AND true", expected, a, b, 0, 0, 1, 1);
340 }
341
342 #[test]
343 fn test_private_and_private() {
344 let expected = false;
346 let a = Boolean::<Circuit>::new(Mode::Private, false);
347 let b = Boolean::<Circuit>::new(Mode::Private, false);
348 check_and("false AND false", expected, a, b, 0, 0, 1, 1);
349
350 let expected = false;
352 let a = Boolean::<Circuit>::new(Mode::Private, false);
353 let b = Boolean::<Circuit>::new(Mode::Private, true);
354 check_and("false AND true", expected, a, b, 0, 0, 1, 1);
355
356 let expected = false;
358 let a = Boolean::<Circuit>::new(Mode::Private, true);
359 let b = Boolean::<Circuit>::new(Mode::Private, false);
360 check_and("true AND false", expected, a, b, 0, 0, 1, 1);
361
362 let expected = true;
364 let a = Boolean::<Circuit>::new(Mode::Private, true);
365 let b = Boolean::<Circuit>::new(Mode::Private, true);
366 check_and("true AND true", expected, a, b, 0, 0, 1, 1);
367 }
368}