fancy_garbling/
errors.rs

1//! Errors that may be output by this library.
2
3use std::fmt::{self, Display, Formatter};
4use swanky_block::Block;
5
6/// Errors that may occur when using the `Fancy` trait. These errors are
7/// API-usage errors, such as trying to add two `Items` with different moduli.
8#[derive(Debug)]
9pub enum FancyError {
10    /// Unequal moduli.
11    UnequalModuli,
12    /// Invalid argument.
13    InvalidArg(String),
14    /// Invalid number of arguments.
15    InvalidArgNum {
16        /// Received number of arguments.
17        got: usize,
18        /// Expected number of arguments.
19        needed: usize,
20    },
21    /// Invalid argument modulus.
22    InvalidArgMod {
23        /// Received modulus.
24        got: u16,
25        /// Expected modulus.
26        needed: u16,
27    },
28    /// Expected binary argument.
29    ArgNotBinary,
30    /// Truth table expected but none given.
31    NoTruthTable,
32    /// Projection truth table is invalid.
33    InvalidTruthTable,
34    /// Uninitialized value encountered.
35    UninitializedValue,
36}
37
38/// Errors from the dummy fancy object.
39#[derive(Debug)]
40pub enum DummyError {
41    /// Not enough garbler inputs provided.
42    NotEnoughGarblerInputs,
43    /// Not enough evaluator inputs provided.
44    NotEnoughEvaluatorInputs,
45    /// Encoding error.
46    EncodingError,
47    /// A fancy error has occurred.
48    FancyError(FancyError),
49}
50
51/// Errors from the evaluator.
52#[derive(Debug)]
53pub enum EvaluatorError {
54    /// Not enough garbler inputs provided.
55    NotEnoughGarblerInputs,
56    /// Not enough evaluator inputs provided.
57    NotEnoughEvaluatorInputs,
58    /// Decoding failed.
59    DecodingFailed,
60    /// A communication error has occurred.
61    CommunicationError(String),
62    /// A fancy error has occurred.
63    FancyError(FancyError),
64}
65
66/// Errors from the garbler.
67#[derive(Debug)]
68pub enum GarblerError {
69    /// An error occurred while processing a message.
70    CommunicationError(String),
71    /// Asymmetric moduli error.
72    AsymmetricHalfGateModuliMax8(u16),
73    /// A truth table was missing.
74    TruthTableRequired,
75    /// Delta required for wire reuse.
76    DeltaRequired,
77    /// Encoding error.
78    EncodingError,
79    /// A fancy error has occurred.
80    FancyError(FancyError),
81}
82
83/// Errors emitted when building a circuit.
84#[derive(Debug)]
85pub enum CircuitBuilderError {
86    /// Reuse not supported.
87    ReuseUndefined,
88    /// A fancy error has occurred.
89    FancyError(FancyError),
90}
91
92/// General wire deserialization error
93#[cfg(feature = "serde")]
94#[derive(Debug)]
95pub enum WireDeserializationError {
96    /// Deserialization of `WireMod3` failed
97    InvalidWireMod3,
98    /// Deserialization of `WireModQ` failed
99    InvalidWireModQ(ModQDeserializationError),
100}
101
102/// `WireModQ` wire deserialization error
103#[cfg(feature = "serde")]
104#[derive(Debug)]
105pub enum ModQDeserializationError {
106    /// Modulus must be greater than 1
107    BadModulus(u16),
108
109    /// One of the digits is larger than the modulus
110    DigitTooLarge {
111        /// The invalid digit
112        digit: u16,
113        /// Modulus of wire
114        modulus: u16,
115    },
116
117    /// Unexpected number of digits
118    InvalidDigitsLength {
119        /// Number of digits given
120        got: usize,
121        /// Number of digits expected (based on modulus)
122        needed: usize,
123    },
124}
125
126////////////////////////////////////////////////////////////////////////////////
127// Serialization error
128//
129
130#[cfg(feature = "serde")]
131impl Display for WireDeserializationError {
132    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
133        match self {
134            WireDeserializationError::InvalidWireMod3 => {
135                "deserialization of WireMod3 failed: both lsb and msb cannot be set".fmt(f)
136            }
137            WireDeserializationError::InvalidWireModQ(e) => {
138                write!(f, "deserialization of WireModQ failed: {}", e)
139            }
140        }
141    }
142}
143
144#[cfg(feature = "serde")]
145impl Display for ModQDeserializationError {
146    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
147        match self {
148            ModQDeserializationError::BadModulus(modulus) => {
149                write!(f, "modulus must be at least 2. Got {}", modulus)
150            }
151            ModQDeserializationError::DigitTooLarge { digit, modulus } => {
152                write!(
153                    f,
154                    "a digit {} is greater than the modulus ({}) ",
155                    digit, modulus
156                )
157            }
158            ModQDeserializationError::InvalidDigitsLength { got, needed } => {
159                write!(
160                    f,
161                    "invalid number of digits. Expected {}, got {}",
162                    needed, got
163                )
164            }
165        }
166    }
167}
168
169////////////////////////////////////////////////////////////////////////////////
170// fancy error
171//
172
173impl Display for FancyError {
174    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
175        match self {
176            FancyError::UnequalModuli => "unequal moduli".fmt(f),
177            FancyError::InvalidArg(s) => write!(f, "invalid argument: {}", s),
178            FancyError::InvalidArgNum { got, needed } => write!(
179                f,
180                "invalid number of arguments: needed {} but got {}",
181                got, needed
182            ),
183            FancyError::InvalidArgMod { got, needed } => write!(
184                f,
185                "invalid modulus: got mod {} but require mod {}",
186                got, needed
187            ),
188            FancyError::ArgNotBinary => "argument bundle must be boolean".fmt(f),
189            FancyError::NoTruthTable => "truth table required".fmt(f),
190            FancyError::InvalidTruthTable => "invalid truth table".fmt(f),
191            FancyError::UninitializedValue => {
192                "uninitialized value in circuit. is the circuit topologically sorted?".fmt(f)
193            }
194        }
195    }
196}
197
198////////////////////////////////////////////////////////////////////////////////
199// Dummy error
200
201impl Display for DummyError {
202    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
203        match self {
204            DummyError::NotEnoughGarblerInputs => "not enough garbler inputs".fmt(f),
205            DummyError::NotEnoughEvaluatorInputs => "not enough evaluator inputs".fmt(f),
206            DummyError::EncodingError => "not enough inputs or moduli".fmt(f),
207            DummyError::FancyError(e) => write!(f, "fancy error: {}", e),
208        }
209    }
210}
211
212impl From<FancyError> for DummyError {
213    fn from(e: FancyError) -> DummyError {
214        DummyError::FancyError(e)
215    }
216}
217
218////////////////////////////////////////////////////////////////////////////////
219// Evaluator error
220
221impl Display for EvaluatorError {
222    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
223        match self {
224            EvaluatorError::NotEnoughGarblerInputs => "not enough garbler inputs".fmt(f),
225            EvaluatorError::NotEnoughEvaluatorInputs => "not enough evaluator inputs".fmt(f),
226            EvaluatorError::DecodingFailed => write!(f, "decodiing failed"),
227            EvaluatorError::CommunicationError(s) => write!(f, "communication error: {}", s),
228            EvaluatorError::FancyError(e) => write!(f, "fancy error: {}", e),
229        }
230    }
231}
232
233impl From<FancyError> for EvaluatorError {
234    fn from(e: FancyError) -> Self {
235        EvaluatorError::FancyError(e)
236    }
237}
238
239impl From<std::io::Error> for EvaluatorError {
240    fn from(e: std::io::Error) -> Self {
241        EvaluatorError::CommunicationError(e.to_string())
242    }
243}
244
245impl From<std::sync::mpsc::RecvError> for EvaluatorError {
246    fn from(e: std::sync::mpsc::RecvError) -> Self {
247        EvaluatorError::CommunicationError(e.to_string())
248    }
249}
250
251////////////////////////////////////////////////////////////////////////////////
252// Garbler error
253
254impl Display for GarblerError {
255    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
256        match self {
257            GarblerError::CommunicationError(s) => write!(f, "{}", s),
258            GarblerError::AsymmetricHalfGateModuliMax8(q) => write!(
259                f,
260                "the small modulus in a half gate with asymmetric moduli is capped at 8, got {}",
261                q
262            ),
263            GarblerError::TruthTableRequired => {
264                "truth table required for garbler projection gates".fmt(f)
265            }
266            GarblerError::DeltaRequired => {
267                "delta from previous execution of garbler must be provided with wire to reuse"
268                    .fmt(f)
269            }
270            GarblerError::EncodingError => {
271                "encoding failed: unequal length input values and moduli".fmt(f)
272            }
273            GarblerError::FancyError(e) => write!(f, "{}", e),
274        }
275    }
276}
277
278impl From<FancyError> for GarblerError {
279    fn from(e: FancyError) -> Self {
280        GarblerError::FancyError(e)
281    }
282}
283
284impl From<std::io::Error> for GarblerError {
285    fn from(e: std::io::Error) -> Self {
286        GarblerError::CommunicationError(e.to_string())
287    }
288}
289
290impl From<std::sync::mpsc::SendError<Vec<Block>>> for GarblerError {
291    fn from(e: std::sync::mpsc::SendError<Vec<Block>>) -> Self {
292        GarblerError::CommunicationError(e.to_string())
293    }
294}
295
296////////////////////////////////////////////////////////////////////////////////
297// circuit builder error
298
299impl Display for CircuitBuilderError {
300    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
301        match self {
302            CircuitBuilderError::FancyError(e) => write!(f, "fancy error: {}", e),
303            CircuitBuilderError::ReuseUndefined => write!(
304                f,
305                "reuse is undefined for circuits. it is unclear what it means to reuse a
306                CircuitRef from a previous circuit."
307            ),
308        }
309    }
310}
311
312impl From<FancyError> for CircuitBuilderError {
313    fn from(e: FancyError) -> Self {
314        CircuitBuilderError::FancyError(e)
315    }
316}
317
318/// Errors emitted by the circuit parser.
319#[derive(Debug)]
320pub enum CircuitParserError {
321    /// An I/O error occurred.
322    IoError(std::io::Error),
323    /// A regular expression parsing error occurred.
324    RegexError(regex::Error),
325    /// An error occurred parsing an integer.
326    ParseIntError,
327    /// An error occurred parsing a line.
328    ParseLineError(String),
329    /// An error occurred parsing a gate type.
330    ParseGateError(String),
331}
332
333impl Display for CircuitParserError {
334    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
335        match self {
336            CircuitParserError::IoError(e) => write!(f, "io error: {}", e),
337            CircuitParserError::RegexError(e) => write!(f, "regex error: {}", e),
338            CircuitParserError::ParseIntError => write!(f, "unable to parse integer"),
339            CircuitParserError::ParseLineError(s) => write!(f, "unable to parse line '{}'", s),
340            CircuitParserError::ParseGateError(s) => write!(f, "unable to parse gate '{}'", s),
341        }
342    }
343}
344
345impl From<std::io::Error> for CircuitParserError {
346    fn from(e: std::io::Error) -> CircuitParserError {
347        CircuitParserError::IoError(e)
348    }
349}
350
351impl From<regex::Error> for CircuitParserError {
352    fn from(e: regex::Error) -> CircuitParserError {
353        CircuitParserError::RegexError(e)
354    }
355}
356
357impl From<std::num::ParseIntError> for CircuitParserError {
358    fn from(_: std::num::ParseIntError) -> CircuitParserError {
359        CircuitParserError::ParseIntError
360    }
361}
362
363////////////////////////////////////////////////////////////////////////////////
364// 2PC errors
365
366/// Errors produced by `twopac`.
367#[derive(Debug)]
368pub enum TwopacError {
369    /// An I/O error has occurred.
370    IoError(std::io::Error),
371    /// An oblivious transfer error has occurred.
372    OtError(swanky_ocelot_error::Error),
373    /// The garbler produced an error.
374    GarblerError(GarblerError),
375    /// The evaluator produced an error.
376    EvaluatorError(EvaluatorError),
377    /// Processing the garbled circuit produced an error.
378    FancyError(FancyError),
379}
380
381impl std::error::Error for TwopacError {}
382
383impl From<swanky_ocelot_error::Error> for TwopacError {
384    fn from(e: swanky_ocelot_error::Error) -> TwopacError {
385        TwopacError::OtError(e)
386    }
387}
388
389impl From<std::io::Error> for TwopacError {
390    fn from(e: std::io::Error) -> TwopacError {
391        TwopacError::IoError(e)
392    }
393}
394
395impl From<EvaluatorError> for TwopacError {
396    fn from(e: EvaluatorError) -> TwopacError {
397        TwopacError::EvaluatorError(e)
398    }
399}
400
401impl From<GarblerError> for TwopacError {
402    fn from(e: GarblerError) -> TwopacError {
403        TwopacError::GarblerError(e)
404    }
405}
406
407impl From<FancyError> for TwopacError {
408    fn from(e: FancyError) -> TwopacError {
409        TwopacError::FancyError(e)
410    }
411}
412
413impl std::fmt::Display for TwopacError {
414    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
415        match self {
416            TwopacError::IoError(e) => write!(f, "IO error: {}", e),
417            TwopacError::OtError(e) => write!(f, "oblivious transfer error: {}", e),
418            TwopacError::EvaluatorError(e) => write!(f, "evaluator error: {}", e),
419            TwopacError::GarblerError(e) => write!(f, "garbler error: {}", e),
420            TwopacError::FancyError(e) => write!(f, "fancy error: {}", e),
421        }
422    }
423}
424
425impl From<TwopacError> for GarblerError {
426    fn from(e: TwopacError) -> GarblerError {
427        GarblerError::CommunicationError(e.to_string())
428    }
429}
430
431impl From<TwopacError> for EvaluatorError {
432    fn from(e: TwopacError) -> EvaluatorError {
433        EvaluatorError::CommunicationError(e.to_string())
434    }
435}