Skip to main content

fancy_garbling/circuits/binary/
pairwise_or.rs

1use crate::{FancyBinary, circuit::Circuit};
2use core::marker::PhantomData;
3use swanky_channel::Channel;
4use swanky_error::Result;
5
6/// Pairwise OR of two bitvectors.
7#[derive(Default)]
8pub struct PairwiseOr<'a>(PhantomData<&'a ()>);
9
10impl<'a> PairwiseOr<'a> {
11    /// Create a new [`PairwiseOr`] circuit.
12    pub fn new() -> Self {
13        Default::default()
14    }
15}
16
17impl<'a, F: FancyBinary> Circuit<F> for PairwiseOr<'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.or(x, y, channel))
34            .collect()
35    }
36}
37
38#[cfg(test)]
39pub mod test {
40    use super::PairwiseOr;
41
42    #[test]
43    fn pairwise_or() {
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            let x = (0..n)
51                .map(|_| DummyVal::rand_bool(&mut rng))
52                .collect::<Vec<_>>();
53            let y = (0..n)
54                .map(|_| DummyVal::rand_bool(&mut rng))
55                .collect::<Vec<_>>();
56            let expected = x
57                .iter()
58                .zip(y.iter())
59                .map(|(x, y)| DummyVal::new(x.val() | y.val(), 2))
60                .collect::<Vec<_>>();
61            let output = Dummy::eval(&PairwiseOr::new(), (&x, &y)).unwrap();
62            assert_eq!(output, expected);
63        }
64    }
65}