Skip to content

Commit

Permalink
zkvm proof size statistics data (#852)
Browse files Browse the repository at this point in the history
This PR implement formatter on `ZKVMProof` to break down proof size,
which helps to identify and prioritize recursion tasks

> NOTE: it's based on basefold mpcs

```bash
e2e proof stat: overall_size 19.07mb.
opcode mpcs commitment 0%
opcode mpcs opening 40%
opcode tower proof 0%
opcode main sumcheck proof 0%
table mpcs commitment 0%
table mpcs opening 32%
table mpcs fixed opening 25%
table tower proof 0%
table same r sumcheck proof 0%
```
  • Loading branch information
hero78119 authored Mar 5, 2025
1 parent 254e92f commit e8197db
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 13 deletions.
5 changes: 2 additions & 3 deletions ceno_zkvm/benches/fibonacci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn fibonacci_prove(c: &mut Criterion) {
.0
.expect("PrepSanityCheck do not provide proof and verifier");

let serialize_size = bincode::serialize(&proof).unwrap().len();
println!("e2e proof {}", proof);
let stat_recorder = StatisticRecorder::default();
let transcript = BasicTranscriptWithStat::new(&stat_recorder, b"riscv");
assert!(
Expand All @@ -61,9 +61,8 @@ fn fibonacci_prove(c: &mut Criterion) {
);
println!();
println!(
"max_steps = {}, proof size = {}, hashes count = {}",
"max_steps = {}, hashes count = {}",
max_steps,
serialize_size,
stat_recorder.into_inner().field_appended_num
);

Expand Down
5 changes: 2 additions & 3 deletions ceno_zkvm/src/bin/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,12 @@ fn main() {
let (mut zkvm_proof, verifier) = state.expect("PrepSanityCheck should yield state.");

// do statistics
let serialize_size = bincode::serialize(&zkvm_proof).unwrap().len();
let stat_recorder = StatisticRecorder::default();
let transcript = TranscriptWithStat::new(&stat_recorder, b"riscv");
verifier.verify_proof(zkvm_proof.clone(), transcript).ok();
println!("e2e proof stat: {}", zkvm_proof);
println!(
"e2e proof stat: proof size = {}, hashes count = {}",
serialize_size,
"hashes count = {}",
stat_recorder.into_inner().field_appended_num
);

Expand Down
126 changes: 123 additions & 3 deletions ceno_zkvm/src/scheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use itertools::Itertools;
use mpcs::PolynomialCommitmentScheme;
use p3_field::PrimeCharacteristicRing;
use serde::{Deserialize, Serialize, de::DeserializeOwned};
use std::{collections::BTreeMap, fmt::Debug};
use std::{
collections::BTreeMap,
fmt::{self, Debug},
ops::Div,
};
use sumcheck::structs::IOPProverMessage;

use crate::structs::TowerProofs;
Expand Down Expand Up @@ -160,10 +164,126 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProof<E, PCS> {
pub fn update_pi_eval(&mut self, idx: usize, v: E) {
self.pi_evals[idx] = v;
}
}

impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProof<E, PCS> {
pub fn num_circuits(&self) -> usize {
self.opcode_proofs.len() + self.table_proofs.len()
}
}

impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E> + Serialize> fmt::Display
for ZKVMProof<E, PCS>
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// break down zkvm proof size
// opcode circuit mpcs size
let mpcs_opcode_commitment = self
.opcode_proofs
.iter()
.map(|(_, (_, proof))| bincode::serialized_size(&proof.wits_commit))
.collect::<Result<Vec<u64>, _>>()
.expect("serialization error")
.iter()
.sum::<u64>();
let mpcs_opcode_opening = self
.opcode_proofs
.iter()
.map(|(_, (_, proof))| bincode::serialized_size(&proof.wits_opening_proof))
.collect::<Result<Vec<u64>, _>>()
.expect("serialization error")
.iter()
.sum::<u64>();
// opcode circuit for tower proof size
let tower_proof_opcode = self
.opcode_proofs
.iter()
.map(|(_, (_, proof))| bincode::serialized_size(&proof.tower_proof))
.collect::<Result<Vec<u64>, _>>()
.expect("serialization error")
.iter()
.sum::<u64>();
// opcode circuit main sumcheck
let main_sumcheck_opcode = self
.opcode_proofs
.iter()
.map(|(_, (_, proof))| bincode::serialized_size(&proof.main_sel_sumcheck_proofs))
.collect::<Result<Vec<u64>, _>>()
.expect("serialization error")
.iter()
.sum::<u64>();
// table circuit mpcs size
let mpcs_table_commitment = self
.table_proofs
.iter()
.map(|(_, (_, proof))| bincode::serialized_size(&proof.wits_commit))
.collect::<Result<Vec<u64>, _>>()
.expect("serialization error")
.iter()
.sum::<u64>();
let mpcs_table_opening = self
.table_proofs
.iter()
.map(|(_, (_, proof))| bincode::serialized_size(&proof.wits_opening_proof))
.collect::<Result<Vec<u64>, _>>()
.expect("serialization error")
.iter()
.sum::<u64>();
let mpcs_table_fixed_opening = self
.table_proofs
.iter()
.map(|(_, (_, proof))| bincode::serialized_size(&proof.fixed_opening_proof))
.collect::<Result<Vec<u64>, _>>()
.expect("serialization error")
.iter()
.sum::<u64>();
// table circuit for tower proof size
let tower_proof_table = self
.table_proofs
.iter()
.map(|(_, (_, proof))| bincode::serialized_size(&proof.tower_proof))
.collect::<Result<Vec<u64>, _>>()
.expect("serialization error")
.iter()
.sum::<u64>();
// table circuit same r sumcheck
let same_r_sumcheck_table = self
.table_proofs
.iter()
.map(|(_, (_, proof))| bincode::serialized_size(&proof.same_r_sumcheck_proofs))
.collect::<Result<Vec<u64>, _>>()
.expect("serialization error")
.iter()
.sum::<u64>();

// overall size
let overall_size = bincode::serialized_size(&self).expect("serialization error");

// let mpcs_size = bincode::serialized_size(&proof.).unwrap().len();
write!(
f,
"overall_size {:.2}mb. \n\
opcode mpcs commitment {:?}% \n\
opcode mpcs opening {:?}% \n\
opcode tower proof {:?}% \n\
opcode main sumcheck proof {:?}% \n\
table mpcs commitment {:?}% \n\
table mpcs opening {:?}% \n\
table mpcs fixed opening {:?}% \n\
table tower proof {:?}% \n\
table same r sumcheck proof {:?}%",
byte_to_mb(overall_size),
(mpcs_opcode_commitment * 100).div(overall_size),
(mpcs_opcode_opening * 100).div(overall_size),
(tower_proof_opcode * 100).div(overall_size),
(main_sumcheck_opcode * 100).div(overall_size),
(mpcs_table_commitment * 100).div(overall_size),
(mpcs_table_opening * 100).div(overall_size),
(mpcs_table_fixed_opening * 100).div(overall_size),
(tower_proof_table * 100).div(overall_size),
(same_r_sumcheck_table * 100).div(overall_size),
)
}
}

fn byte_to_mb(byte_size: u64) -> f64 {
byte_size as f64 / (1024.0 * 1024.0)
}
6 changes: 2 additions & 4 deletions ceno_zkvm/src/scheme/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,7 @@ fn test_single_add_instance_e2e() {
.create_proof(zkvm_witness, pi, transcript)
.expect("create_proof failed");

let encoded_bin = bincode::serialize(&zkvm_proof).unwrap();

println!("encoded zkvm proof {}", &zkvm_proof,);
let stat_recorder = StatisticRecorder::default();
{
let transcript = BasicTranscriptWithStat::new(&stat_recorder, b"riscv");
Expand All @@ -304,8 +303,7 @@ fn test_single_add_instance_e2e() {
);
}
println!(
"encoded zkvm proof size: {}, hash_num: {}",
encoded_bin.len(),
"hash_num: {}",
stat_recorder.into_inner().field_appended_num
);
}
Expand Down

0 comments on commit e8197db

Please sign in to comment.