Skip to main content

fancy_garbling/
dummy.rs

1//! Dummy implementation of `Fancy`.
2//!
3//! Useful for evaluating the circuits produced by `Fancy` without actually
4//! creating any circuits.
5
6use swanky_channel::Channel;
7use swanky_error::ErrorKind;
8
9use crate::{
10    FancyArithmetic, FancyBinary, FancyProj, check_binary,
11    circuit::CircuitExecutor,
12    fancy::{Fancy, HasModulus},
13};
14
15/// Simple struct that performs the fancy computation over `u16`.
16pub struct Dummy;
17
18/// Wrapper around `u16`.
19#[derive(Clone, Debug)]
20pub struct DummyVal {
21    val: u16,
22    modulus: u16,
23}
24
25impl HasModulus for DummyVal {
26    fn modulus(&self) -> u16 {
27        self.modulus
28    }
29}
30
31impl DummyVal {
32    /// Create a new DummyVal.
33    pub fn new(val: u16, modulus: u16) -> Self {
34        Self { val, modulus }
35    }
36
37    /// Extract the value.
38    pub fn val(&self) -> u16 {
39        self.val
40    }
41}
42
43impl Dummy {
44    /// Create a new Dummy.
45    pub fn new() -> Dummy {
46        Dummy {}
47    }
48
49    /// Evaluate `circuit` in plaintext.
50    ///
51    /// # Panics
52    /// Panics if `inputs.len()` does not equal the circuit's expected number of
53    /// inputs.
54    pub fn eval<C: CircuitExecutor<Dummy>>(
55        circuit: &C,
56        inputs: &[u16],
57    ) -> swanky_error::Result<Vec<u16>> {
58        assert_eq!(inputs.len(), circuit.ninputs());
59
60        let mut dummy = crate::dummy::Dummy::new();
61
62        // encode inputs as DummyVals
63        let inputs = inputs
64            .iter()
65            .enumerate()
66            .map(|(i, x)| DummyVal::new(*x, circuit.modulus(i)))
67            .collect::<Vec<_>>();
68
69        let outputs = Channel::with(std::io::empty(), |c| {
70            circuit.execute(&mut dummy, &inputs, c)
71        })?;
72        Ok(outputs.iter().map(|x| x.val()).collect())
73    }
74}
75
76impl Default for Dummy {
77    fn default() -> Self {
78        Self::new()
79    }
80}
81
82impl FancyBinary for Dummy {
83    fn xor(&mut self, x: &Self::Item, y: &Self::Item) -> Self::Item {
84        check_binary!(x);
85        check_binary!(y);
86
87        self.add(x, y)
88    }
89
90    fn and(
91        &mut self,
92        x: &Self::Item,
93        y: &Self::Item,
94        channel: &mut Channel,
95    ) -> swanky_error::Result<Self::Item> {
96        check_binary!(x);
97        check_binary!(y);
98
99        self.mul(x, y, channel)
100    }
101
102    fn negate(&mut self, x: &Self::Item) -> Self::Item {
103        check_binary!(x);
104
105        self.xor(x, &DummyVal::new(1, 2))
106    }
107}
108
109impl FancyArithmetic for Dummy {
110    fn add(&mut self, x: &DummyVal, y: &DummyVal) -> DummyVal {
111        assert_eq!(x.modulus(), y.modulus());
112        DummyVal {
113            val: (x.val + y.val) % x.modulus,
114            modulus: x.modulus,
115        }
116    }
117
118    fn sub(&mut self, x: &DummyVal, y: &DummyVal) -> DummyVal {
119        assert_eq!(x.modulus(), y.modulus());
120        DummyVal {
121            val: (x.modulus + x.val - y.val) % x.modulus,
122            modulus: x.modulus,
123        }
124    }
125
126    fn cmul(&mut self, x: &DummyVal, c: u16) -> DummyVal {
127        DummyVal {
128            val: (x.val * c) % x.modulus,
129            modulus: x.modulus,
130        }
131    }
132
133    fn mul(
134        &mut self,
135        x: &DummyVal,
136        y: &DummyVal,
137        _channel: &mut Channel,
138    ) -> swanky_error::Result<DummyVal> {
139        if x.modulus < y.modulus {
140            return self.mul(y, x, _channel);
141        }
142        Ok(DummyVal {
143            val: x.val * y.val % x.modulus,
144            modulus: x.modulus,
145        })
146    }
147}
148
149impl FancyProj for Dummy {
150    fn proj(
151        &mut self,
152        x: &DummyVal,
153        modulus: u16,
154        tt: Option<Vec<u16>>,
155        _: &mut Channel,
156    ) -> swanky_error::Result<DummyVal> {
157        assert!(tt.is_some(), "`tt` must not be `None`");
158        let tt = tt.unwrap();
159        assert!(
160            tt.len() >= x.modulus() as usize,
161            "`tt` not large enough for `x`s modulus"
162        );
163        assert!(
164            tt.iter().all(|&x| x < modulus),
165            "`tt` value larger than `q`"
166        );
167        let val = tt[x.val as usize];
168        Ok(DummyVal { val, modulus })
169    }
170}
171
172impl Fancy for Dummy {
173    type Item = DummyVal;
174
175    /// Encode a single dummy value.
176    fn encode(
177        &mut self,
178        value: u16,
179        modulus: u16,
180        _: &mut Channel,
181    ) -> swanky_error::Result<DummyVal> {
182        Ok(DummyVal::new(value, modulus))
183    }
184
185    /// Encode a slice of inputs and a slice of moduli as DummyVals.
186    fn encode_many(
187        &mut self,
188        xs: &[u16],
189        moduli: &[u16],
190        _: &mut Channel,
191    ) -> swanky_error::Result<Vec<DummyVal>> {
192        assert_eq!(xs.len(), moduli.len());
193        Ok(xs
194            .iter()
195            .zip(moduli.iter())
196            .map(|(x, q)| DummyVal::new(*x, *q))
197            .collect())
198    }
199
200    fn receive_many(
201        &mut self,
202        _moduli: &[u16],
203        _: &mut Channel,
204    ) -> swanky_error::Result<Vec<DummyVal>> {
205        // Receive is undefined for Dummy which is a single party "protocol"
206        swanky_error::bail!(
207            ErrorKind::UnsupportedError,
208            "`receive_many` is undefined for `Dummy`"
209        );
210    }
211
212    fn constant(
213        &mut self,
214        val: u16,
215        modulus: u16,
216        _: &mut Channel,
217    ) -> swanky_error::Result<DummyVal> {
218        Ok(DummyVal { val, modulus })
219    }
220
221    fn output(&mut self, x: &DummyVal, _: &mut Channel) -> swanky_error::Result<Option<u16>> {
222        Ok(Some(x.val))
223    }
224}