diff --git a/workflow/.gitignore b/workflow/.gitignore index a3547b9..88ac17f 100644 --- a/workflow/.gitignore +++ b/workflow/.gitignore @@ -11,3 +11,7 @@ pgo-data.profdata # MacOS nuisances .DS_Store + +# circuit files +/prover_data +/verifier_data \ No newline at end of file diff --git a/workflow/Cargo.toml b/workflow/Cargo.toml index 61a810e..2bb125e 100644 --- a/workflow/Cargo.toml +++ b/workflow/Cargo.toml @@ -28,7 +28,7 @@ parallel = ["plonky2/parallel"] [[bin]] name = "prove_and_verify" -path = "src/bin/prove_and_verify.rs" +path = "src/bin/verify.rs" [[bin]] name = "gen_input" @@ -42,6 +42,10 @@ path = "src/bin/build_circ.rs" name = "prove" path = "src/bin/prove.rs" +[[bin]] +name = "verify" +path = "src/bin/verify.rs" + [[bin]] name = "aggregate" path = "src/bin/aggregate.rs" diff --git a/workflow/README.md b/workflow/README.md index 2d1722c..5fbb307 100644 --- a/workflow/README.md +++ b/workflow/README.md @@ -20,7 +20,7 @@ This crate can be used to: - [`prove`](./src/bin/prove.rs) contains the main function to generated input with the given params as environment variables. -- [`prove_and_verify`](./src/bin/prove_and_verify.rs) contains the main function to generated input with the given params as environment variables. +- [`prove_and_verify`](./src/bin/verify) contains the main function to generated input with the given params as environment variables. - [`aggregate`](./src/bin/aggregate.rs) contains the main function to generate the sampling proofs and aggregate `k` of them. @@ -119,7 +119,7 @@ Make sure that you generate the circuit input prior to this so that you have the ```bash sudo bash ./scripts/prove_and_verify.sh ``` -To inspect the source code, see [`prove_and_verify`](./src/bin/prove_and_verify.rs). +To inspect the source code, see [`prove_and_verify`](./src/bin/verify). ### Generate K Proofs and aggregate them To do this, you can run the following script: diff --git a/workflow/scripts/build_circuit.sh b/workflow/scripts/build_circuit.sh index 82828a6..1190fa9 100755 --- a/workflow/scripts/build_circuit.sh +++ b/workflow/scripts/build_circuit.sh @@ -10,5 +10,5 @@ cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; } cargo build --release || { echo "build_circuit.sh: cargo build failed"; exit 101; } # Run the Rust executable -cargo run --bin build_circ || { echo "build_circuit.sh: cargo run failed"; exit 102; } +cargo run --bin build_circ --features "parallel" || { echo "build_circuit.sh: cargo run failed"; exit 102; } diff --git a/workflow/scripts/circ_params.sh b/workflow/scripts/circ_params.sh index 299129b..bae02b0 100755 --- a/workflow/scripts/circ_params.sh +++ b/workflow/scripts/circ_params.sh @@ -4,4 +4,4 @@ export MAX_DEPTH=32 # maximum depth of the slot tree export MAX_LOG2_N_SLOTS=8 # Depth of the dataset tree = ceiling_log2(max_slots) export BLOCK_TREE_DEPTH=5 # depth of the mini tree (block tree) export N_FIELD_ELEMS_PER_CELL=272 # number of field elements per cell -export N_SAMPLES=5 # number of samples to prove \ No newline at end of file +export N_SAMPLES=100 # number of samples to prove \ No newline at end of file diff --git a/workflow/scripts/gen_input.sh b/workflow/scripts/gen_input.sh index e174f5c..7eb5afa 100755 --- a/workflow/scripts/gen_input.sh +++ b/workflow/scripts/gen_input.sh @@ -10,4 +10,4 @@ cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; } cargo build --release || { echo "gen_input.sh: cargo build failed"; exit 101; } # Run the Rust executable -cargo run --bin gen_input || { echo "gen_input.sh: cargo run failed"; exit 102; } +cargo run --bin gen_input --features "parallel" || { echo "gen_input.sh: cargo run failed"; exit 102; } diff --git a/workflow/scripts/prove.sh b/workflow/scripts/prove.sh index cda727c..dcdf01f 100755 --- a/workflow/scripts/prove.sh +++ b/workflow/scripts/prove.sh @@ -10,4 +10,4 @@ cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; } cargo build --release || { echo "prove.sh: cargo build failed"; exit 101; } # Run the Rust executable -cargo run --bin prove || { echo "prove.sh: cargo run failed"; exit 102; } +cargo run --bin prove --features "parallel" || { echo "prove.sh: cargo run failed"; exit 102; } diff --git a/workflow/scripts/prove_and_verify.sh b/workflow/scripts/prove_and_verify.sh index 5df856d..6e70ae7 100755 --- a/workflow/scripts/prove_and_verify.sh +++ b/workflow/scripts/prove_and_verify.sh @@ -1,13 +1,42 @@ #!/bin/bash -# Source the parameters from params.sh +# Source the parameters +source ./params.sh source ./circ_params.sh # Change to the parent directory of the script cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; } # Build -cargo build --release || { echo "prove_and_verify.sh: cargo build failed"; exit 101; } +cargo build --release > /dev/null 2>&1 || { echo "prove_and_verify.sh: cargo build failed"; exit 101; } + +# Run all steps +echo "START" + +echo "Generating Input" +start=$(date +%s) +cargo run --bin gen_input --features "parallel" > /dev/null 2>&1 || { echo "gen_input.sh: cargo run failed"; exit 102; } +end=$(date +%s) +echo "Generating Input took $((end - start)) seconds." + +echo "Building the circuit" +start=$(date +%s) +cargo run --bin build_circ --features "parallel" > /dev/null 2>&1 || { echo "build_circuit.sh: cargo run failed"; exit 102; } +end=$(date +%s) +echo "Building the circuit took $((end - start)) seconds." + +echo "Generating a proof" +start=$(date +%s) +cargo run --bin prove --features "parallel" > /dev/null 2>&1 || { echo "prove.sh: cargo run failed"; exit 102; } +end=$(date +%s) +echo "Generating a proof took $((end - start)) seconds." + +echo "Verifying the proof" +start=$(date +%s) +cargo run --bin verify --features "parallel" > /dev/null 2>&1 || { echo "verify.sh: cargo run failed"; exit 102; } +end=$(date +%s) +echo "Verifying the proof took $((end - start)) seconds." + +echo "DONE" + -# Run the Rust executable -cargo run --bin prove_and_verify || { echo "prove_and_verify.sh: cargo run failed"; exit 102; } diff --git a/workflow/src/bin/aggregate.rs b/workflow/src/bin/aggregate.rs index a0fbd1b..e2a507c 100644 --- a/workflow/src/bin/aggregate.rs +++ b/workflow/src/bin/aggregate.rs @@ -48,13 +48,13 @@ fn main() -> Result<()> { // dummy proofs let proofs: Vec> = (0..k).map(|i| inner_proof.clone()).collect(); - let mut tree = TreeRecursion::::build(data.common.clone()).unwrap(); + let mut tree = TreeRecursion::::build_with_standard_config(data.common.clone(), data.verifier_only.clone()).unwrap(); - let tree_proof = tree.prove_tree(&proofs, &data.verifier_only).unwrap(); + let tree_proof = tree.prove_tree(&proofs).unwrap(); let inner_pi: Vec> = proofs.iter().map(|p| p.public_inputs.clone()).collect(); - assert!(tree.verify_proof_and_public_input(tree_proof,inner_pi.clone(),&data.verifier_data(), false).is_ok()); + assert!(tree.verify_proof_and_public_input(tree_proof,inner_pi.clone(),false).is_ok()); Ok(()) } diff --git a/workflow/src/bin/build_circ.rs b/workflow/src/bin/build_circ.rs index 758b5a4..8d1d39a 100644 --- a/workflow/src/bin/build_circ.rs +++ b/workflow/src/bin/build_circ.rs @@ -1,39 +1,29 @@ -use plonky2::plonk::circuit_data::CircuitConfig; -use plonky2::plonk::config::GenericConfig; -use plonky2::plonk::circuit_builder::CircuitBuilder; -use anyhow::Result; use std::time::Instant; +use anyhow::Result; +use codex_plonky2_circuits::circuit_helper::Plonky2Circuit; use codex_plonky2_circuits::circuits::sample_cells::SampleCircuit; -use plonky2_poseidon2::serialization::{DefaultGateSerializer,DefaultGeneratorSerializer}; -use proof_input::serialization::json::write_bytes_to_file; +use proof_input::serialization::json::export_circuit_data; use proof_input::params::Params; use proof_input::params::{D, C, F,HF}; +use proof_input::serialization::file_paths::{PROVER_CIRC_DATA_JSON, TARGETS_JSON, VERIFIER_CIRC_DATA_JSON}; fn main() -> Result<()> { // Load the parameters from environment variables let params = Params::from_env()?; // 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); - let mut targets = circ.sample_slot_circuit_with_public_input(&mut builder); - - // Build the circuit - let build_time = Instant::now(); - let data = builder.build::(); - println!("Build time: {:?}", build_time.elapsed()); + let start_time = Instant::now(); + let (targets, data) = circ.build_with_standard_config()?; + println!("Build time: {:?}", start_time.elapsed()); println!("Circuit size (degree bits): {:?}", 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 file_path = "circ_data.bin"; - // Write data to the file - write_bytes_to_file(data_bytes.clone(), file_path).unwrap(); - println!("Data written to {}", file_path); + // export the circuit data + export_circuit_data::(data, &targets)?; + println!("Prover Data written to {}", PROVER_CIRC_DATA_JSON); + println!("Verifier Data written to {}", VERIFIER_CIRC_DATA_JSON); + println!("Targets written to {}", TARGETS_JSON); Ok(()) } diff --git a/workflow/src/bin/gen_input.rs b/workflow/src/bin/gen_input.rs index ff5c26e..380de90 100644 --- a/workflow/src/bin/gen_input.rs +++ b/workflow/src/bin/gen_input.rs @@ -1,21 +1,24 @@ +use std::time::Instant; use plonky2::plonk::config::GenericConfig; use anyhow::Result; use proof_input::serialization::circuit_input::export_circ_input_to_json; use proof_input::gen_input::gen_testing_circuit_input; use proof_input::params::Params; use proof_input::params::{D, F}; +use proof_input::serialization::file_paths::CIRC_INPUT_JSON; fn main() -> Result<()> { // Load the parameters from environment variables let params = Params::from_env()?; // generate circuit input with given parameters + let start_time = Instant::now(); let circ_input = gen_testing_circuit_input::(¶ms.input_params); + println!("Generating input time: {:?}", start_time.elapsed()); // export circuit parameters to json file - let filename= "input.json"; - export_circ_input_to_json(circ_input, filename)?; - println!("proof input written to {}", filename); + export_circ_input_to_json(circ_input)?; + println!("proof input written to {}", CIRC_INPUT_JSON); Ok(()) } diff --git a/workflow/src/bin/prove.rs b/workflow/src/bin/prove.rs index debac54..8ce9308 100644 --- a/workflow/src/bin/prove.rs +++ b/workflow/src/bin/prove.rs @@ -1,45 +1,39 @@ -use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::GenericConfig; -use plonky2::iop::witness::PartialWitness; -use plonky2::plonk::circuit_builder::CircuitBuilder; use anyhow::Result; use std::time::Instant; - +use codex_plonky2_circuits::circuit_helper::Plonky2Circuit; use proof_input::serialization::circuit_input::import_circ_input_from_json; -use codex_plonky2_circuits::circuits::sample_cells::{SampleCircuit, SampleCircuitInput}; +use codex_plonky2_circuits::circuits::sample_cells::{SampleCircuit, SampleCircuitInput, SampleTargets}; use codex_plonky2_circuits::circuits::params::CircuitParams; use proof_input::params::{D, C, F, HF}; +use proof_input::serialization::file_paths::{CIRC_INPUT_JSON, PROVER_CIRC_DATA_JSON, TARGETS_JSON}; +use proof_input::serialization::json::{export_proof_with_pi, import_prover_circuit_data, import_targets}; fn main() -> Result<()> { // Load the parameters from environment variables let circuit_params = CircuitParams::from_env()?; // Read the witness from input.json - let circ_input: SampleCircuitInput = import_circ_input_from_json("input.json")?; - println!("Witness imported from input.json"); + let circ_input: SampleCircuitInput = import_circ_input_from_json()?; + println!("Witness imported from: {}", CIRC_INPUT_JSON); - // Create the circuit - let config = CircuitConfig::standard_recursion_config(); - let mut builder = CircuitBuilder::::new(config); - let circ = SampleCircuit::::new(circuit_params); - let mut targets = circ.sample_slot_circuit_with_public_input(&mut builder)?; + // read the targets + let circ_targets: SampleTargets = import_targets()?; + println!("circuit targets imported from: {}", TARGETS_JSON); - // Create a PartialWitness and assign - let mut pw = PartialWitness::new(); - circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input)?; - - // Build the circuit - let build_time = Instant::now(); - let data = builder.build::(); - println!("Build time: {:?}", build_time.elapsed()); - println!("Circuit size (degree bits): {:?}", data.common.degree_bits()); + // read the circuit data + let prover_data = import_prover_circuit_data::()?; + println!("Prover circuit data imported from: {}", PROVER_CIRC_DATA_JSON); + println!("Circuit size (degree bits): {:?}", prover_data.common.degree_bits()); // Prove the circuit with the assigned witness + let circ = SampleCircuit::::new(circuit_params); let start_time = Instant::now(); - let proof_with_pis = data.prove(pw)?; + let proof_with_pis = circ.prove(&circ_targets, &circ_input, &prover_data)?; println!("Proving time: {:?}", start_time.elapsed()); - //TODO: write proof to json file + //export the proof to json file + export_proof_with_pi(&proof_with_pis)?; Ok(()) } diff --git a/workflow/src/bin/prove_and_verify.rs b/workflow/src/bin/prove_and_verify.rs deleted file mode 100644 index 1798ae4..0000000 --- a/workflow/src/bin/prove_and_verify.rs +++ /dev/null @@ -1,52 +0,0 @@ -use plonky2::plonk::circuit_data::CircuitConfig; -use plonky2::plonk::config::GenericConfig; -use plonky2::iop::witness::PartialWitness; -use plonky2::plonk::circuit_builder::CircuitBuilder; -use anyhow::Result; -use std::time::Instant; - -use proof_input::serialization::circuit_input::import_circ_input_from_json; -use codex_plonky2_circuits::circuits::sample_cells::{SampleCircuit, SampleCircuitInput}; -use codex_plonky2_circuits::circuits::params::CircuitParams; -use proof_input::params::{D, C, F, HF}; - -fn main() -> Result<()> { - // Load the parameters from environment variables - let circuit_params = CircuitParams::from_env()?; - - // Read the witness from input.json - let circ_input: SampleCircuitInput = import_circ_input_from_json("input.json")?; - println!("Witness imported from input.json"); - - // Create the circuit - let config = CircuitConfig::standard_recursion_config(); - let mut builder = CircuitBuilder::::new(config); - - let circ = SampleCircuit::::new(circuit_params); - let mut targets = circ.sample_slot_circuit_with_public_input(&mut builder)?; - - // Create a PartialWitness and assign - let mut pw = PartialWitness::new(); - - circ.sample_slot_assign_witness(&mut pw, &targets, &circ_input)?; - - // Build the circuit - let build_time = Instant::now(); - let data = builder.build::(); - println!("Build time: {:?}", build_time.elapsed()); - println!("Circuit size (degree bits): {:?}", data.common.degree_bits()); - - // Prove the circuit with the assigned witness - let start_time = Instant::now(); - let proof_with_pis = data.prove(pw)?; - println!("Proving time: {:?}", start_time.elapsed()); - - // Verify the proof - let verifier_data = data.verifier_data(); - let ver_time = Instant::now(); - verifier_data.verify(proof_with_pis)?; - println!("verification time: {:?}", ver_time.elapsed()); - println!("Proof verification succeeded."); - - Ok(()) -} diff --git a/workflow/src/bin/verify.rs b/workflow/src/bin/verify.rs new file mode 100644 index 0000000..6e64d5e --- /dev/null +++ b/workflow/src/bin/verify.rs @@ -0,0 +1,27 @@ +use std::time::Instant; +use plonky2::plonk::config::GenericConfig; +use anyhow::Result; +use codex_plonky2_circuits::circuits::params::CircuitParams; +use proof_input::params::{D, C, F}; +use proof_input::serialization::file_paths::{PROOF_JSON, VERIFIER_CIRC_DATA_JSON}; +use proof_input::serialization::json::{import_proof_with_pi, import_verifier_circuit_data}; + +fn main() -> Result<()> { + // Load the parameters from environment variables + let circuit_params = CircuitParams::from_env()?; + + // read the circuit data + let verifier_data = import_verifier_circuit_data::()?; + println!("Verifier circuit data imported from: {}", VERIFIER_CIRC_DATA_JSON); + + // Read the proof + let proof_with_pi = import_proof_with_pi::()?; + println!("Proof with public input imported from: {}", PROOF_JSON); + + // verify the proof + let start_time = Instant::now(); + assert!(verifier_data.verify(proof_with_pi).is_ok(), "proof is NOT VALID"); + println!("Verifying time: {:?}", start_time.elapsed()); + + Ok(()) +}