From 57e5b57f8675c9cf02dea6711b2bc8ef989cc5d3 Mon Sep 17 00:00:00 2001 From: xander42280 Date: Fri, 20 Dec 2024 21:03:09 +0800 Subject: [PATCH 1/3] Update zkm receipt --- sdk/src/local/stark.rs | 10 +-- sdk/src/local/util.rs | 199 ++++++++++++++--------------------------- 2 files changed, 69 insertions(+), 140 deletions(-) diff --git a/sdk/src/local/stark.rs b/sdk/src/local/stark.rs index 792fe2a9..1c0eb7be 100644 --- a/sdk/src/local/stark.rs +++ b/sdk/src/local/stark.rs @@ -27,12 +27,6 @@ pub fn prove_stark( return Ok(false); } log::info!("[The seg_num is:{} ]", &seg_num); - if seg_num == 1 { - let seg_file = format!("{seg_path}/{}", 0); - util::prove_single_seg_common(&seg_file, "", "", "")?; - Ok(false) - } else { - util::prove_multi_seg_common(&seg_path, "", "", "", storedir, seg_num, 0)?; - Ok(true) - } + util::prove_segments(&seg_path, "", storedir, "", "", seg_num, 0, vec![])?; + Ok(seg_num > 1) } diff --git a/sdk/src/local/util.rs b/sdk/src/local/util.rs index cc74edab..2920a220 100644 --- a/sdk/src/local/util.rs +++ b/sdk/src/local/util.rs @@ -3,76 +3,37 @@ use std::io::BufReader; use std::ops::Range; use std::time::Duration; -use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2::util::timing::TimingTree; use plonky2x::backend::circuit::Groth16WrapperParameters; use plonky2x::backend::wrapper::wrap::WrappedCircuit; use plonky2x::frontend::builder::CircuitBuilder as WrapperBuilder; use plonky2x::prelude::DefaultParameters; + use zkm_prover::all_stark::AllStark; use zkm_prover::config::StarkConfig; use zkm_prover::cpu::kernel::assembler::segment_kernel; use zkm_prover::fixed_recursive_verifier::AllRecursiveCircuits; -use zkm_prover::proof; -use zkm_prover::proof::PublicValues; -use zkm_prover::prover::prove; -use zkm_prover::verifier::verify_proof; +use zkm_prover::generation::state::{AssumptionReceipts, Receipt}; const DEGREE_BITS_RANGE: [Range; 6] = [10..21, 12..22, 10..21, 10..21, 6..21, 13..23]; +const D: usize = 2; +type C = PoseidonGoldilocksConfig; +type F = >::F; -pub fn prove_single_seg_common( - seg_file: &str, - basedir: &str, - block: &str, - file: &str, -) -> anyhow::Result<()> { - let seg_reader = BufReader::new(File::open(seg_file)?); - let kernel = segment_kernel(basedir, block, file, seg_reader); - - const D: usize = 2; - type C = PoseidonGoldilocksConfig; - type F = >::F; - - let allstark: AllStark = AllStark::default(); - let config = StarkConfig::standard_fast_config(); - let mut timing = TimingTree::new("prove", log::Level::Info); - let allproof: proof::AllProof = - prove(&allstark, &kernel, &config, &mut timing)?; - let mut count_bytes = 0; - for (row, proof) in allproof.stark_proofs.clone().iter().enumerate() { - let proof_str = serde_json::to_string(&proof.proof)?; - log::info!("row:{} proof bytes:{}", row, proof_str.len()); - count_bytes += proof_str.len(); - } - timing.filter(Duration::from_millis(100)).print(); - log::info!("total proof bytes:{}KB", count_bytes / 1024); - verify_proof(&allstark, allproof, &config)?; - log::info!("Prove done"); - Ok(()) -} - -#[allow(clippy::too_many_arguments)] -pub fn prove_multi_seg_common( +pub fn prove_segments( seg_dir: &str, basedir: &str, + outdir: &str, block: &str, file: &str, - outdir: &str, seg_file_number: usize, seg_start_id: usize, -) -> anyhow::Result<()> { + assumptions: AssumptionReceipts, +) -> anyhow::Result> { type InnerParameters = DefaultParameters; type OuterParameters = Groth16WrapperParameters; - type F = GoldilocksField; - const D: usize = 2; - type C = PoseidonGoldilocksConfig; - - if seg_file_number < 2 { - panic!("seg file number must >= 2\n"); - } - let total_timing = TimingTree::new("prove total time", log::Level::Info); let all_stark = AllStark::::default(); let config = StarkConfig::standard_fast_config(); @@ -85,15 +46,20 @@ pub fn prove_multi_seg_common( let seg_reader = BufReader::new(File::open(seg_file)?); let input_first = segment_kernel(basedir, block, file, seg_reader); let mut timing = TimingTree::new("prove root first", log::Level::Info); - let (mut agg_proof, mut updated_agg_public_values) = - all_circuits.prove_root(&all_stark, &input_first, &config, &mut timing)?; + let mut agg_receipt = all_circuits.prove_root_with_assumption( + &all_stark, + &input_first, + &config, + &mut timing, + assumptions, + )?; timing.filter(Duration::from_millis(100)).print(); - all_circuits.verify_root(agg_proof.clone())?; + all_circuits.verify_root(agg_receipt.clone())?; let mut base_seg = seg_start_id + 1; let mut seg_num = seg_file_number - 1; - let mut is_agg: bool = false; + let mut is_agg = false; if seg_file_number % 2 == 0 { let seg_file = format!("{}/{}", seg_dir, seg_start_id + 1); @@ -101,29 +67,16 @@ pub fn prove_multi_seg_common( let seg_reader = BufReader::new(File::open(seg_file)?); let input = segment_kernel(basedir, block, file, seg_reader); timing = TimingTree::new("prove root second", log::Level::Info); - let (root_proof, public_values) = - all_circuits.prove_root(&all_stark, &input, &config, &mut timing)?; + let receipt = all_circuits.prove_root(&all_stark, &input, &config, &mut timing)?; timing.filter(Duration::from_millis(100)).print(); - all_circuits.verify_root(root_proof.clone())?; + all_circuits.verify_root(receipt.clone())?; - // Update public values for the aggregation. - let agg_public_values = PublicValues { - roots_before: updated_agg_public_values.roots_before, - roots_after: public_values.roots_after, - userdata: public_values.userdata, - }; timing = TimingTree::new("prove aggression", log::Level::Info); // We can duplicate the proofs here because the state hasn't mutated. - (agg_proof, updated_agg_public_values) = all_circuits.prove_aggregation( - false, - &agg_proof, - false, - &root_proof, - agg_public_values.clone(), - )?; + agg_receipt = all_circuits.prove_aggregation(false, &agg_receipt, false, &receipt)?; timing.filter(Duration::from_millis(100)).print(); - all_circuits.verify_aggregation(&agg_proof)?; + all_circuits.verify_aggregation(&agg_receipt)?; is_agg = true; base_seg = seg_start_id + 2; @@ -136,96 +89,78 @@ pub fn prove_multi_seg_common( let seg_reader = BufReader::new(File::open(&seg_file)?); let input_first = segment_kernel(basedir, block, file, seg_reader); let mut timing = TimingTree::new("prove root first", log::Level::Info); - let (root_proof_first, first_public_values) = + let root_receipt_first = all_circuits.prove_root(&all_stark, &input_first, &config, &mut timing)?; timing.filter(Duration::from_millis(100)).print(); - all_circuits.verify_root(root_proof_first.clone())?; + all_circuits.verify_root(root_receipt_first.clone())?; let seg_file = format!("{}/{}", seg_dir, base_seg + (i << 1) + 1); log::info!("Process segment {}", seg_file); let seg_reader = BufReader::new(File::open(&seg_file)?); let input = segment_kernel(basedir, block, file, seg_reader); let mut timing = TimingTree::new("prove root second", log::Level::Info); - let (root_proof, public_values) = - all_circuits.prove_root(&all_stark, &input, &config, &mut timing)?; + let root_receipt = all_circuits.prove_root(&all_stark, &input, &config, &mut timing)?; timing.filter(Duration::from_millis(100)).print(); - all_circuits.verify_root(root_proof.clone())?; + all_circuits.verify_root(root_receipt.clone())?; - // Update public values for the aggregation. - let new_agg_public_values = PublicValues { - roots_before: first_public_values.roots_before, - roots_after: public_values.roots_after, - userdata: public_values.userdata, - }; timing = TimingTree::new("prove aggression", log::Level::Info); // We can duplicate the proofs here because the state hasn't mutated. - let (new_agg_proof, new_updated_agg_public_values) = all_circuits.prove_aggregation( - false, - &root_proof_first, - false, - &root_proof, - new_agg_public_values, - )?; + let new_agg_receipt = + all_circuits.prove_aggregation(false, &root_receipt_first, false, &root_receipt)?; timing.filter(Duration::from_millis(100)).print(); - all_circuits.verify_aggregation(&new_agg_proof)?; - - // Update public values for the nested aggregation. - let agg_public_values = PublicValues { - roots_before: updated_agg_public_values.roots_before, - roots_after: new_updated_agg_public_values.roots_after, - userdata: new_updated_agg_public_values.userdata, - }; + all_circuits.verify_aggregation(&new_agg_receipt)?; + timing = TimingTree::new("prove nested aggression", log::Level::Info); // We can duplicate the proofs here because the state hasn't mutated. - (agg_proof, updated_agg_public_values) = all_circuits.prove_aggregation( - is_agg, - &agg_proof, - true, - &new_agg_proof, - agg_public_values.clone(), - )?; + agg_receipt = + all_circuits.prove_aggregation(is_agg, &agg_receipt, true, &new_agg_receipt)?; is_agg = true; timing.filter(Duration::from_millis(100)).print(); - all_circuits.verify_aggregation(&agg_proof)?; + all_circuits.verify_aggregation(&agg_receipt)?; } - let (block_proof, _block_public_values) = - all_circuits.prove_block(None, &agg_proof, updated_agg_public_values.clone())?; - log::info!( "proof size: {:?}", - serde_json::to_string(&block_proof.proof).unwrap().len() - ); - let result = all_circuits.verify_block(&block_proof); - - let builder = WrapperBuilder::::new(); - let mut circuit = builder.build(); - circuit.set_data(all_circuits.block.circuit); - let mut bit_size = vec![32usize; 16]; - bit_size.extend(vec![8; 32]); - bit_size.extend(vec![64; 68]); - let wrapped_circuit = WrappedCircuit::::build( - circuit, - Some((vec![], bit_size)), + serde_json::to_string(&agg_receipt.proof().proof) + .unwrap() + .len() ); - log::info!("build finish"); + let final_receipt = if seg_file_number > 1 { + let block_receipt = all_circuits.prove_block(None, &agg_receipt)?; + all_circuits.verify_block(&block_receipt)?; + let builder = WrapperBuilder::::new(); + let mut circuit = builder.build(); + circuit.set_data(all_circuits.block.circuit); + let mut bit_size = vec![32usize; 16]; + bit_size.extend(vec![8; 32]); + bit_size.extend(vec![64; 68]); + let wrapped_circuit = WrappedCircuit::::build( + circuit, + Some((vec![], bit_size)), + ); + let wrapped_proof = wrapped_circuit.prove(&block_receipt.proof()).unwrap(); + wrapped_proof.save(outdir).unwrap(); + + let block_public_inputs = serde_json::json!({ + "public_inputs": wrapped_proof.proof.public_inputs, + }); + let outdir_path = std::path::Path::new(outdir); + let public_values_file = File::create(outdir_path.join("public_values.json"))?; + serde_json::to_writer(&public_values_file, &block_receipt.values())?; + let block_public_inputs_file = File::create(outdir_path.join("block_public_inputs.json"))?; + serde_json::to_writer(&block_public_inputs_file, &block_public_inputs)?; + + block_receipt + } else { + agg_receipt + }; - let wrapped_proof = wrapped_circuit.prove(&block_proof)?; - wrapped_proof.save(outdir)?; - - let block_public_inputs = serde_json::json!({ - "public_inputs": block_proof.public_inputs, - }); - let outdir_path = std::path::Path::new(outdir); - let public_values_file = File::create(outdir_path.join("public_values.json"))?; - serde_json::to_writer(&public_values_file, &updated_agg_public_values)?; - let block_public_inputs_file = File::create(outdir_path.join("block_public_inputs.json"))?; - serde_json::to_writer(&block_public_inputs_file, &block_public_inputs)?; + log::info!("build finish"); total_timing.filter(Duration::from_millis(100)).print(); - result + Ok(final_receipt) } From c6d2cf4ba0ed3ffc440d7a77dfa7d6452c21c51c Mon Sep 17 00:00:00 2001 From: xander42280 Date: Fri, 20 Dec 2024 21:12:05 +0800 Subject: [PATCH 2/3] Fix fmt --- sdk/src/local/util.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/src/local/util.rs b/sdk/src/local/util.rs index 2920a220..df3e4f7d 100644 --- a/sdk/src/local/util.rs +++ b/sdk/src/local/util.rs @@ -21,6 +21,7 @@ const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; +#[allow(clippy::too_many_arguments)] pub fn prove_segments( seg_dir: &str, basedir: &str, From 05ee23eb47c4a887921647f5e131de45fafc4d8b Mon Sep 17 00:00:00 2001 From: xander42280 Date: Sun, 22 Dec 2024 10:15:29 +0800 Subject: [PATCH 3/3] Update block_public_inputs --- sdk/src/local/util.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sdk/src/local/util.rs b/sdk/src/local/util.rs index df3e4f7d..d68da568 100644 --- a/sdk/src/local/util.rs +++ b/sdk/src/local/util.rs @@ -146,8 +146,12 @@ pub fn prove_segments( let wrapped_proof = wrapped_circuit.prove(&block_receipt.proof()).unwrap(); wrapped_proof.save(outdir).unwrap(); + let src_public_inputs = match &block_receipt { + Receipt::Segments(receipt) => &receipt.proof.public_inputs, + Receipt::Composite(recepit) => &recepit.program_receipt.proof.public_inputs, + }; let block_public_inputs = serde_json::json!({ - "public_inputs": wrapped_proof.proof.public_inputs, + "public_inputs": src_public_inputs, }); let outdir_path = std::path::Path::new(outdir); let public_values_file = File::create(outdir_path.join("public_values.json"))?;