diff --git a/proof-input/tests/serialization.rs b/proof-input/tests/serialization.rs index 9e4225a..ae0e147 100644 --- a/proof-input/tests/serialization.rs +++ b/proof-input/tests/serialization.rs @@ -1,20 +1,13 @@ -use plonky2::hash::poseidon::PoseidonHash; -use plonky2::plonk::config::PoseidonGoldilocksConfig; use plonky2_field::goldilocks_field::GoldilocksField; -use proof_input::params::Params; // types used in all tests type F = GoldilocksField; const D: usize = 2; -type H = PoseidonHash; -type C = PoseidonGoldilocksConfig; -#[cfg(test)] -mod serialization_tests { +pub(crate) mod serialization_test_functions { use super::*; - use codex_plonky2_circuits::circuits::sample_cells::{SampleCircuit, SampleCircuitInput}; - use plonky2::plonk::circuit_data::{CircuitConfig, ProverCircuitData, VerifierCircuitData}; - use codex_plonky2_circuits::circuit_trait::Plonky2Circuit; + use codex_plonky2_circuits::circuits::sample_cells::SampleCircuitInput; + use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData}; use proof_input::input_generator::InputGenerator; use proof_input::input_generator::serialization::{export_circ_input_to_json, import_circ_input_from_json}; use std::path::Path; @@ -22,23 +15,25 @@ mod serialization_tests { use plonky2::iop::target::Target; use plonky2::iop::witness::{PartialWitness, WitnessWrite}; use plonky2::plonk::circuit_builder::CircuitBuilder; - use plonky2::plonk::config::PoseidonGoldilocksConfig; + use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, Hasher}; use plonky2::plonk::proof::ProofWithPublicInputs; - use plonky2_field::goldilocks_field::GoldilocksField; use plonky2_field::types::Field; - use codex_plonky2_circuits::serialization::{export_circuit_data, export_proof_with_pi, import_proof_with_pi, import_prover_circuit_data, import_targets, import_verifier_circuit_data}; + use serde::Serialize; + use codex_plonky2_circuits::serialization::{export_circuit_data, export_proof_with_pi, import_circuit_data, import_proof_with_pi, import_targets}; - #[test] - fn test_export_and_import_circuit_data_roundtrip() -> anyhow::Result<()> { - use serde::Serialize; + pub(crate) const CIRC_BASE_PATH: &str = "../output/test/circuit/"; - #[derive(Clone, Debug, PartialEq, Serialize, serde::Deserialize)] - struct DummyTargets { - a: Target, - } + #[derive(Clone, Debug, PartialEq, Serialize, serde::Deserialize)] + struct DummyTargets { + a: Target, + } - let conf = CircuitConfig::standard_recursion_config(); - let mut builder = CircuitBuilder::::new(conf); + fn dummy_circuit + Serialize + Default + 'static>( + config: CircuitConfig, + ) -> anyhow::Result<(CircuitData, ProofWithPublicInputs, DummyTargets)> where + >::Hasher: AlgebraicHasher, + { + let mut builder = CircuitBuilder::::new(config); for _ in 0..128 { builder.add_gate(NoopGate, vec![]); } @@ -49,49 +44,53 @@ mod serialization_tests { pw.set_target(t, F::ZERO).expect("faulty assign"); let dummy_inner_proof = dummy_circuit.prove(pw).unwrap(); assert!(dummy_circuit.verify(dummy_inner_proof.clone()).is_ok()); - let dummy_t = DummyTargets{a: t}; - let base_output = Path::new("../output/sampling_circ"); + Ok((dummy_circuit, dummy_inner_proof, dummy_t)) + } + + pub(crate) fn test_export_and_import_circuit_data + Serialize + Default + 'static>( + config: CircuitConfig, + ) -> anyhow::Result<()> where + >::Hasher: AlgebraicHasher, + { + + let (dummy_circuit, dummy_inner_proof, dummy_t) = dummy_circuit(config)?; + + let base_output = Path::new(CIRC_BASE_PATH); export_circuit_data::(dummy_circuit, &dummy_t, base_output)?; - let imported_prover: ProverCircuitData = - import_prover_circuit_data(base_output)?; - let imported_verifier: VerifierCircuitData = - import_verifier_circuit_data(base_output)?; + let imported_circuit: CircuitData = import_circuit_data(base_output)?; let imported_target: DummyTargets = import_targets(base_output)?; + assert!( + imported_circuit.verify(dummy_inner_proof).is_ok(), + "imported circuit data failed to verify valid proof" + ); let mut pw = PartialWitness::new(); pw.set_target(imported_target.a, F::ZERO).expect("faulty assign"); - let proof_with_pis = imported_prover.prove(pw).unwrap(); + let new_proof = imported_circuit.prove(pw).unwrap(); assert!( - imported_verifier.verify(proof_with_pis).is_ok(), - "imported verifier failed to verify" + imported_circuit.verify(new_proof).is_ok(), + "imported target failed usage" ); Ok(()) } - #[test] - fn test_export_and_import_proof_with_pi() -> anyhow::Result<()> { - let conf = CircuitConfig::standard_recursion_config(); - let mut builder = CircuitBuilder::::new(conf); - for _ in 0..128 { - builder.add_gate(NoopGate, vec![]); - } - let t = builder.add_virtual_public_input(); + pub(crate) fn test_export_and_import_proof_with_pi + Serialize + Default + 'static>( + config: CircuitConfig, + ) -> anyhow::Result<()> where + >::Hasher: AlgebraicHasher, + { + let (dummy_circuit, dummy_inner_proof, _) = dummy_circuit(config)?; - let dummy_circuit = builder.build::(); - let mut pw = PartialWitness::new(); - pw.set_target(t, F::ZERO).expect("faulty assign"); - let dummy_inner_proof = dummy_circuit.prove(pw).unwrap(); - assert!(dummy_circuit.verify(dummy_inner_proof.clone()).is_ok()); - - let base_output = Path::new("../output/sampling_circ"); + let base_output = Path::new(CIRC_BASE_PATH); export_proof_with_pi(&dummy_inner_proof, base_output)?; let imported_proof: ProofWithPublicInputs = import_proof_with_pi(base_output)?; + assert_eq!(dummy_inner_proof.clone(), imported_proof.clone(), "proofs are not equal"); assert!( dummy_circuit.verify(imported_proof).is_ok(), "Imported proof failed verification" @@ -100,101 +99,110 @@ mod serialization_tests { Ok(()) } - // Test to generate the JSON file - #[test] - fn test_export_circ_input_to_json() -> anyhow::Result<()> { - // Create InputGenerator - let input_gen = InputGenerator::::default(); - // Export the circuit input to JSON - input_gen.generate_and_export_circ_input_to_json( "../output/test/")?; - - println!("Circuit input exported to input.json"); - - Ok(()) - } - - #[test] - fn test_import_circ_input_from_json() -> anyhow::Result<()> { - // Import the circuit input from the JSON file - // NOTE: MAKE SURE THE FILE EXISTS - let _circ_input: SampleCircuitInput = import_circ_input_from_json("../output/test/")?; - println!("circuit input imported successfully"); - - Ok(()) - } - // export the circuit input and then import it and checks equality - #[test] - fn test_export_import_circ_input() -> anyhow::Result<()> { + pub(crate) fn test_export_import_circ_input>() -> anyhow::Result<()> { // Create InputGenerator let input_gen = InputGenerator::::default(); // Export the circuit input to JSON let original_circ_input = input_gen.gen_testing_circuit_input(); - export_circ_input_to_json(original_circ_input.clone(), "../output/test/")?; + export_circ_input_to_json(original_circ_input.clone(), CIRC_BASE_PATH)?; println!("circuit input exported to input.json"); // Import the circuit input from JSON - let imported_circ_input: SampleCircuitInput = import_circ_input_from_json("../output/test/")?; + let imported_circ_input: SampleCircuitInput = import_circ_input_from_json(CIRC_BASE_PATH)?; println!("circuit input imported from input.json"); // Compare the original and imported circuit input assert_eq!(original_circ_input, imported_circ_input, "circuit input are not equal"); - // cleanup: Remove the generated JSON file - // fs::remove_file("input.json")?; - println!("Test passed: Original and imported circuit input are equal."); Ok(()) } - // reads the json input from file and runs the circuit +} + +#[cfg(test)] +mod poseidon_serialization_tests { + use plonky2::hash::poseidon::PoseidonHash; + use plonky2::plonk::circuit_data::CircuitConfig; + use plonky2::plonk::config::PoseidonGoldilocksConfig; + use super::serialization_test_functions::*; + + type H = PoseidonHash; + pub type C = PoseidonGoldilocksConfig; + #[test] - fn test_read_json_and_run_circuit() -> anyhow::Result<()> { - // Create the circuit - let circuit_params = Params::default().circuit_params; - - let circ = SampleCircuit::::new(circuit_params.clone()); - let (targets, data) = circ.build_with_standard_config()?; - - let verifier_data: VerifierCircuitData = data.verifier_data(); - let prover_data: ProverCircuitData = data.prover_data(); - println!("circuit size = {:?}", verifier_data.common.degree_bits()); - - // Import the circuit input from JSON - let imported_circ_input: SampleCircuitInput = import_circ_input_from_json("../output/test/")?; - println!("circuit input imported from input.json"); - - let proof = circ.prove(&targets, &imported_circ_input, &prover_data)?; - - // Verify the proof - assert!( - verifier_data.verify(proof).is_ok(), - "Merkle proof verification failed" - ); - - Ok(()) + fn test_poseidon_export_import_circ_input() -> anyhow::Result<()> { + test_export_import_circ_input::() } - // reads the json input and verify (non-circuit) - // NOTE: expects that the json input proof uses the default params #[test] - fn test_read_json_and_verify() -> anyhow::Result<()> { - // Create InputGenerator - let input_gen = InputGenerator::::default(); + fn test_poseidon_export_and_import_circuit_data() -> anyhow::Result<()> { + let config = CircuitConfig::standard_recursion_config(); + test_export_and_import_circuit_data::(config) + } - // Import the circuit input from JSON - let imported_circ_input: SampleCircuitInput = import_circ_input_from_json("../output/test/")?; - println!("circuit input imported from input.json"); + #[test] + fn test_poseidon_export_and_import_proof_with_pi() -> anyhow::Result<()> { + let config = CircuitConfig::standard_recursion_config(); + test_export_and_import_proof_with_pi::(config) + } +} - // Verify the proof - let ver = input_gen.verify_circuit_input(imported_circ_input); - assert!( - ver, - "Merkle proof verification failed" - ); +#[cfg(test)] +mod poseidon2_serialization_tests { + use plonky2::plonk::circuit_data::CircuitConfig; + use plonky2::plonk::config::PoseidonGoldilocksConfig; + use plonky2_poseidon2::poseidon2_hash::poseidon2::Poseidon2Hash; + use super::serialization_test_functions::*; - Ok(()) + type H = Poseidon2Hash; + pub type C = PoseidonGoldilocksConfig; + + #[test] + fn test_poseidon_export_import_circ_input() -> anyhow::Result<()> { + test_export_import_circ_input::() + } + + #[test] + fn test_poseidon_export_and_import_circuit_data() -> anyhow::Result<()> { + let config = CircuitConfig::standard_recursion_config(); + test_export_and_import_circuit_data::(config) + } + + #[test] + fn test_poseidon_export_and_import_proof_with_pi() -> anyhow::Result<()> { + let config = CircuitConfig::standard_recursion_config(); + test_export_and_import_proof_with_pi::(config) + } +} + +#[cfg(test)] +mod monolith_serialization_tests { + use plonky2::plonk::circuit_data::CircuitConfig; + use plonky2::plonk::config::PoseidonGoldilocksConfig; + use plonky2_monolith::monolith_hash::MonolithHash; + use super::serialization_test_functions::*; + + type H = MonolithHash; + pub type C = PoseidonGoldilocksConfig; + + #[test] + fn test_poseidon_export_import_circ_input() -> anyhow::Result<()> { + test_export_import_circ_input::() + } + + #[test] + fn test_poseidon_export_and_import_circuit_data() -> anyhow::Result<()> { + let config = CircuitConfig::standard_recursion_config(); + test_export_and_import_circuit_data::(config) + } + + #[test] + fn test_poseidon_export_and_import_proof_with_pi() -> anyhow::Result<()> { + let config = CircuitConfig::standard_recursion_config(); + test_export_and_import_proof_with_pi::(config) } } \ No newline at end of file