1use crate::{
2 AllWire, ArithmeticWire, Fancy, FancyArithmetic, FancyBinary, FancyInput, FancyReveal,
3 Garbler as Gb, WireMod2, errors::TwopacError, wire::WireLabel,
4};
5use rand::{CryptoRng, Rng, SeedableRng};
6use swanky_adversary::SemiHonest;
7use swanky_block::Block;
8use swanky_channel_legacy::AbstractChannel;
9use swanky_ot_traits::Sender as OtSender;
10
11pub struct Garbler<C, RNG, OT, Wire> {
13 garbler: Gb<C, RNG, Wire>,
14 ot: OT,
15 rng: RNG,
16}
17
18impl<C, OT, RNG, Wire> std::ops::Deref for Garbler<C, RNG, OT, Wire> {
19 type Target = Gb<C, RNG, Wire>;
20 fn deref(&self) -> &Self::Target {
21 &self.garbler
22 }
23}
24
25impl<C, OT, RNG, Wire> std::ops::DerefMut for Garbler<C, RNG, OT, Wire> {
26 fn deref_mut(&mut self) -> &mut Gb<C, RNG, Wire> {
27 &mut self.garbler
28 }
29}
30
31impl<
32 C: AbstractChannel,
33 RNG: CryptoRng + Rng + SeedableRng<Seed = Block>,
34 OT: OtSender<Msg = Block> + SemiHonest,
35 Wire: WireLabel,
36> Garbler<C, RNG, OT, Wire>
37{
38 pub fn new(mut channel: C, mut rng: RNG) -> Result<Self, TwopacError> {
40 let ot = OT::init(&mut channel, &mut rng)?;
41
42 let garbler = Gb::new(channel, RNG::from_seed(rng.r#gen()));
43 Ok(Garbler { garbler, ot, rng })
44 }
45
46 pub fn get_channel(&mut self) -> &mut C {
48 &mut self.garbler.channel
49 }
50
51 fn _evaluator_input(&mut self, delta: &Wire, q: u16) -> (Wire, Vec<(Block, Block)>) {
52 let len = f32::from(q).log(2.0).ceil() as u16;
53 let mut wire = Wire::zero(q);
54 let inputs = (0..len)
55 .map(|i| {
56 let zero = Wire::rand(&mut self.rng, q);
57 let one = zero.plus(delta);
58 wire = wire.plus(&zero.cmul(1 << i));
59 (zero.as_block(), one.as_block())
60 })
61 .collect::<Vec<(Block, Block)>>();
62 (wire, inputs)
63 }
64}
65
66impl<
67 C: AbstractChannel,
68 RNG: CryptoRng + Rng + SeedableRng<Seed = Block>,
69 OT: OtSender<Msg = Block> + SemiHonest,
70 Wire: WireLabel,
71> FancyInput for Garbler<C, RNG, OT, Wire>
72{
73 type Item = Wire;
74 type Error = TwopacError;
75
76 fn encode(&mut self, val: u16, modulus: u16) -> Result<Wire, TwopacError> {
77 let (mine, theirs) = self.garbler.encode_wire(val, modulus);
78 self.garbler.send_wire(&theirs)?;
79 self.channel.flush()?;
80 Ok(mine)
81 }
82
83 fn encode_many(&mut self, vals: &[u16], moduli: &[u16]) -> Result<Vec<Wire>, TwopacError> {
84 let ws = vals
85 .iter()
86 .zip(moduli.iter())
87 .map(|(x, q)| {
88 let (mine, theirs) = self.garbler.encode_wire(*x, *q);
89 self.garbler.send_wire(&theirs)?;
90 Ok(mine)
91 })
92 .collect();
93 self.channel.flush()?;
94 ws
95 }
96
97 fn receive_many(&mut self, qs: &[u16]) -> Result<Vec<Wire>, TwopacError> {
98 self.channel.flush()?;
99 let n = qs.len();
100 let lens = qs.iter().map(|q| f32::from(*q).log(2.0).ceil() as usize);
101 let mut wires = Vec::with_capacity(n);
102 let mut inputs = Vec::with_capacity(lens.sum());
103
104 for q in qs.iter() {
105 let delta = self.garbler.delta(*q);
106 let (wire, input) = self._evaluator_input(&delta, *q);
107 wires.push(wire);
108 for i in input.into_iter() {
109 inputs.push(i);
110 }
111 }
112 self.ot
113 .send(&mut self.garbler.channel, &inputs, &mut self.rng)?;
114 Ok(wires)
115 }
116}
117
118impl<C: AbstractChannel, RNG: CryptoRng + Rng, OT> FancyBinary for Garbler<C, RNG, OT, WireMod2> {
119 fn negate(&mut self, x: &Self::Item) -> Result<Self::Item, Self::Error> {
120 self.garbler.negate(x).map_err(Self::Error::from)
121 }
122
123 fn xor(&mut self, x: &Self::Item, y: &Self::Item) -> Result<Self::Item, Self::Error> {
124 self.garbler.xor(x, y).map_err(Self::Error::from)
125 }
126
127 fn and(&mut self, x: &Self::Item, y: &Self::Item) -> Result<Self::Item, Self::Error> {
128 self.garbler.and(x, y).map_err(Self::Error::from)
129 }
130}
131
132impl<C: AbstractChannel, RNG: CryptoRng + Rng, OT> FancyBinary for Garbler<C, RNG, OT, AllWire> {
133 fn negate(&mut self, x: &Self::Item) -> Result<Self::Item, Self::Error> {
134 self.garbler.negate(x).map_err(Self::Error::from)
135 }
136
137 fn xor(&mut self, x: &Self::Item, y: &Self::Item) -> Result<Self::Item, Self::Error> {
138 self.garbler.xor(x, y).map_err(Self::Error::from)
139 }
140
141 fn and(&mut self, x: &Self::Item, y: &Self::Item) -> Result<Self::Item, Self::Error> {
142 self.garbler.and(x, y).map_err(Self::Error::from)
143 }
144}
145
146impl<C: AbstractChannel, RNG: CryptoRng + Rng, OT, Wire: WireLabel + ArithmeticWire> FancyArithmetic
147 for Garbler<C, RNG, OT, Wire>
148{
149 fn add(&mut self, x: &Wire, y: &Wire) -> Result<Self::Item, Self::Error> {
150 self.garbler.add(x, y).map_err(Self::Error::from)
151 }
152
153 fn sub(&mut self, x: &Wire, y: &Wire) -> Result<Self::Item, Self::Error> {
154 self.garbler.sub(x, y).map_err(Self::Error::from)
155 }
156
157 fn cmul(&mut self, x: &Wire, c: u16) -> Result<Self::Item, Self::Error> {
158 self.garbler.cmul(x, c).map_err(Self::Error::from)
159 }
160
161 fn mul(&mut self, x: &Wire, y: &Wire) -> Result<Self::Item, Self::Error> {
162 self.garbler.mul(x, y).map_err(Self::Error::from)
163 }
164
165 fn proj(&mut self, x: &Wire, q: u16, tt: Option<Vec<u16>>) -> Result<Self::Item, Self::Error> {
166 self.garbler.proj(x, q, tt).map_err(Self::Error::from)
167 }
168}
169
170impl<C: AbstractChannel, RNG: CryptoRng + Rng, OT, Wire: WireLabel> Fancy
171 for Garbler<C, RNG, OT, Wire>
172{
173 type Item = Wire;
174 type Error = TwopacError;
175
176 fn constant(&mut self, x: u16, q: u16) -> Result<Self::Item, Self::Error> {
177 self.garbler.constant(x, q).map_err(Self::Error::from)
178 }
179
180 fn output(&mut self, x: &Self::Item) -> Result<Option<u16>, Self::Error> {
181 self.garbler.output(x).map_err(Self::Error::from)
182 }
183}
184
185impl<C: AbstractChannel, RNG: CryptoRng + Rng, OT, Wire: WireLabel> FancyReveal
186 for Garbler<C, RNG, OT, Wire>
187{
188 fn reveal(&mut self, x: &Self::Item) -> Result<u16, Self::Error> {
189 self.garbler.reveal(x).map_err(Self::Error::from)
190 }
191}
192
193impl<C, RNG, OT, Wire> SemiHonest for Garbler<C, RNG, OT, Wire> {}