diff --git a/proof-input/src/gen_input.rs b/proof-input/src/gen_input.rs index d787901..37554d3 100644 --- a/proof-input/src/gen_input.rs +++ b/proof-input/src/gen_input.rs @@ -11,7 +11,6 @@ use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData}; use plonky2::plonk::proof::ProofWithPublicInputs; -use codex_plonky2_circuits::circuits::params::CircuitParams; use crate::data_structs::DatasetTree; use crate::sponge::hash_bytes_no_padding; use crate::params::{C, D, F, HF}; @@ -220,12 +219,8 @@ pub fn get_m_circ_input(params: InputParams) -> [SampleCircuitIn mod tests { use std::time::Instant; use super::*; - use plonky2::plonk::circuit_data::CircuitConfig; - use plonky2::iop::witness::PartialWitness; - use plonky2::plonk::circuit_builder::CircuitBuilder; - use codex_plonky2_circuits::circuits::params::CircuitParams; + use codex_plonky2_circuits::circuit_helper::Plonky2Circuit; use codex_plonky2_circuits::circuits::sample_cells::SampleCircuit; - // use crate::params::{C, D, F}; // Test sample cells (non-circuit) #[test] @@ -241,37 +236,26 @@ mod tests { // get input let mut params = Params::default(); let mut input_params = params.input_params; - input_params.n_samples = 10; - let circ_input = gen_testing_circuit_input::(&input_params); - - // Create the circuit - let config = CircuitConfig::standard_recursion_config(); - let mut builder = CircuitBuilder::::new(config); - let mut circuit_params = params.circuit_params; + input_params.n_samples = 10; circuit_params.n_samples = 10; + let circ_input = gen_testing_circuit_input::(&input_params); // build the circuit let circ = SampleCircuit::::new(circuit_params.clone()); - let mut targets = circ.sample_slot_circuit_with_public_input(&mut builder)?; - - // Create a PartialWitness and assign - let mut pw = PartialWitness::new(); - - // assign a witness - circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input)?; - - // Build the circuit - let data = builder.build::(); + let (targets, data) = circ.build_with_standard_config()?; println!("circuit size = {:?}", data.common.degree_bits()); - // Prove the circuit with the assigned witness + // separate the prover and verifier + let verifier_data = data.verifier_data(); + let prover_data = data.prover_data(); + + // Prove the circuit using the circuit input let start_time = Instant::now(); - let proof_with_pis = data.prove(pw)?; + let proof_with_pis: ProofWithPublicInputs = circ.prove(&targets, &circ_input, &prover_data)?; println!("prove_time = {:?}", start_time.elapsed()); // Verify the proof - let verifier_data = data.verifier_data(); assert!( verifier_data.verify(proof_with_pis).is_ok(), "Merkle proof verification failed" diff --git a/proof-input/src/merkle_tree/merkle_circuit.rs b/proof-input/src/merkle_tree/merkle_circuit.rs index 83a27fa..c91d196 100644 --- a/proof-input/src/merkle_tree/merkle_circuit.rs +++ b/proof-input/src/merkle_tree/merkle_circuit.rs @@ -203,7 +203,7 @@ mod tests { // create a PartialWitness and assign let mut pw = PartialWitness::new(); assign_witness(&mut pw, &mut targets, circuit_input)?; - pw.set_hash_target(expected_root, tree.root().unwrap()); + pw.set_hash_target(expected_root, tree.root().unwrap())?; // build the circuit let data = builder.build::(); @@ -290,7 +290,7 @@ mod tests { }; assign_witness(&mut pw, &mut targets, circuit_input)?; - pw.set_hash_target(expected_root_target, expected_root); + pw.set_hash_target(expected_root_target, expected_root)?; let proof_with_pis = data.prove(pw)?; diff --git a/proof-input/src/merkle_tree/merkle_safe.rs b/proof-input/src/merkle_tree/merkle_safe.rs index f221042..8408af8 100644 --- a/proof-input/src/merkle_tree/merkle_safe.rs +++ b/proof-input/src/merkle_tree/merkle_safe.rs @@ -193,7 +193,7 @@ impl< let mut i = 0; for p in &path { - let bottom = if(i==0){ + let bottom = if i==0 { KEY_BOTTOM_LAYER }else{ KEY_NONE diff --git a/proof-input/src/recursion/uniform.rs b/proof-input/src/recursion/uniform.rs index de09490..042b98c 100644 --- a/proof-input/src/recursion/uniform.rs +++ b/proof-input/src/recursion/uniform.rs @@ -2,24 +2,22 @@ #[cfg(test)] mod tests { - use plonky2::iop::witness::{PartialWitness}; - use plonky2::plonk::circuit_builder::CircuitBuilder; - use plonky2::plonk::circuit_data::{CircuitConfig}; use plonky2::plonk::config::{ GenericConfig}; use plonky2::plonk::proof::{ProofWithPublicInputs}; + use codex_plonky2_circuits::circuit_helper::Plonky2Circuit; use codex_plonky2_circuits::circuits::sample_cells::SampleCircuit; use crate::params::{F, D, C, HF}; use crate::gen_input::gen_testing_circuit_input; use crate::params::Params; use codex_plonky2_circuits::recursion::uniform::{tree::TreeRecursion}; - use codex_plonky2_circuits::recursion::uniform::pi_verifier::PublicInputVerificationCircuit; + use codex_plonky2_circuits::recursion::uniform::pi_verifier::{PublicInputVerificationCircuit, PublicInputVerificationInput}; use codex_plonky2_circuits::recursion::uniform::tree::get_hash_of_verifier_data; #[test] fn test_uniform_recursion() -> anyhow::Result<()> { - let config = CircuitConfig::standard_recursion_config(); - let mut sampling_builder = CircuitBuilder::::new(config); + // total number of proofs to aggregate + const T:usize = 4; //------------ sampling inner circuit ---------------------- // Circuit that does the sampling - 100 samples @@ -28,27 +26,29 @@ mod tests { params.circuit_params.n_samples = 100; let one_circ_input = gen_testing_circuit_input::(¶ms.input_params); let samp_circ = SampleCircuit::::new(params.circuit_params); - let inner_tar = samp_circ.sample_slot_circuit_with_public_input(&mut sampling_builder)?; - // get generate a sampling proof - let mut pw = PartialWitness::::new(); - samp_circ.sample_slot_assign_witness(&mut pw,&inner_tar,&one_circ_input)?; - let inner_data = sampling_builder.build::(); - println!("sampling circuit degree bits = {:?}", inner_data.common.degree_bits()); - let inner_proof = inner_data.prove(pw)?; + let (inner_tar, inner_data) = samp_circ.build_with_standard_config()?; - let num_of_proofs = 4; - let proofs: Vec> = (0..num_of_proofs).map(|i| inner_proof.clone()).collect(); + let inner_verifier_data = inner_data.verifier_data(); + let inner_prover_data = inner_data.prover_data(); + + println!("sampling circuit degree bits = {:?}", inner_verifier_data.common.degree_bits()); + let inner_proof = samp_circ.prove(&inner_tar, &one_circ_input, &inner_prover_data)?; + + let proofs: Vec> = (0..T).map(|i| inner_proof.clone()).collect(); // ------------------- tree -------------------- + // 2-to-1 tree aggregation const N: usize = 1; const M: usize = 2; - let mut tree = TreeRecursion::::build(inner_data.common.clone(), inner_data.verifier_only.clone())?; + let mut tree = TreeRecursion::::build_with_standard_config(inner_verifier_data.common.clone(), inner_verifier_data.verifier_only.clone())?; + // aggregate - no compression let root = tree.prove_tree(&proofs)?; println!("pub input size = {}", root.public_inputs.len()); println!("proof size = {:?} bytes", root.to_bytes().len()); + // aggregate with compression let root_compressed = tree.prove_tree_and_compress(&proofs)?; println!("pub input size (compressed) = {}", root_compressed.public_inputs.len()); println!("proof size compressed = {:?} bytes", root_compressed.to_bytes().len()); @@ -72,8 +72,10 @@ mod tests { #[test] fn test_pi_verifier() -> anyhow::Result<()> { - let config = CircuitConfig::standard_recursion_config(); - let mut sampling_builder = CircuitBuilder::::new(config); + // total number of proofs to aggregate + const T:usize = 4; + // 9 field elems as public inputs in the sampling circuit + const K:usize = 9; //------------ sampling inner circuit ---------------------- // Circuit that does the sampling - 100 samples @@ -82,25 +84,22 @@ mod tests { params.circuit_params.n_samples = 100; let one_circ_input = gen_testing_circuit_input::(¶ms.input_params); let samp_circ = SampleCircuit::::new(params.circuit_params); - let inner_tar = samp_circ.sample_slot_circuit_with_public_input(&mut sampling_builder)?; - // get generate a sampling proof - let mut pw = PartialWitness::::new(); - samp_circ.sample_slot_assign_witness(&mut pw,&inner_tar,&one_circ_input)?; - let inner_data = sampling_builder.build::(); - println!("sampling circuit degree bits = {:?}", inner_data.common.degree_bits()); - let inner_proof = inner_data.prove(pw)?; + let (inner_tar, inner_data) = samp_circ.build_with_standard_config()?; + + let inner_verifier_data = inner_data.verifier_data(); + let inner_prover_data = inner_data.prover_data(); + + // get generate a sampling proof + println!("sampling circuit degree bits = {:?}", inner_verifier_data.common.degree_bits()); + let inner_proof = samp_circ.prove(&inner_tar, &one_circ_input, &inner_prover_data)?; - // 9 field elems as public inputs in the sampling circuit - const K:usize = 9; - // change the following as needed. - const T: usize = 4; let proofs: Vec> = (0..T).map(|i| inner_proof.clone()).collect(); // ------------------- tree -------------------- const N: usize = 1; const M: usize = 2; - let mut tree = TreeRecursion::::build(inner_data.common.clone(), inner_data.verifier_only.clone())?; + let mut tree = TreeRecursion::::build_with_standard_config(inner_verifier_data.common.clone(), inner_verifier_data.verifier_only.clone())?; let root = tree.prove_tree(&proofs)?; println!("pub input size = {}", root.public_inputs.len()); @@ -117,18 +116,19 @@ mod tests { let pi_verifier_circ = PublicInputVerificationCircuit::::new(tree.get_node_common_data(), tree.get_node_verifier_data().verifier_only); - let config = CircuitConfig::standard_recursion_config(); - let mut builder = CircuitBuilder::::new(config); - let pi_tarq = pi_verifier_circ.build(&mut builder)?; - - let pi_circ_data = builder.build::(); + let (pi_tarq, pi_circ_data) = pi_verifier_circ.build_with_standard_config()?; println!("PI verifier circuit degree bits = {:?}", pi_circ_data.common.degree_bits()); - let mut pw = PartialWitness::::new(); + let pi_circ_input = PublicInputVerificationInput{ + inner_proof:root, + inner_pub_inputs_vals: inner_pi.clone() + }; - pi_verifier_circ.assign_targets(&mut pw, &pi_tarq, root, inner_pi.clone())?; + let pi_circ_verifier_data = pi_circ_data.verifier_data(); + let pi_circ_prover_data = pi_circ_data.prover_data(); + + let proof =pi_verifier_circ.prove(&pi_tarq, &pi_circ_input, &pi_circ_prover_data)?; - let proof = pi_circ_data.prove(pw)?; println!("pub input size = {}", proof.public_inputs.len()); println!("proof size = {:?} bytes", proof.to_bytes().len()); @@ -150,7 +150,7 @@ mod tests { assert!( - pi_circ_data.verify(proof).is_ok(), + pi_circ_verifier_data.verify(proof).is_ok(), "pi-verifier proof verification failed" ); diff --git a/proof-input/src/serialization/json.rs b/proof-input/src/serialization/json.rs index 5a5b41b..df39991 100644 --- a/proof-input/src/serialization/json.rs +++ b/proof-input/src/serialization/json.rs @@ -10,12 +10,12 @@ use plonky2_field::extension::Extendable; use plonky2_field::types::Field; use plonky2_poseidon2::poseidon2_hash::poseidon2::Poseidon2; use codex_plonky2_circuits::circuits::sample_cells::SampleCircuitInput; -use plonky2::plonk::proof::CompressedProofWithPublicInputs; +use plonky2::plonk::proof::ProofWithPublicInputs; use serde_json::to_writer_pretty; // Function to export proof with public input to json file fn export_proof_with_pi_to_json( - instance: &CompressedProofWithPublicInputs, + instance: &ProofWithPublicInputs, path: &str, ) -> io::Result<()> where @@ -50,7 +50,8 @@ mod tests { use codex_plonky2_circuits::circuits::sample_cells::SampleCircuit; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; - use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData}; + use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData, ProverCircuitData, VerifierCircuitData}; + use codex_plonky2_circuits::circuit_helper::Plonky2Circuit; use plonky2_poseidon2::serialization::{DefaultGateSerializer, DefaultGeneratorSerializer}; use crate::gen_input::verify_circuit_input; use crate::serialization::circuit_input::{export_circ_input_to_json, generate_and_export_circ_input_to_json, import_circ_input_from_json}; @@ -72,7 +73,7 @@ mod tests { 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("input.json")?; + let _circ_input: SampleCircuitInput = import_circ_input_from_json("input.json")?; println!("circuit input imported successfully"); Ok(()) @@ -108,36 +109,24 @@ mod tests { #[test] fn test_read_json_and_run_circuit() -> anyhow::Result<()> { // Create the circuit - let config = CircuitConfig::standard_recursion_config(); - let mut builder = CircuitBuilder::::new(config); - let circuit_params = Params::default().circuit_params; let circ = SampleCircuit::::new(circuit_params.clone()); - let mut targets = circ.sample_slot_circuit_with_public_input(&mut builder)?; + let (targets, data) = circ.build_with_standard_config()?; - // Create a PartialWitness and assign - let mut pw = PartialWitness::new(); + 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("input.json")?; println!("circuit input imported from input.json"); - circ.sample_slot_assign_witness(&mut pw, &targets, &imported_circ_input)?; - - // Build the circuit - let data = builder.build::(); - println!("circuit size = {:?}", data.common.degree_bits()); - - // Prove the circuit with the assigned witness - let start_time = Instant::now(); - let proof_with_pis = data.prove(pw)?; - println!("prove_time = {:?}", start_time.elapsed()); + let proof = circ.prove(&targets, &imported_circ_input, &prover_data)?; // Verify the proof - let verifier_data = data.verifier_data(); assert!( - verifier_data.verify(proof_with_pis).is_ok(), + verifier_data.verify(proof).is_ok(), "Merkle proof verification failed" ); @@ -171,27 +160,20 @@ mod tests { let input_params = params.input_params; // Create the circuit - let config = CircuitConfig::standard_recursion_config(); - let mut builder = CircuitBuilder::::new(config); - let circuit_params = params.circuit_params; let circ = SampleCircuit::::new(circuit_params.clone()); - let mut targets = circ.sample_slot_circuit_with_public_input(&mut builder)?; + let (targets, data) = circ.build_with_standard_config()?; + println!("circuit size = {:?}", data.common.degree_bits()); - // Create a PartialWitness and assign - let mut pw = PartialWitness::new(); + let verifier_data: VerifierCircuitData = data.verifier_data(); + let prover_data: ProverCircuitData = data.prover_data(); // gen circ input let imported_circ_input: SampleCircuitInput = gen_testing_circuit_input::(&input_params); - circ.sample_slot_assign_witness(&mut pw, &targets, &imported_circ_input)?; - - // Build the circuit - let data = builder.build::(); - println!("circuit size = {:?}", data.common.degree_bits()); let gate_serializer = DefaultGateSerializer; let generator_serializer =DefaultGeneratorSerializer::::default(); - let data_bytes = data.to_bytes(&gate_serializer, &generator_serializer).unwrap(); + let data_bytes = prover_data.to_bytes(&gate_serializer, &generator_serializer).unwrap(); let file_path = "circ_data.bin"; // Write data to the file @@ -200,15 +182,14 @@ mod tests { // Read data back from the file let read_data = read_bytes_from_file(file_path).unwrap(); - let data = CircuitData::::from_bytes(&read_data, &gate_serializer, &generator_serializer).unwrap(); + let prover_data = ProverCircuitData::::from_bytes(&read_data, &gate_serializer, &generator_serializer).unwrap(); // Prove the circuit with the assigned witness let start_time = Instant::now(); - let proof_with_pis = data.prove(pw)?; + let proof_with_pis = circ.prove(&targets, &imported_circ_input, &prover_data)?; println!("prove_time = {:?}", start_time.elapsed()); // Verify the proof - let verifier_data = data.verifier_data(); assert!( verifier_data.verify(proof_with_pis).is_ok(), "Merkle proof verification failed" @@ -224,37 +205,28 @@ mod tests { let input_params = params.input_params; // Create the circuit - let config = CircuitConfig::standard_recursion_config(); - let mut builder = CircuitBuilder::::new(config); - let circuit_params = params.circuit_params; let circ = SampleCircuit::::new(circuit_params.clone()); - let mut targets = circ.sample_slot_circuit_with_public_input(&mut builder)?; + let (targets, data) = circ.build_with_standard_config()?; + println!("circuit size = {:?}", data.common.degree_bits()); - // Create a PartialWitness and assign - let mut pw = PartialWitness::new(); + let verifier_data: VerifierCircuitData = data.verifier_data(); + let prover_data: ProverCircuitData = data.prover_data(); // gen circ input let imported_circ_input: SampleCircuitInput = gen_testing_circuit_input::(&input_params); - circ.sample_slot_assign_witness(&mut pw, &targets, &imported_circ_input)?; - - // Build the circuit - let data = builder.build::(); - println!("circuit size = {:?}", data.common.degree_bits()); // Prove the circuit with the assigned witness let start_time = Instant::now(); - let proof_with_pis = data.prove(pw)?; + let proof_with_pis = circ.prove(&targets, &imported_circ_input, &prover_data)?; println!("prove_time = {:?}", start_time.elapsed()); println!("Proof size: {} bytes", proof_with_pis.to_bytes().len()); - let compressed_proof_with_pi = data.compress(proof_with_pis.clone())?; let filename = "proof_with_pi.json"; - export_proof_with_pi_to_json(&compressed_proof_with_pi,filename)?; - println!("Proof size: {} bytes", compressed_proof_with_pi.to_bytes().len()); + export_proof_with_pi_to_json(&proof_with_pis,filename)?; + println!("Proof size: {} bytes", proof_with_pis.to_bytes().len()); // Verify the proof - let verifier_data = data.verifier_data(); assert!( verifier_data.verify(proof_with_pis).is_ok(), "Merkle proof verification failed" diff --git a/proof-input/src/sponge.rs b/proof-input/src/sponge.rs index 450afa0..b71b841 100644 --- a/proof-input/src/sponge.rs +++ b/proof-input/src/sponge.rs @@ -35,8 +35,8 @@ pub fn hash_n_to_m_with_padding< let domsep_value = F::from_canonical_u64(rate as u64 + 256 * 12 + 65536 * 63); perm.set_elt(domsep_value, 8); - let N = inputs.len(); - let num_chunks = (N + rate) / rate; // Calculate number of chunks with 10* padding + let input_n = inputs.len(); + let num_chunks = (input_n + rate) / rate; // Calculate number of chunks with 10* padding let mut input_iter = inputs.iter(); // Process all chunks except the last one @@ -59,7 +59,7 @@ pub fn hash_n_to_m_with_padding< } // Process the last chunk with 10* padding - let rem = num_chunks * rate - N; // Number of padding elements (0 < rem <= rate) + let rem = num_chunks * rate - input_n; // Number of padding elements (0 < rem <= rate) let ofs = rate - rem; // Offset where padding starts let mut last_chunk = Vec::with_capacity(rate); @@ -123,7 +123,6 @@ pub fn hash_bytes_to_m_no_padding< let rate = P::RATE; let width = P::WIDTH; // rate + capacity let zero = F::ZERO; - let one = F::ONE; let mut perm = P::new(core::iter::repeat(zero).take(width)); // Set the domain separator at index 8