-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
396 additions
and
361 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
[package] | ||
name = "prove-seg" | ||
version = { workspace = true } | ||
edition = { workspace = true } | ||
publish = false | ||
|
||
[dependencies] | ||
zkm-prover = { workspace = true } | ||
zkm-emulator = { workspace = true } | ||
plonky2 = { git = "https://github.com/zkMIPS/plonky2.git", branch = "zkm_dev" } | ||
plonky2_util = { git = "https://github.com/zkMIPS/plonky2.git", branch = "zkm_dev" } | ||
plonky2_maybe_rayon = { git = "https://github.com/zkMIPS/plonky2.git", branch = "zkm_dev" } | ||
plonky2x = { git = "https://github.com/zkMIPS/succinctx.git", package = "plonky2x", branch = "zkm" } | ||
|
||
log = { version = "0.4.14", default-features = false } | ||
serde = { version = "1.0.144", features = ["derive"] } | ||
serde_json = "1.0" | ||
byteorder = "1.5.0" | ||
hex = "0.4" | ||
env_logger = "0.11.5" | ||
anyhow = "1.0.75" | ||
|
||
[build-dependencies] | ||
zkm-build = { workspace = true } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
use std::env; | ||
use std::fs::File; | ||
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; | ||
|
||
const D: usize = 2; | ||
type C = PoseidonGoldilocksConfig; | ||
type F = <C as GenericConfig<D>>::F; | ||
|
||
const DEGREE_BITS_RANGE: [Range<usize>; 6] = [10..21, 12..22, 12..21, 8..21, 6..21, 13..23]; | ||
|
||
fn prove_single_seg_common(seg_file: &str, basedir: &str, block: &str, file: &str) { | ||
let seg_reader = BufReader::new(File::open(seg_file).unwrap()); | ||
let kernel = segment_kernel(basedir, block, file, seg_reader); | ||
|
||
let allstark: AllStark<F, D> = AllStark::default(); | ||
let config = StarkConfig::standard_fast_config(); | ||
let mut timing = TimingTree::new("prove", log::Level::Info); | ||
let allproof: proof::AllProof<GoldilocksField, C, D> = | ||
prove(&allstark, &kernel, &config, &mut timing).unwrap(); | ||
let mut count_bytes = 0; | ||
for (row, proof) in allproof.stark_proofs.clone().iter().enumerate() { | ||
let proof_str = serde_json::to_string(&proof.proof).unwrap(); | ||
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).unwrap(); | ||
log::info!("Prove done"); | ||
} | ||
|
||
fn prove_multi_seg_common( | ||
seg_dir: &str, | ||
basedir: &str, | ||
block: &str, | ||
file: &str, | ||
seg_file_number: usize, | ||
seg_start_id: usize, | ||
) -> anyhow::Result<()> { | ||
type InnerParameters = DefaultParameters; | ||
type OuterParameters = Groth16WrapperParameters; | ||
|
||
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::<F, D>::default(); | ||
let config = StarkConfig::standard_fast_config(); | ||
// Preprocess all circuits. | ||
let all_circuits = | ||
AllRecursiveCircuits::<F, C, D>::new(&all_stark, &DEGREE_BITS_RANGE, &config); | ||
|
||
let seg_file = format!("{}/{}", seg_dir, seg_start_id); | ||
log::info!("Process segment {}", seg_file); | ||
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)?; | ||
|
||
timing.filter(Duration::from_millis(100)).print(); | ||
all_circuits.verify_root(agg_proof.clone())?; | ||
|
||
let mut base_seg = seg_start_id + 1; | ||
let mut seg_num = seg_file_number - 1; | ||
let mut is_agg = false; | ||
|
||
if seg_file_number % 2 == 0 { | ||
let seg_file = format!("{}/{}", seg_dir, seg_start_id + 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); | ||
timing = TimingTree::new("prove root second", log::Level::Info); | ||
let (root_proof, public_values) = | ||
all_circuits.prove_root(&all_stark, &input, &config, &mut timing)?; | ||
timing.filter(Duration::from_millis(100)).print(); | ||
|
||
all_circuits.verify_root(root_proof.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(), | ||
)?; | ||
timing.filter(Duration::from_millis(100)).print(); | ||
all_circuits.verify_aggregation(&agg_proof)?; | ||
|
||
is_agg = true; | ||
base_seg = seg_start_id + 2; | ||
seg_num -= 1; | ||
} | ||
|
||
for i in 0..seg_num / 2 { | ||
let seg_file = format!("{}/{}", seg_dir, base_seg + (i << 1)); | ||
log::info!("Process segment {}", seg_file); | ||
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) = | ||
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())?; | ||
|
||
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)?; | ||
timing.filter(Duration::from_millis(100)).print(); | ||
|
||
all_circuits.verify_root(root_proof.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, | ||
)?; | ||
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, | ||
}; | ||
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(), | ||
)?; | ||
is_agg = true; | ||
timing.filter(Duration::from_millis(100)).print(); | ||
|
||
all_circuits.verify_aggregation(&agg_proof)?; | ||
} | ||
|
||
let (block_proof, _block_public_values) = | ||
all_circuits.prove_block(None, &agg_proof, updated_agg_public_values)?; | ||
|
||
log::info!( | ||
"proof size: {:?}", | ||
serde_json::to_string(&block_proof.proof).unwrap().len() | ||
); | ||
let result = all_circuits.verify_block(&block_proof); | ||
|
||
let build_path = "../verifier/data".to_string(); | ||
let path = format!("{}/test_circuit/", build_path); | ||
let builder = WrapperBuilder::<DefaultParameters, 2>::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::<InnerParameters, OuterParameters, D>::build( | ||
circuit, | ||
Some((vec![], bit_size)), | ||
); | ||
log::info!("build finish"); | ||
|
||
let wrapped_proof = wrapped_circuit.prove(&block_proof).unwrap(); | ||
wrapped_proof.save(path).unwrap(); | ||
|
||
total_timing.filter(Duration::from_millis(100)).print(); | ||
result | ||
} | ||
|
||
fn prove_segments() { | ||
let basedir = env::var("BASEDIR").unwrap_or("/tmp/cannon".to_string()); | ||
let block = env::var("BLOCK_NO").unwrap_or("".to_string()); | ||
let file = env::var("BLOCK_FILE").unwrap_or(String::from("")); | ||
let seg_dir = env::var("SEG_FILE_DIR").expect("segment file dir is missing"); | ||
let seg_num = env::var("SEG_NUM").unwrap_or("1".to_string()); | ||
let seg_num = seg_num.parse::<_>().unwrap_or(1usize); | ||
let seg_start_id = env::var("SEG_START_ID").unwrap_or("0".to_string()); | ||
let seg_start_id = seg_start_id.parse::<_>().unwrap_or(0usize); | ||
|
||
if seg_num == 1 { | ||
let seg_file = format!("{seg_dir}/{}", seg_start_id); | ||
prove_single_seg_common(&seg_file, &basedir, &block, &file) | ||
} else { | ||
prove_multi_seg_common(&seg_dir, &basedir, &block, &file, seg_num, seg_start_id).unwrap() | ||
} | ||
} | ||
|
||
fn main() { | ||
env_logger::try_init().unwrap_or_default(); | ||
prove_segments(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
Oops, something went wrong.