Skip to content

Commit 1025644

Browse files
committed
unify non-uniform witness in proof
1 parent e712182 commit 1025644

File tree

5 files changed

+160
-75
lines changed

5 files changed

+160
-75
lines changed

ceno_zkvm/src/bin/e2e.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ fn verify(proof_file: &str, vk_file: &str) {
222222
let transcript = TranscriptWithStat::new(&stat_recorder, b"riscv");
223223
assert!(
224224
verifier
225-
.verify_proof_halt(zkvm_proof.clone(), transcript, zkvm_proof.has_halt())
225+
.verify_proof_halt(zkvm_proof.clone(), transcript, zkvm_proof.has_halt(&vk))
226226
.is_ok()
227227
);
228228
println!("e2e proof stat: {}", zkvm_proof);

ceno_zkvm/src/scheme.rs

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use sumcheck::structs::IOPProverMessage;
1212

1313
use crate::{
1414
instructions::{Instruction, riscv::ecall::HaltInstruction},
15-
structs::TowerProofs,
15+
structs::{TowerProofs, ZKVMVerifyingKey},
1616
};
1717

1818
pub mod constants;
@@ -70,9 +70,6 @@ pub struct ZKVMTableProof<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>>
7070

7171
pub tower_proof: TowerProofs<E>,
7272

73-
// num_vars hint for rw dynamic address to work
74-
pub rw_hints_num_vars: Vec<usize>,
75-
7673
pub fixed_in_evals: Vec<E>,
7774
pub fixed_opening_proof: Option<PCS::Proof>,
7875
pub wits_commit: PCS::Commitment,
@@ -143,8 +140,8 @@ pub struct ZKVMProof<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> {
143140
pub pi_evals: Vec<E>,
144141
// circuit size -> instance mapping
145142
pub num_instances: Vec<(usize, usize)>,
146-
opcode_proofs: BTreeMap<String, (usize, ZKVMOpcodeProof<E, PCS>)>,
147-
table_proofs: BTreeMap<String, (usize, ZKVMTableProof<E, PCS>)>,
143+
opcode_proofs: BTreeMap<usize, ZKVMOpcodeProof<E, PCS>>,
144+
table_proofs: BTreeMap<usize, ZKVMTableProof<E, PCS>>,
148145
}
149146

150147
impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProof<E, PCS> {
@@ -166,6 +163,7 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProof<E, PCS> {
166163
Self {
167164
raw_pi,
168165
pi_evals,
166+
num_instances: vec![],
169167
opcode_proofs: BTreeMap::new(),
170168
table_proofs: BTreeMap::new(),
171169
}
@@ -179,11 +177,19 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProof<E, PCS> {
179177
self.opcode_proofs.len() + self.table_proofs.len()
180178
}
181179

182-
pub fn has_halt(&self) -> bool {
180+
pub fn has_halt(&self, vk: &ZKVMVerifyingKey<E, PCS>) -> bool {
183181
let halt_instance_count = self
184-
.opcode_proofs
185-
.get(&HaltInstruction::<E>::name())
186-
.map(|(_, p)| p.num_instances)
182+
.num_instances
183+
.iter()
184+
.find_map(|(circuit_index, num_instances)| {
185+
(*circuit_index
186+
== vk
187+
.circuit_vks
188+
.keys()
189+
.position(|circuit_name| *circuit_name == HaltInstruction::<E>::name())
190+
.expect("halt circuit not exist"))
191+
.then_some(*num_instances)
192+
})
187193
.unwrap_or(0);
188194
if halt_instance_count > 0 {
189195
assert_eq!(
@@ -207,10 +213,10 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E> + Serialize> fmt::Dis
207213
let mpcs_opcode_commitment = self
208214
.opcode_proofs
209215
.iter()
210-
.map(|(circuit_name, (_, proof))| {
216+
.map(|(circuit_index, proof)| {
211217
let size = bincode::serialized_size(&proof.wits_commit);
212218
size.inspect(|size| {
213-
*by_circuitname_stats.entry(circuit_name).or_insert(0) += size;
219+
*by_circuitname_stats.entry(circuit_index).or_insert(0) += size;
214220
})
215221
})
216222
.collect::<Result<Vec<u64>, _>>()
@@ -220,10 +226,10 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E> + Serialize> fmt::Dis
220226
let mpcs_opcode_opening = self
221227
.opcode_proofs
222228
.iter()
223-
.map(|(circuit_name, (_, proof))| {
229+
.map(|(circuit_index, proof)| {
224230
let size = bincode::serialized_size(&proof.wits_opening_proof);
225231
size.inspect(|size| {
226-
*by_circuitname_stats.entry(circuit_name).or_insert(0) += size;
232+
*by_circuitname_stats.entry(circuit_index).or_insert(0) += size;
227233
})
228234
})
229235
.collect::<Result<Vec<u64>, _>>()
@@ -234,10 +240,10 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E> + Serialize> fmt::Dis
234240
let tower_proof_opcode = self
235241
.opcode_proofs
236242
.iter()
237-
.map(|(circuit_name, (_, proof))| {
243+
.map(|(circuit_index, proof)| {
238244
let size = bincode::serialized_size(&proof.tower_proof);
239245
size.inspect(|size| {
240-
*by_circuitname_stats.entry(circuit_name).or_insert(0) += size;
246+
*by_circuitname_stats.entry(circuit_index).or_insert(0) += size;
241247
})
242248
})
243249
.collect::<Result<Vec<u64>, _>>()
@@ -248,10 +254,10 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E> + Serialize> fmt::Dis
248254
let main_sumcheck_opcode = self
249255
.opcode_proofs
250256
.iter()
251-
.map(|(circuit_name, (_, proof))| {
257+
.map(|(circuit_index, proof)| {
252258
let size = bincode::serialized_size(&proof.main_sel_sumcheck_proofs);
253259
size.inspect(|size| {
254-
*by_circuitname_stats.entry(circuit_name).or_insert(0) += size;
260+
*by_circuitname_stats.entry(circuit_index).or_insert(0) += size;
255261
})
256262
})
257263
.collect::<Result<Vec<u64>, _>>()
@@ -262,10 +268,10 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E> + Serialize> fmt::Dis
262268
let mpcs_table_commitment = self
263269
.table_proofs
264270
.iter()
265-
.map(|(circuit_name, (_, proof))| {
271+
.map(|(circuit_index, proof)| {
266272
let size = bincode::serialized_size(&proof.wits_commit);
267273
size.inspect(|size| {
268-
*by_circuitname_stats.entry(circuit_name).or_insert(0) += size;
274+
*by_circuitname_stats.entry(circuit_index).or_insert(0) += size;
269275
})
270276
})
271277
.collect::<Result<Vec<u64>, _>>()
@@ -275,10 +281,10 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E> + Serialize> fmt::Dis
275281
let mpcs_table_opening = self
276282
.table_proofs
277283
.iter()
278-
.map(|(circuit_name, (_, proof))| {
284+
.map(|(circuit_index, proof)| {
279285
let size = bincode::serialized_size(&proof.wits_opening_proof);
280286
size.inspect(|size| {
281-
*by_circuitname_stats.entry(circuit_name).or_insert(0) += size;
287+
*by_circuitname_stats.entry(circuit_index).or_insert(0) += size;
282288
})
283289
})
284290
.collect::<Result<Vec<u64>, _>>()
@@ -288,10 +294,10 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E> + Serialize> fmt::Dis
288294
let mpcs_table_fixed_opening = self
289295
.table_proofs
290296
.iter()
291-
.map(|(circuit_name, (_, proof))| {
297+
.map(|(circuit_index, proof)| {
292298
let size = bincode::serialized_size(&proof.fixed_opening_proof);
293299
size.inspect(|size| {
294-
*by_circuitname_stats.entry(circuit_name).or_insert(0) += size;
300+
*by_circuitname_stats.entry(circuit_index).or_insert(0) += size;
295301
})
296302
})
297303
.collect::<Result<Vec<u64>, _>>()
@@ -302,10 +308,10 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E> + Serialize> fmt::Dis
302308
let tower_proof_table = self
303309
.table_proofs
304310
.iter()
305-
.map(|(circuit_name, (_, proof))| {
311+
.map(|(circuit_index, proof)| {
306312
let size = bincode::serialized_size(&proof.tower_proof);
307313
size.inspect(|size| {
308-
*by_circuitname_stats.entry(circuit_name).or_insert(0) += size;
314+
*by_circuitname_stats.entry(circuit_index).or_insert(0) += size;
309315
})
310316
})
311317
.collect::<Result<Vec<u64>, _>>()
@@ -316,10 +322,10 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E> + Serialize> fmt::Dis
316322
let same_r_sumcheck_table = self
317323
.table_proofs
318324
.iter()
319-
.map(|(circuit_name, (_, proof))| {
325+
.map(|(circuit_index, proof)| {
320326
let size = bincode::serialized_size(&proof.same_r_sumcheck_proofs);
321327
size.inspect(|size| {
322-
*by_circuitname_stats.entry(circuit_name).or_insert(0) += size;
328+
*by_circuitname_stats.entry(circuit_index).or_insert(0) += size;
323329
})
324330
})
325331
.collect::<Result<Vec<u64>, _>>()

ceno_zkvm/src/scheme/prover.rs

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,14 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
6464
pi: PublicValues<u32>,
6565
mut transcript: impl Transcript<E>,
6666
) -> Result<ZKVMProof<E, PCS>, ZKVMError> {
67-
let span = entered_span!("commit_to_fixed_commit", profiling_1 = true);
6867
let mut vm_proof = ZKVMProof::empty(pi);
6968

69+
let span = entered_span!("commit_to_pi", profiling_1 = true);
7070
// including raw public input to transcript
7171
for v in vm_proof.raw_pi.iter().flatten() {
7272
transcript.append_field_element(v);
7373
}
74+
exit_span!(span);
7475

7576
let pi: Vec<ArcMultilinearExtension<E>> = vm_proof
7677
.raw_pi
@@ -82,6 +83,7 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
8283
.collect();
8384

8485
// commit to fixed commitment
86+
let span = entered_span!("commit_to_fixed_commit", profiling_1 = true);
8587
for pk in self.pk.circuit_pks.values() {
8688
if let Some(fixed_commit) = &pk.vk.fixed_commit {
8789
PCS::write_commitment(fixed_commit, &mut transcript)
@@ -91,10 +93,48 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
9193
exit_span!(span);
9294

9395
// commit to main traces
96+
let circuit_name_index_mapping = self
97+
.pk
98+
.circuit_pks
99+
.keys()
100+
.enumerate()
101+
.map(|(k, v)| (v, k))
102+
.collect::<BTreeMap<_, _>>();
94103
let mut commitments = BTreeMap::new();
95104
let mut wits = BTreeMap::new();
96105
let mut structural_wits = BTreeMap::new();
97106

107+
let mut num_instances = Vec::with_capacity(self.pk.circuit_pks.len());
108+
for (index, (circuit_name, _)) in self.pk.circuit_pks.iter().enumerate() {
109+
if let Some(num_instance) = witnesses
110+
.get_opcode_witness(circuit_name)
111+
.or_else(|| {
112+
witnesses
113+
.get_table_witness(circuit_name)
114+
.map(|rmms| &rmms[0])
115+
})
116+
.map(|rmm| rmm.num_instances())
117+
.and_then(|num_instance| {
118+
if num_instance > 0 {
119+
Some(num_instance)
120+
} else {
121+
None
122+
}
123+
})
124+
{
125+
num_instances.push((index, num_instance));
126+
}
127+
}
128+
129+
// verifier need this information from prover to achieve non-uniform design.
130+
vm_proof.num_instances = num_instances;
131+
132+
// write (circuit_size, num_var) to transcript
133+
for (circuit_size, num_var) in &vm_proof.num_instances {
134+
transcript.append_message(&circuit_size.to_le_bytes());
135+
transcript.append_message(&num_var.to_le_bytes());
136+
}
137+
98138
let commit_to_traces_span = entered_span!("commit_to_traces", profiling_1 = true);
99139
// commit to opcode circuits first and then commit to table circuits, sorted by name
100140
for (circuit_name, mut rmm) in witnesses.into_iter_sorted() {
@@ -120,7 +160,7 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
120160
PCS::batch_commit_and_write(&self.pk.pp, witness_rmm, &mut transcript)
121161
.map_err(ZKVMError::PCSError)?;
122162
let witness = PCS::get_arc_mle_witness_from_commitment(&commit);
123-
commitments.insert(circuit_name.clone(), commit);
163+
commitments.insert(circuit_name_index_mapping[&circuit_name], commit);
124164
(witness, structural_witness)
125165
}
126166
};
@@ -155,7 +195,7 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
155195
continue;
156196
}
157197
transcript.append_field_element(&E::BaseField::from_u64(index as u64));
158-
let wits_commit = commitments.remove(circuit_name).unwrap();
198+
let wits_commit = commitments.remove(&index).unwrap();
159199
// TODO: add an enum for circuit type either in constraint_system or vk
160200
let cs = pk.get_cs();
161201
let is_opcode_circuit = cs.lk_table_expressions.is_empty()
@@ -187,9 +227,7 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
187227
circuit_name,
188228
num_instances
189229
);
190-
vm_proof
191-
.opcode_proofs
192-
.insert(circuit_name.clone(), (index, opcode_proof));
230+
vm_proof.opcode_proofs.insert(index, opcode_proof);
193231
} else {
194232
let (structural_witness, structural_num_instances) = structural_wits
195233
.remove(circuit_name)
@@ -211,9 +249,7 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
211249
num_instances,
212250
structural_num_instances
213251
);
214-
vm_proof
215-
.table_proofs
216-
.insert(circuit_name.clone(), (index, table_proof));
252+
vm_proof.table_proofs.insert(index, table_proof);
217253
for (idx, eval) in pi_in_evals {
218254
vm_proof.update_pi_eval(idx, eval);
219255
}
@@ -652,7 +688,6 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
652688
let wits_commit = PCS::get_pure_commitment(&wits_commit);
653689

654690
Ok(ZKVMOpcodeProof {
655-
num_instances,
656691
record_r_out_evals,
657692
record_w_out_evals,
658693
lk_p1_out_eval,
@@ -919,15 +954,6 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
919954
})
920955
.collect_vec();
921956

922-
// (non uniform) collect dynamic address hints as witness for verifier
923-
let rw_hints_num_vars = structural_witnesses
924-
.iter()
925-
.map(|mle| mle.num_vars())
926-
.collect_vec();
927-
for var in rw_hints_num_vars.iter() {
928-
transcript.append_message(&var.to_le_bytes());
929-
}
930-
931957
let (rt_tower, tower_proof) = TowerProver::create_proof(
932958
// pattern [r1, w1, r2, w2, ...] same pair are chain together
933959
r_wit_layers
@@ -1130,7 +1156,6 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
11301156
tower_proof,
11311157
fixed_in_evals,
11321158
fixed_opening_proof,
1133-
rw_hints_num_vars,
11341159
wits_in_evals,
11351160
wits_commit,
11361161
wits_opening_proof,

ceno_zkvm/src/scheme/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ fn test_rw_lk_expression_combination() {
166166
&vk.vp,
167167
verifier.vk.circuit_vks.get(&name).unwrap(),
168168
&proof,
169+
num_instances,
169170
&[],
170171
&mut v_transcript,
171172
NUM_FANIN,

0 commit comments

Comments
 (0)