1use 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
15pub struct Dummy;
17
18#[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 pub fn new(val: u16, modulus: u16) -> Self {
34 Self { val, modulus }
35 }
36
37 pub fn val(&self) -> u16 {
39 self.val
40 }
41}
42
43impl Dummy {
44 pub fn new() -> Dummy {
46 Dummy {}
47 }
48
49 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 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 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 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 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}