Skip to content

Commit

Permalink
feat: unify proofs by receipt and assumption (#197)
Browse files Browse the repository at this point in the history
* remove unused control_root in sys_verify

* feat: use commit info instead input for sys_verify

* use receipt type wrapper for prove/verify

* update example tests

* fix single-segemnt prove

* fix verify

* fix commit info in receipt

* fix input type in precompile test

* mov utils from prover to example, update prover/runtime version
  • Loading branch information
weilzkm authored Dec 20, 2024
1 parent 3f4ec4d commit 3e32a00
Show file tree
Hide file tree
Showing 31 changed files with 561 additions and 1,109 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ members = [
]
resolver = "2"

[workspace.package]
version = "0.2.0"
edition = "2021"

[profile.release]
opt-level = 3
Expand Down
4 changes: 2 additions & 2 deletions build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
name = "zkm-build"
description = "Build an ZKM program."
readme = "README.md"
version = "0.1.0"
edition = "2021"
version = { workspace = true }
edition = { workspace = true }

[dependencies]
cargo_metadata = "0.18.1"
Expand Down
4 changes: 2 additions & 2 deletions emulator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "zkm-emulator"
version = "0.1.0"
edition = "2021"
version = { workspace = true }
edition = { workspace = true }

[dependencies]
plonky2 = { git = "https://github.com/zkMIPS/plonky2.git", branch = "zkm_dev" }
Expand Down
5 changes: 2 additions & 3 deletions prover/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "zkm-prover"
version = "0.1.0"
edition = "2021"
version = { workspace = true }
edition = { workspace = true }

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down Expand Up @@ -39,7 +39,6 @@ lazy_static = "1.4.0"
elf = { version = "0.7", default-features = false }
sha2 = { version = "0.10.8", default-features = false }


[dev-dependencies]
env_logger = "0.10.0"
keccak-hash = "0.10.0"
Expand Down
5 changes: 1 addition & 4 deletions prover/examples/prove-seg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ 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" }
zkm-utils = { path = "../utils" }

log = { version = "0.4.14", default-features = false }
serde = { version = "1.0.144", features = ["derive"] }
Expand Down
231 changes: 11 additions & 220 deletions prover/examples/prove-seg/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,217 +1,5 @@
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
}
use zkm_prover::utils;

fn prove_segments() {
let basedir = env::var("BASEDIR").unwrap_or("/tmp/cannon".to_string());
Expand All @@ -223,15 +11,18 @@ fn prove_segments() {
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()
}
let _ = utils::prove_segments(
&seg_dir,
&basedir,
&block,
&file,
seg_num,
seg_start_id,
vec![],
);
}

fn main() {
env_logger::try_init().unwrap_or_default();
prove_segments();
}
}
4 changes: 2 additions & 2 deletions prover/examples/revme/guest/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions prover/examples/revme/host/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ 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" }
zkm-utils = { path = "../../utils" }

log = { version = "0.4.14", default-features = false }
serde = { version = "1.0.144", features = ["derive"] }
Expand Down
Loading

0 comments on commit 3e32a00

Please sign in to comment.