fancy_garbling/garble/
garbler.rs1use crate::{BinaryWireLabel, WireLabel, util::output_tweak};
2use fancy_traits::{Fancy, FancyBinary, FancyConstant, FancyEncode, FancyOutput};
3use rand::CryptoRng;
4use swanky_channel::Channel;
5use swanky_field_binary::F2;
6use vectoreyes::U8x16;
7
8pub struct Garbler<RNG, Wire> {
10 zero: Wire,
12 delta: Wire,
13 current_output: usize,
14 current_gate: usize,
15 rng: RNG,
16}
17
18impl<RNG: CryptoRng, Wire: WireLabel<F2>> Garbler<RNG, Wire> {
19 pub fn new(mut rng: RNG) -> Self {
21 let delta = Wire::rand_delta(&mut rng);
22 let one = Wire::from_repr(U8x16::from(1u128));
25 let zero = delta + one;
26 Garbler {
27 zero,
28 delta,
29 current_gate: 0,
30 current_output: 0,
31 rng,
32 }
33 }
34
35 fn current_gate(&mut self) -> usize {
37 let current = self.current_gate;
38 self.current_gate += 1;
39 current
40 }
41
42 pub fn delta(&mut self) -> Wire {
44 self.delta
45 }
46
47 fn current_output(&mut self) -> usize {
49 let current = self.current_output;
50 self.current_output += 1;
51 current
52 }
53
54 pub fn encode_zero(&mut self) -> Wire {
56 Wire::rand(&mut self.rng)
57 }
58}
59
60impl<RNG: CryptoRng, W: BinaryWireLabel> FancyBinary for Garbler<RNG, W> {
61 fn and(
62 &mut self,
63 A: &Self::Item,
64 B: &Self::Item,
65 channel: &mut Channel,
66 ) -> swanky_error::Result<Self::Item> {
67 let gate_num = self.current_gate();
68 let (gate0, gate1, C) = W::garble_and_gate(gate_num, A, B, &self.delta);
69 channel.write(&gate0)?;
70 channel.write(&gate1)?;
71 Ok(C)
72 }
73
74 fn xor(&mut self, x: &Self::Item, y: &Self::Item) -> Self::Item {
75 *x + *y
76 }
77
78 fn negate(&mut self, x: &Self::Item) -> Self::Item {
83 self.zero + *x
84 }
85}
86
87impl<RNG: CryptoRng, Wire: WireLabel<F2>> Fancy for Garbler<RNG, Wire> {
88 type Item = Wire;
89}
90
91impl<RNG: CryptoRng, Wire: WireLabel<F2>> FancyConstant<F2> for Garbler<RNG, Wire> {
92 fn constant(&mut self, x: F2) -> Self::Item {
93 if x.into() {
94 self.zero
97 } else {
98 Default::default()
100 }
101 }
102}
103
104impl<RNG: CryptoRng, Wire: WireLabel<F2>> FancyEncode<F2> for Garbler<RNG, Wire> {
105 fn encode_many(
106 &mut self,
107 values: &[F2],
108 channel: &mut Channel,
109 ) -> swanky_error::Result<Vec<Self::Item>> {
110 let mut zeros = Vec::with_capacity(values.len());
111 for x in values.iter() {
112 let zero = self.encode_zero();
113 let encoded = zero + self.delta * (*x).into();
114 channel.write(&encoded.to_repr())?;
115 zeros.push(zero);
116 }
117 Ok(zeros)
118 }
119
120 fn receive_many(&mut self, _: usize, _: &mut Channel) -> swanky_error::Result<Vec<Self::Item>> {
121 unimplemented!("Garbler cannot receive values")
122 }
123}
124
125impl<RNG: CryptoRng, Wire: WireLabel<F2>> FancyOutput<F2> for Garbler<RNG, Wire> {
126 fn output(&mut self, X: &Wire, channel: &mut Channel) -> swanky_error::Result<Option<F2>> {
127 let i = self.current_output();
128 for k in 0..2 {
129 let block = (*X + self.delta() * k).hash(output_tweak(i, k));
130 channel.write(&block)?;
131 }
132 Ok(None)
133 }
134}