diff --git a/examples/fixture/asm/kimchi/unused_variables.asm b/examples/fixture/asm/kimchi/unused_variables.asm new file mode 100644 index 000000000..56f7c5f59 --- /dev/null +++ b/examples/fixture/asm/kimchi/unused_variables.asm @@ -0,0 +1,7 @@ +@ noname.0.7.0 +@ public inputs: 1 + +DoubleGeneric<1> +DoubleGeneric<1,0,-1,0,1> +DoubleGeneric<1,0,0,0,-2> +(0,0) -> (2,0) diff --git a/examples/fixture/asm/r1cs/unused_variables.asm b/examples/fixture/asm/r1cs/unused_variables.asm new file mode 100644 index 000000000..217b7d2cd --- /dev/null +++ b/examples/fixture/asm/r1cs/unused_variables.asm @@ -0,0 +1,4 @@ +@ noname.0.7.0 +@ public inputs: 1 + +2 == (v_1) * (1) diff --git a/examples/unused_variables.no b/examples/unused_variables.no new file mode 100644 index 000000000..9e9247b3b --- /dev/null +++ b/examples/unused_variables.no @@ -0,0 +1,4 @@ +fn main(pub xx: Field, yy: Field) { + let zz = yy + 1; + assert_eq(xx, 2); +} diff --git a/src/backends/kimchi/mod.rs b/src/backends/kimchi/mod.rs index c15c7f107..7607d97b9 100644 --- a/src/backends/kimchi/mod.rs +++ b/src/backends/kimchi/mod.rs @@ -335,6 +335,7 @@ impl Backend for KimchiVesta { &mut self, public_output: Option>, returned_cells: Option>, + disable_safety_check: bool, ) -> Result<()> { // TODO: the current tests pass even this is commented out. Add a test case for this one. // important: there might still be a pending generic gate @@ -357,7 +358,7 @@ impl Backend for KimchiVesta { } for var in 0..self.next_variable { - if !written_vars.contains(&var) { + if !written_vars.contains(&var) && !disable_safety_check { if let Some(private_cell_var) = self .private_input_cell_vars .iter() diff --git a/src/backends/kimchi/prover.rs b/src/backends/kimchi/prover.rs index 0b706d06d..038363c80 100644 --- a/src/backends/kimchi/prover.rs +++ b/src/backends/kimchi/prover.rs @@ -269,7 +269,7 @@ mod tests { .unwrap(); let kimchi_vesta = KimchiVesta::new(false); - let compiled_circuit = compile(&sources, tast, kimchi_vesta, &mut None)?; + let compiled_circuit = compile(&sources, tast, kimchi_vesta, &mut None, false)?; let (prover_index, _) = compiled_circuit.compile_to_indexes().unwrap(); diff --git a/src/backends/mod.rs b/src/backends/mod.rs index 4b5ef5820..1fb08c541 100644 --- a/src/backends/mod.rs +++ b/src/backends/mod.rs @@ -407,6 +407,7 @@ pub trait Backend: Clone { &mut self, public_output: Option>, returned_cells: Option>, + disable_safety_check: bool, ) -> Result<()>; /// Generate the witness for a backend. diff --git a/src/backends/r1cs/arkworks.rs b/src/backends/r1cs/arkworks.rs index c43b04222..381f44464 100644 --- a/src/backends/r1cs/arkworks.rs +++ b/src/backends/r1cs/arkworks.rs @@ -91,6 +91,7 @@ pub const WITH_PUBLIC_OUTPUT_ARRAY: &str = pub fn compile_source_code( code: &str, + disable_safety_check: bool, ) -> Result>, crate::error::Error> { let mut sources = Sources::new(); @@ -111,7 +112,7 @@ pub fn compile_source_code( let mast = mast::monomorphize(tast)?; let r1cs = R1CS::::new(); // compile - CircuitWriter::generate_circuit(mast, r1cs) + CircuitWriter::generate_circuit(mast, r1cs, disable_safety_check) } #[cfg(test)] @@ -124,7 +125,8 @@ mod tests { #[test] fn test_arkworks_cs_is_satisfied() { - let compiled_circuit = compile_source_code::(SIMPLE_ADDITION).unwrap(); + let compiled_circuit = + compile_source_code::(SIMPLE_ADDITION, false).unwrap(); let inputs_public = r#"{"public_input": "2"}"#; let inputs_private = r#"{"private_input": "2"}"#; @@ -148,7 +150,7 @@ mod tests { #[test] fn test_arkworks_cs_is_satisfied_array() { let compiled_circuit = - compile_source_code::(WITH_PUBLIC_OUTPUT_ARRAY).unwrap(); + compile_source_code::(WITH_PUBLIC_OUTPUT_ARRAY, false).unwrap(); let inputs_public = r#"{"public_input": ["2", "5"]}"#; let inputs_private = r#"{"private_input": ["8", "2"]}"#; diff --git a/src/backends/r1cs/mod.rs b/src/backends/r1cs/mod.rs index 6eb6527cd..dea53efb8 100644 --- a/src/backends/r1cs/mod.rs +++ b/src/backends/r1cs/mod.rs @@ -407,6 +407,7 @@ where &mut self, public_output: Option>, returned_cells: Option>>, + disable_safety_check: bool, ) -> crate::error::Result<()> { // store the return value in the public input that was created for that if let Some(public_output) = public_output { @@ -440,7 +441,7 @@ where continue; } - if !written_vars.contains(&index) { + if !written_vars.contains(&index) && !disable_safety_check { if let Some(private_cell_var) = self .private_input_cell_vars .iter() diff --git a/src/circuit_writer/mod.rs b/src/circuit_writer/mod.rs index 1f77adc22..efd4b0d1f 100644 --- a/src/circuit_writer/mod.rs +++ b/src/circuit_writer/mod.rs @@ -139,7 +139,11 @@ impl CircuitWriter { } } - pub fn generate_circuit(typed: Mast, backend: B) -> Result> { + pub fn generate_circuit( + typed: Mast, + backend: B, + disable_safety_check: bool, + ) -> Result> { // create circuit writer let mut circuit_writer = CircuitWriter::new(typed, backend); @@ -212,9 +216,11 @@ impl CircuitWriter { } } - circuit_writer - .backend - .finalize_circuit(public_output, returned_cells)?; + circuit_writer.backend.finalize_circuit( + public_output, + returned_cells, + disable_safety_check, + )?; // Ok(CompiledCircuit::new(circuit_writer)) diff --git a/src/cli/cmd_build_and_check.rs b/src/cli/cmd_build_and_check.rs index a3e49f3ce..8877aec9d 100644 --- a/src/cli/cmd_build_and_check.rs +++ b/src/cli/cmd_build_and_check.rs @@ -71,6 +71,11 @@ pub struct CmdBuild { /// Run in server mode to help debug and understand the compiler passes. #[clap(long)] server_mode: bool, + + /// WARNING: This option disables safety checks that ensure each variable is properly constrained. + /// Do not check that every variable is in a constraint + #[arg(long = "disable-safety-check", global = true)] + disable_safety_check: bool, } pub fn cmd_build(args: CmdBuild) -> miette::Result<()> { @@ -87,8 +92,13 @@ pub fn cmd_build(args: CmdBuild) -> miette::Result<()> { }; // build - let (sources, prover_index, verifier_index) = - build(&curr_dir, args.asm, args.debug, &mut server_mode)?; + let (sources, prover_index, verifier_index) = build( + &curr_dir, + args.asm, + args.debug, + &mut server_mode, + args.disable_safety_check, + )?; // create COMPILED_DIR let compiled_path = curr_dir.join(COMPILED_DIR); @@ -255,6 +265,7 @@ pub fn build( asm: bool, debug: bool, server_mode: &mut Option, + disable_safety_check: bool, ) -> miette::Result<(Sources, ProverIndex, VerifierIndex)> { // produce all TASTs let (sources, tast) = produce_all_asts(curr_dir, server_mode)?; @@ -263,7 +274,13 @@ pub fn build( let double_generic_gate_optimization = false; let kimchi_vesta = KimchiVesta::new(double_generic_gate_optimization); - let compiled_circuit = compile(&sources, tast, kimchi_vesta, server_mode)?; + let compiled_circuit = compile( + &sources, + tast, + kimchi_vesta, + server_mode, + disable_safety_check, + )?; if asm { println!("{}", compiled_circuit.asm(&sources, debug)); @@ -304,6 +321,11 @@ pub struct CmdTest { /// enable the double generic gate optimization of kimchi (by default noname uses that optimization) #[clap(long)] double: bool, + + /// WARNING: This option disables safety checks that ensure each variable is properly constrained. + /// Do not check that every variable is in a constraint + #[arg(long = "disable-safety-check", global = true)] + disable_safety_check: bool, } pub fn cmd_test(args: CmdTest) -> miette::Result<()> { @@ -324,7 +346,13 @@ pub fn cmd_test(args: CmdTest) -> miette::Result<()> { BackendKind::KimchiVesta(_) => { let (tast, sources) = typecheck_file(&args.path)?; let kimchi_vesta = KimchiVesta::new(args.double); - let compiled_circuit = compile(&sources, tast, kimchi_vesta, &mut None)?; + let compiled_circuit = compile( + &sources, + tast, + kimchi_vesta, + &mut None, + args.disable_safety_check, + )?; let (prover_index, verifier_index) = compiled_circuit.compile_to_indexes()?; println!("successfully compiled"); @@ -343,10 +371,24 @@ pub fn cmd_test(args: CmdTest) -> miette::Result<()> { println!("proof verified"); } BackendKind::R1csBls12_381(r1cs) => { - test_r1cs_backend(r1cs, &args.path, public_inputs, private_inputs, args.debug)?; + test_r1cs_backend( + r1cs, + &args.path, + public_inputs, + private_inputs, + args.debug, + args.disable_safety_check, + )?; } BackendKind::R1csBn254(r1cs) => { - test_r1cs_backend(r1cs, &args.path, public_inputs, private_inputs, args.debug)?; + test_r1cs_backend( + r1cs, + &args.path, + public_inputs, + private_inputs, + args.debug, + args.disable_safety_check, + )?; } } @@ -371,6 +413,11 @@ pub struct CmdRun { /// JSON encoding of the private inputs. Similar to `--public-inputs` but for private inputs. #[clap(long, value_parser, default_value = "{}")] private_inputs: Option, + + /// WARNING: This option disables safety checks that ensure each variable is properly constrained. + /// Do not check that every variable is in a constraint + #[arg(long = "disable-safety-check", global = true)] + disable_safety_check: bool, } pub fn cmd_run(args: CmdRun) -> miette::Result<()> { @@ -395,12 +442,20 @@ pub fn cmd_run(args: CmdRun) -> miette::Result<()> { BackendKind::KimchiVesta(_) => { unimplemented!("kimchi-vesta backend is not yet supported for this command") } - BackendKind::R1csBls12_381(r1cs) => { - run_r1cs_backend(r1cs, &curr_dir, public_inputs, private_inputs)? - } - BackendKind::R1csBn254(r1cs) => { - run_r1cs_backend(r1cs, &curr_dir, public_inputs, private_inputs)? - } + BackendKind::R1csBls12_381(r1cs) => run_r1cs_backend( + r1cs, + &curr_dir, + public_inputs, + private_inputs, + args.disable_safety_check, + )?, + BackendKind::R1csBn254(r1cs) => run_r1cs_backend( + r1cs, + &curr_dir, + public_inputs, + private_inputs, + args.disable_safety_check, + )?, } Ok(()) @@ -411,6 +466,7 @@ fn run_r1cs_backend( curr_dir: &PathBuf, public_inputs: JsonInputs, private_inputs: JsonInputs, + disable_safety_check: bool, ) -> miette::Result<()> where F: BackendField, @@ -418,7 +474,7 @@ where // Assuming `curr_dir`, `public_inputs`, and `private_inputs` are available in the scope let (sources, tast) = produce_all_asts(curr_dir, &mut None)?; - let compiled_circuit = compile(&sources, tast, r1cs, &mut None)?; + let compiled_circuit = compile(&sources, tast, r1cs, &mut None, disable_safety_check)?; let generated_witness = generate_witness(&compiled_circuit, &sources, public_inputs, private_inputs)?; @@ -445,6 +501,7 @@ fn test_r1cs_backend( public_inputs: JsonInputs, private_inputs: JsonInputs, debug: bool, + disable_safety_check: bool, ) -> miette::Result<()> where F: BackendField, @@ -471,7 +528,7 @@ where &mut None, )?; - let compiled_circuit = compile(&sources, tast, r1cs, &mut None)?; + let compiled_circuit = compile(&sources, tast, r1cs, &mut None, disable_safety_check)?; generate_witness(&compiled_circuit, &sources, public_inputs, private_inputs)?; diff --git a/src/cli/cmd_prove_and_verify.rs b/src/cli/cmd_prove_and_verify.rs index 6830170f9..a5e2a8ade 100644 --- a/src/cli/cmd_prove_and_verify.rs +++ b/src/cli/cmd_prove_and_verify.rs @@ -26,6 +26,11 @@ pub struct CmdProve { /// JSON encoding of the private inputs. Similar to `--public-inputs` but for private inputs. #[clap(long, value_parser, default_value = "{}")] private_inputs: String, + + /// WARNING: This option disables safety checks that ensure each variable is properly constrained. + /// Do not check that every variable is in a constraint + #[arg(long = "disable-safety-check", global = true)] + disable_safety_check: bool, } pub fn cmd_prove(args: CmdProve) -> miette::Result<()> { @@ -33,7 +38,13 @@ pub fn cmd_prove(args: CmdProve) -> miette::Result<()> { .path .unwrap_or_else(|| std::env::current_dir().unwrap().try_into().unwrap()); - let (sources, prover_index, verifier_index) = build(&curr_dir, false, args.debug, &mut None)?; + let (sources, prover_index, verifier_index) = build( + &curr_dir, + false, + args.debug, + &mut None, + args.disable_safety_check, + )?; // parse inputs let public_inputs = parse_inputs(&args.public_inputs).unwrap(); @@ -86,6 +97,11 @@ pub struct CmdVerify { /// An optional expected public output, in JSON format. #[clap(short, long, value_parser)] public_output: Option, + + /// WARNING: This option disables safety checks that ensure each variable is properly constrained. + /// Do not check that every variable is in a constraint + #[arg(long = "disable-safety-check", global = true)] + disable_safety_check: bool, } pub fn cmd_verify(args: CmdVerify) -> miette::Result<()> { @@ -93,7 +109,13 @@ pub fn cmd_verify(args: CmdVerify) -> miette::Result<()> { .path .unwrap_or_else(|| std::env::current_dir().unwrap().try_into().unwrap()); - let (_sources, _prover_index, verifier_index) = build(&curr_dir, false, false, &mut None)?; + let (_sources, _prover_index, verifier_index) = build( + &curr_dir, + false, + false, + &mut None, + args.disable_safety_check, + )?; // parse inputs let mut public_inputs = parse_inputs(&args.public_inputs).unwrap(); diff --git a/src/compiler.rs b/src/compiler.rs index 9bd2d7689..e1a2e13ec 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -210,6 +210,7 @@ pub fn compile( tast: TypeChecker, backend: B, server_mode: &mut Option, + disable_safety_check: bool, ) -> miette::Result> { // monomorphization pass let mast = mast::monomorphize(tast)?; @@ -228,7 +229,7 @@ pub fn compile( serde_json::to_string(&mast).unwrap(); // synthesizer pass - CircuitWriter::generate_circuit(mast, backend).into_miette(sources) + CircuitWriter::generate_circuit(mast, backend, disable_safety_check).into_miette(sources) } pub fn generate_witness( diff --git a/src/negative_tests.rs b/src/negative_tests.rs index b50f86f46..1796fe0c8 100644 --- a/src/negative_tests.rs +++ b/src/negative_tests.rs @@ -57,7 +57,7 @@ fn mast_pass(code: &str) -> Result> { fn synthesizer_pass(code: &str) -> Result> { let mast = mast_pass(code); - CircuitWriter::generate_circuit(mast?, R1CS::new()) + CircuitWriter::generate_circuit(mast?, R1CS::new(), false) } #[test] diff --git a/src/tests/examples.rs b/src/tests/examples.rs index 7921a154b..e86d85874 100644 --- a/src/tests/examples.rs +++ b/src/tests/examples.rs @@ -15,12 +15,29 @@ use crate::{ type_checker::TypeChecker, }; +pub struct TestOptions { + ///Disable safety checks + pub disable_safety_check: bool, +} + +impl TestOptions { + pub const fn new(disable_safety_check_arg: bool) -> Self { + Self { + disable_safety_check: disable_safety_check_arg, + } + } +} + +const DEFAULT_OPTIONS: TestOptions = TestOptions::new(false); +const DISABLE_SAFETY_CHECK_OPTIONS: TestOptions = TestOptions::new(true); + fn test_file( file_name: &str, public_inputs: &str, private_inputs: &str, expected_public_output: Vec<&str>, backend: BackendKind, + options: TestOptions, ) -> miette::Result<()> { let version = env!("CARGO_MANIFEST_DIR"); let prefix_examples = Path::new(version).join("examples"); @@ -58,7 +75,13 @@ fn test_file( ) .unwrap(); - let compiled_circuit = compile(&sources, tast, kimchi_vesta, &mut None)?; + let compiled_circuit = compile( + &sources, + tast, + kimchi_vesta, + &mut None, + options.disable_safety_check, + )?; let (prover_index, verifier_index) = compiled_circuit.compile_to_indexes().unwrap(); @@ -129,7 +152,13 @@ fn test_file( ) .unwrap(); - let compiled_circuit = compile(&sources, tast, r1cs, &mut None)?; + let compiled_circuit = compile( + &sources, + tast, + r1cs, + &mut None, + options.disable_safety_check, + )?; // this should check the constraints let generated_witness = compiled_circuit @@ -195,7 +224,13 @@ fn test_file( ) .unwrap(); - let compiled_circuit = compile(&sources, tast, r1cs, &mut None)?; + let compiled_circuit = compile( + &sources, + tast, + r1cs, + &mut None, + options.disable_safety_check, + )?; // this should check the constraints let generated_witness = compiled_circuit @@ -249,7 +284,14 @@ fn test_arithmetic(#[case] backend: BackendKind) -> miette::Result<()> { let public_inputs = r#"{"public_input": "2"}"#; let private_inputs = r#"{"private_input": "2"}"#; - test_file("arithmetic", public_inputs, private_inputs, vec![], backend)?; + test_file( + "arithmetic", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -267,6 +309,7 @@ fn test_public_output(#[case] backend: BackendKind) -> miette::Result<()> { private_inputs, vec!["8"], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -285,6 +328,7 @@ fn test_lc_return(#[case] backend: BackendKind) -> miette::Result<()> { private_inputs, vec!["2"], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -305,7 +349,14 @@ fn test_poseidon(#[case] backend: BackendKind) -> miette::Result<()> { let public_inputs = &format!(r#"{{"public_input": "{digest_dec}"}}"#); - test_file("poseidon", public_inputs, private_inputs, vec![], backend)?; + test_file( + "poseidon", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -317,7 +368,14 @@ fn test_bool(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{"private_input": false}"#; let public_inputs = r#"{"public_input": true}"#; - test_file("bool", public_inputs, private_inputs, vec![], backend)?; + test_file( + "bool", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -329,7 +387,14 @@ fn test_mutable(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{"xx": "2", "yy": "3"}"#; let public_inputs = r#"{}"#; - test_file("mutable", public_inputs, private_inputs, vec![], backend)?; + test_file( + "mutable", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -341,7 +406,14 @@ fn test_for_loop(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{"private_input": ["2", "3", "4"]}"#; let public_inputs = r#"{"public_input": "9"}"#; - test_file("for_loop", public_inputs, private_inputs, vec![], backend)?; + test_file( + "for_loop", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -353,7 +425,14 @@ fn test_dup_var(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{"private_input": ["1", "2", "2"]}"#; let public_inputs = r#"{"public_input": "10"}"#; - test_file("dup_var", public_inputs, private_inputs, vec![], backend)?; + test_file( + "dup_var", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -365,7 +444,14 @@ fn test_array(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{}"#; let public_inputs = r#"{"public_input": ["1", "2"]}"#; - test_file("array", public_inputs, private_inputs, vec![], backend)?; + test_file( + "array", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -377,7 +463,14 @@ fn test_equals(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{}"#; let public_inputs = r#"{"xx": ["3", "3"]}"#; - test_file("equals", public_inputs, private_inputs, vec![], backend)?; + test_file( + "equals", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -389,7 +482,14 @@ fn test_not_equal(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{}"#; let public_inputs = r#"{"xx": ["1", "2"]}"#; - test_file("not_equal", public_inputs, private_inputs, vec![], backend)?; + test_file( + "not_equal", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -401,7 +501,14 @@ fn test_types(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{}"#; let public_inputs = r#"{"xx": "1", "yy": "2"}"#; - test_file("types", public_inputs, private_inputs, vec![], backend)?; + test_file( + "types", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -420,6 +527,7 @@ fn test_const(#[case] backend: BackendKind) -> miette::Result<()> { private_inputs, expected_public_output, backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -432,7 +540,14 @@ fn test_functions(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{}"#; let public_inputs = r#"{"one": "1"}"#; - test_file("functions", public_inputs, private_inputs, vec![], backend)?; + test_file( + "functions", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -444,7 +559,14 @@ fn test_methods(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{}"#; let public_inputs = r#"{"xx": "1"}"#; - test_file("methods", public_inputs, private_inputs, vec![], backend)?; + test_file( + "methods", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -462,6 +584,7 @@ fn test_types_array(#[case] backend: BackendKind) -> miette::Result<()> { private_inputs, vec![], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -481,6 +604,7 @@ fn test_iterate(#[case] backend: BackendKind) -> miette::Result<()> { private_inputs, expected_public_output, backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -493,7 +617,14 @@ fn test_assignment(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{}"#; let public_inputs = r#"{"xx": "2"}"#; - test_file("assignment", public_inputs, private_inputs, vec![], backend)?; + test_file( + "assignment", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -512,6 +643,7 @@ fn test_augmented_assign(#[case] backend: BackendKind) -> miette::Result<()> { private_inputs, expected_public_output, backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -524,7 +656,14 @@ fn test_if_else(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{}"#; let public_inputs = r#"{"xx": "1"}"#; - test_file("if_else", public_inputs, private_inputs, vec![], backend)?; + test_file( + "if_else", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -536,7 +675,14 @@ fn test_sudoku(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{"solution": { "inner": ["9", "5", "3", "6", "2", "1", "7", "8", "4", "1", "4", "8", "7", "5", "9", "2", "6", "3", "2", "7", "6", "8", "3", "4", "9", "5", "1", "3", "6", "9", "2", "7", "5", "4", "1", "8", "4", "8", "5", "9", "1", "6", "3", "7", "2", "7", "1", "2", "3", "4", "8", "6", "9", "5", "6", "3", "7", "1", "8", "2", "5", "4", "9", "5", "2", "1", "4", "9", "7", "8", "3", "6", "8", "9", "4", "5", "6", "3", "1", "2", "7"] }}"#; let public_inputs = r#"{"grid": { "inner": ["0", "5", "3", "6", "2", "1", "7", "8", "4", "0", "4", "8", "7", "5", "9", "2", "6", "3", "2", "7", "6", "8", "3", "4", "9", "5", "1", "3", "6", "9", "2", "7", "0", "4", "1", "8", "4", "8", "5", "9", "1", "6", "3", "7", "2", "0", "1", "2", "3", "4", "8", "6", "9", "5", "6", "3", "0", "1", "8", "2", "5", "4", "9", "5", "2", "1", "4", "9", "0", "8", "3", "6", "8", "9", "4", "5", "6", "3", "1", "2", "7"] }}"#; - test_file("sudoku", public_inputs, private_inputs, vec![], backend)?; + test_file( + "sudoku", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -548,7 +694,14 @@ fn test_literals(#[case] backend: BackendKind) -> miette::Result<()> { let private_inputs = r#"{}"#; let public_inputs = r#"{"public_input": "42"}"#; - test_file("literals", public_inputs, private_inputs, vec![], backend)?; + test_file( + "literals", + public_inputs, + private_inputs, + vec![], + backend, + DEFAULT_OPTIONS, + )?; Ok(()) } @@ -566,6 +719,7 @@ fn test_public_output_array(#[case] backend: BackendKind) -> miette::Result<()> private_inputs, vec!["8", "2"], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -584,6 +738,7 @@ fn test_types_array_output(#[case] backend: BackendKind) -> miette::Result<()> { private_inputs, vec!["2", "4", "1", "8"], // 2x, y, x, 2y backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -602,6 +757,7 @@ fn test_public_output_bool(#[case] backend: BackendKind) -> miette::Result<()> { private_inputs, vec!["1"], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -620,6 +776,7 @@ fn test_public_output_types(#[case] backend: BackendKind) -> miette::Result<()> private_inputs, vec!["1", "2"], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -638,6 +795,7 @@ fn test_generic_repeated_array(#[case] backend: BackendKind) -> miette::Result<( private_inputs, vec!["1", "1", "1"], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -656,6 +814,7 @@ fn test_generic_array_access(#[case] backend: BackendKind) -> miette::Result<()> private_inputs, vec![], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -674,6 +833,7 @@ fn test_generic_array_nested(#[case] backend: BackendKind) -> miette::Result<()> private_inputs, vec![], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -692,6 +852,7 @@ fn test_generic_fn_multi_init(#[case] backend: BackendKind) -> miette::Result<() private_inputs, vec![], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -710,6 +871,7 @@ fn generic_method_multi_init(#[case] backend: BackendKind) -> miette::Result<()> private_inputs, vec![], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -728,6 +890,7 @@ fn test_generic_for_loop(#[case] backend: BackendKind) -> miette::Result<()> { private_inputs, vec![], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -746,6 +909,7 @@ fn test_generic_builtin_bits(#[case] backend: BackendKind) -> miette::Result<()> private_inputs, vec![], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -764,6 +928,7 @@ fn test_generic_iterator(#[case] backend: BackendKind) -> miette::Result<()> { private_inputs, vec!["1"], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -782,6 +947,7 @@ fn test_generic_nested_func(#[case] backend: BackendKind) -> miette::Result<()> private_inputs, vec!["1", "1", "1"], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -800,6 +966,7 @@ fn test_generic_nested_method(#[case] backend: BackendKind) -> miette::Result<() private_inputs, vec!["1", "1", "1"], backend, + DEFAULT_OPTIONS, )?; Ok(()) @@ -813,7 +980,35 @@ fn test_hint_fn(#[case] backend: BackendKind) -> miette::Result<()> { let public_inputs = r#"{"public_input": "2"}"#; let private_inputs = r#"{"private_input": "2"}"#; - test_file("hint", public_inputs, private_inputs, vec!["8"], backend)?; + test_file( + "hint", + public_inputs, + private_inputs, + vec!["8"], + backend, + DEFAULT_OPTIONS, + )?; + + Ok(()) +} + +#[rstest] +#[case::kimchi_vesta(BackendKind::KimchiVesta(KimchiVesta::new(false)))] +#[case::r1cs_bls(BackendKind::R1csBls12_381(R1CS::new()))] +fn test_unused_variables_with_disabled_safety_check( + #[case] backend: BackendKind, +) -> miette::Result<()> { + let public_inputs = r#"{"xx": "2"}"#; + let private_inputs = r#"{"yy": "1"}"#; + + test_file( + "unused_variables", + public_inputs, + private_inputs, + vec![], + backend, + DISABLE_SAFETY_CHECK_OPTIONS, + )?; Ok(()) } diff --git a/src/tests/modules.rs b/src/tests/modules.rs index 374286ecf..6517cd4b8 100644 --- a/src/tests/modules.rs +++ b/src/tests/modules.rs @@ -124,7 +124,7 @@ fn test_simple_module() -> miette::Result<()> { let kimchi_vesta = KimchiVesta::new(false); // compile - compile(&sources, tast, kimchi_vesta, &mut None)?; + compile(&sources, tast, kimchi_vesta, &mut None, false)?; Ok(()) } diff --git a/src/tests/stdlib/mod.rs b/src/tests/stdlib/mod.rs index b6f3bb33d..278366d40 100644 --- a/src/tests/stdlib/mod.rs +++ b/src/tests/stdlib/mod.rs @@ -80,7 +80,7 @@ fn test_stdlib_code( .unwrap(); let mast = mast::monomorphize(tast)?; - let compiled_circuit = CircuitWriter::generate_circuit(mast, r1cs)?; + let compiled_circuit = CircuitWriter::generate_circuit(mast, r1cs, false)?; // this should check the constraints let generated_witness = compiled_circuit.generate_witness(