fancy_garbling/circuits/binary/
and_many.rs1use crate::{FancyBinary, circuit::Circuit};
2use core::marker::PhantomData;
3use swanky_channel::Channel;
4use swanky_error::Result;
5
6#[derive(Default)]
11pub struct AndMany<'a>(PhantomData<&'a ()>);
12
13impl<'a> AndMany<'a> {
14 pub fn new() -> Self {
16 Default::default()
17 }
18}
19
20impl<'a, F: FancyBinary> Circuit<F> for AndMany<'a>
21where
22 F::Item: 'a,
23{
24 type Input = &'a [F::Item];
25 type Output = F::Item;
26
27 fn execute(
28 &self,
29 backend: &mut F,
30 inputs: Self::Input,
31 channel: &mut Channel,
32 ) -> Result<Self::Output> {
33 assert!(!inputs.is_empty(), "`args` cannot be empty");
34 inputs
35 .iter()
36 .skip(1)
37 .try_fold(inputs[0].clone(), |acc, x| backend.and(&acc, x, channel))
38 }
39}
40
41#[cfg(test)]
42pub mod test {
43 use super::AndMany;
44
45 #[test]
46 fn and_many() {
47 use crate::dummy::{Dummy, DummyVal};
48 use rand::Rng;
49
50 let mut rng = rand::thread_rng();
51
52 for _ in 0..100 {
53 let n = 2 + (rng.r#gen::<usize>() % 200);
54 let inputs = (0..n)
55 .map(|_| DummyVal::rand_bool(&mut rng))
56 .collect::<Vec<_>>();
57 let expected = inputs.iter().fold(1, |acc, &x| x.val() & acc);
58 let circuit = AndMany::new();
59 let output = Dummy::eval(&circuit, inputs.as_slice()).unwrap();
60 assert_eq!(output.val(), expected);
61 }
62 }
63}