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