fancy_garbling/circuits/binary/
binary_adder.rs1use crate::{FancyBinary, circuit::Circuit};
2use core::marker::PhantomData;
3use swanky_channel::Channel;
4use swanky_error::Result;
5
6#[derive(Default)]
11pub struct BinaryAdder<'a>(PhantomData<&'a ()>);
12
13impl<'a> BinaryAdder<'a> {
14 pub fn new() -> Self {
16 Default::default()
17 }
18}
19
20impl<'a, F: FancyBinary> Circuit<F> for BinaryAdder<'a>
21where
22 F::Item: 'a,
23{
24 type Input = (&'a F::Item, &'a F::Item, Option<&'a F::Item>);
25 type Output = (F::Item, 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 let (x, y, carry_in) = inputs;
34 if let Some(c) = carry_in {
35 let z1 = backend.xor(x, y);
36 let z2 = backend.xor(&z1, c);
37 let z3 = backend.xor(x, c);
38 let z4 = backend.and(&z1, &z3, channel)?;
39 let carry = backend.xor(&z4, x);
40 Ok((z2, carry))
41 } else {
42 let z = backend.xor(x, y);
43 let carry = backend.and(x, y, channel)?;
44 Ok((z, carry))
45 }
46 }
47}
48
49#[cfg(test)]
50pub mod test {
51 use super::BinaryAdder;
52
53 #[test]
54 fn binary_adder() {
55 use crate::dummy::{Dummy, DummyVal};
56
57 let circuit = BinaryAdder::new();
58 let zero = DummyVal::new(0, 2);
59 let one = DummyVal::new(1, 2);
60
61 let output = Dummy::eval(&circuit, (&zero, &zero, None)).unwrap();
62 assert_eq!(output.0, zero);
63 assert_eq!(output.1, zero);
64 let output = Dummy::eval(&circuit, (&zero, &one, None)).unwrap();
65 assert_eq!(output.0, one);
66 assert_eq!(output.1, zero);
67 let output = Dummy::eval(&circuit, (&one, &zero, None)).unwrap();
68 assert_eq!(output.0, one);
69 assert_eq!(output.1, zero);
70 let output = Dummy::eval(&circuit, (&one, &one, None)).unwrap();
71 assert_eq!(output.0, zero);
72 assert_eq!(output.1, one);
73 }
74}