fancy_garbling/circuits/binary/
pairwise_xor.rs1use crate::{FancyBinary, circuit::Circuit};
2use core::marker::PhantomData;
3use swanky_channel::Channel;
4use swanky_error::Result;
5
6#[derive(Default)]
8pub struct PairwiseXor<'a>(PhantomData<&'a ()>);
9
10impl<'a> PairwiseXor<'a> {
11 pub fn new() -> Self {
13 Default::default()
14 }
15}
16
17impl<'a, F: FancyBinary> Circuit<F> for PairwiseXor<'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 _: &mut Channel,
29 ) -> Result<Self::Output> {
30 let (x, y) = inputs;
31 Ok(x.iter()
32 .zip(y.iter())
33 .map(|(x, y)| backend.xor(x, y))
34 .collect())
35 }
36}
37
38#[cfg(test)]
39pub mod test {
40 use super::PairwiseXor;
41
42 #[test]
43 fn pairwise_xor() {
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(&PairwiseXor::new(), (&x, &y)).unwrap();
62 assert_eq!(output, expected);
63 }
64 }
65}