diff --git a/src/circuit.rs b/src/circuit.rs index d441107..ae6b7cd 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -263,8 +263,8 @@ pub(crate) struct CircuitBuilder { gates_optimized: usize, gate_counter: usize, panic_gates: PanicResult, + panic_wires: HashMap, consts: HashMap, - panic_enabled: bool, } pub(crate) const USIZE_BITS: usize = 32; @@ -389,11 +389,7 @@ impl PanicReason { } impl CircuitBuilder { - pub fn new( - input_gates: Vec, - consts: HashMap, - panic_enabled: bool, - ) -> Self { + pub fn new(input_gates: Vec, consts: HashMap) -> Self { let mut gate_counter = 2; // for const true and false for input_gates_of_party in input_gates.iter() { gate_counter += input_gates_of_party; @@ -407,8 +403,8 @@ impl CircuitBuilder { gates_optimized: 0, gate_counter, panic_gates: PanicResult::ok(), + panic_wires: HashMap::new(), consts, - panic_enabled, } } @@ -584,7 +580,8 @@ impl CircuitBuilder { } pub fn push_panic_if(&mut self, cond: GateIndex, reason: PanicReason, meta: MetaInfo) { - if !self.panic_enabled { + if let Some(existing_panic) = self.panic_wires.get(&cond) { + self.panic_gates = existing_panic.clone(); return; } let already_panicked = self.panic_gates.has_panicked; @@ -626,6 +623,7 @@ impl CircuitBuilder { current.panic_type[i], ); } + self.panic_wires.insert(cond, self.panic_gates.clone()); } pub fn peek_panic(&self) -> &PanicResult { diff --git a/src/compile.rs b/src/compile.rs index 239adf2..7e14c7d 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -86,18 +86,6 @@ impl TypedProgram { .map(|(c, f, _)| (c, f)) } - /// Compiles the (type-checked) program, _silently ignoring panics_. - /// - /// Assumes that the input program has been correctly type-checked and **panics** if - /// incompatible types are found that should have been caught by the type-checker. - pub fn compile_ignore_panic( - &self, - fn_name: &str, - ) -> Result<(Circuit, &TypedFnDef), Vec> { - self.compile_with_constants_ignore_panic(fn_name, HashMap::new()) - .map(|(c, f, _)| (c, f)) - } - /// Compiles the (type-checked) program with provided constants, producing a circuit of gates. /// /// Assumes that the input program has been correctly type-checked and **panics** if @@ -106,27 +94,6 @@ impl TypedProgram { &self, fn_name: &str, consts: HashMap>, - ) -> Result> { - self.comp_with_constants(fn_name, consts, true) - } - - /// Compiles the (type-checked) program with provided constants, _silently ignoring panics_. - /// - /// Assumes that the input program has been correctly type-checked and **panics** if - /// incompatible types are found that should have been caught by the type-checker. - pub fn compile_with_constants_ignore_panic( - &self, - fn_name: &str, - consts: HashMap>, - ) -> Result> { - self.comp_with_constants(fn_name, consts, false) - } - - fn comp_with_constants( - &self, - fn_name: &str, - consts: HashMap>, - panic_enabled: bool, ) -> Result> { let mut env = Env::new(); let mut const_sizes = HashMap::new(); @@ -282,7 +249,7 @@ impl TypedProgram { input_gates.push(type_size); env.let_in_current_scope(param.name.clone(), wires); } - let mut circuit = CircuitBuilder::new(input_gates, const_sizes.clone(), panic_enabled); + let mut circuit = CircuitBuilder::new(input_gates, const_sizes.clone()); for (const_name, const_def) in self.const_defs.iter() { let ConstExpr(expr, _) = &const_def.value; match expr { diff --git a/src/lib.rs b/src/lib.rs index 414c7c8..269798e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -110,20 +110,6 @@ pub fn compile(prg: &str) -> Result { }) } -/// Scans, parses, type-checks and then compiles the `"main"` fn of a program to a boolean circuit. -pub fn compile_ignore_panic(prg: &str) -> Result { - let program = check(prg)?; - let (circuit, main) = program.compile_ignore_panic("main")?; - let main = main.clone(); - Ok(GarbleProgram { - program, - main, - circuit, - consts: HashMap::new(), - const_sizes: HashMap::new(), - }) -} - /// Scans, parses, type-checks and then compiles the `"main"` fn of a program to a boolean circuit. pub fn compile_with_constants( prg: &str, @@ -141,24 +127,6 @@ pub fn compile_with_constants( }) } -/// Scans, parses, type-checks and then compiles the `"main"` fn of a program to a boolean circuit. -pub fn compile_with_constants_ignore_panic( - prg: &str, - consts: HashMap>, -) -> Result { - let program = check(prg)?; - let (circuit, main, const_sizes) = - program.compile_with_constants_ignore_panic("main", consts.clone())?; - let main = main.clone(); - Ok(GarbleProgram { - program, - main, - circuit, - consts, - const_sizes, - }) -} - /// The result of type-checking and compiling a Garble program. #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] diff --git a/tests/circuit.rs b/tests/circuit.rs index 25c2fcd..c073f7f 100644 --- a/tests/circuit.rs +++ b/tests/circuit.rs @@ -1,4 +1,4 @@ -use garble_lang::{compile, compile_ignore_panic}; +use garble_lang::compile; #[test] fn optimize_or() -> Result<(), String> { @@ -79,8 +79,8 @@ pub fn main(b: bool, x: i32) -> i32 { if b { y } else { y } } "; - let unoptimized = compile_ignore_panic(unoptimized).map_err(|e| e.prettify(unoptimized))?; - let optimized = compile_ignore_panic(optimized).map_err(|e| e.prettify(optimized))?; + let unoptimized = compile(unoptimized).map_err(|e| e.prettify(unoptimized))?; + let optimized = compile(optimized).map_err(|e| e.prettify(optimized))?; assert_eq!( unoptimized.circuit.gates.len(), optimized.circuit.gates.len() @@ -119,8 +119,8 @@ fn add(a: i8, b: i8) -> i8 { a + b } "; - let unoptimized = compile_ignore_panic(unoptimized).map_err(|e| e.prettify(unoptimized))?; - let optimized = compile_ignore_panic(optimized).map_err(|e| e.prettify(optimized))?; + let unoptimized = compile(unoptimized).map_err(|e| e.prettify(unoptimized))?; + let optimized = compile(optimized).map_err(|e| e.prettify(optimized))?; assert_eq!( unoptimized.circuit.gates.len(), optimized.circuit.gates.len() diff --git a/tests/panic.rs b/tests/panic.rs index e52d69a..ba556c4 100644 --- a/tests/panic.rs +++ b/tests/panic.rs @@ -333,7 +333,7 @@ fn expect_panic(eval_result: Result, expected: PanicReaso let eval_output = Vec::::try_from(eval_result.unwrap()); assert!(eval_output.is_err()); match eval_output.unwrap_err() { - EvalError::Panic(EvalPanic { reason, .. }) => assert_eq!(expected, reason), + EvalError::Panic(EvalPanic { reason, .. }) => assert_eq!(reason, expected), e => panic!("Expected a panic, but found {e:?}"), } }