Skip to content

Commit 845c987

Browse files
darth-cyKunming Jiangyczhangsjtukunxian-xia
authored
Verifier Cycle Reduction (#67)
Co-authored-by: Kunming Jiang <[email protected]> Co-authored-by: Yuncong Zhang <[email protected]> Co-authored-by: kunxian xia <[email protected]>
1 parent 1d469dd commit 845c987

File tree

9 files changed

+351
-167
lines changed

9 files changed

+351
-167
lines changed

src/basefold_verifier/basefold.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
use std::collections::BTreeMap;
2-
31
use itertools::Itertools;
42
use mpcs::basefold::structure::BasefoldProof as InnerBasefoldProof;
53
use openvm_native_compiler::{asm::AsmConfig, prelude::*};
6-
use openvm_native_compiler_derive::iter_zip;
74
use openvm_native_recursion::hints::{Hintable, VecAutoHintable};
85
use openvm_stark_sdk::p3_baby_bear::BabyBear;
96
use p3_field::extension::BinomialExtensionField;

src/basefold_verifier/query_phase.rs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,6 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
324324
builder: &mut Builder<C>,
325325
input: QueryPhaseVerifierInputVariable<C>,
326326
) {
327-
builder.cycle_tracker_start("Before checking opening proofs");
328327
let inv_2 = builder.constant(C::F::from_canonical_u32(0x3c000001));
329328
let two_adic_generators_inverses: Array<C, Felt<C::F>> = builder.dyn_array(28);
330329
for (index, val) in [
@@ -393,11 +392,11 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
393392
input.proof.commits.len() + Usize::from(1),
394393
input.fold_challenges.len(),
395394
);
396-
builder.cycle_tracker_end("Before checking opening proofs");
397395

398-
builder.cycle_tracker_start("Build round context");
399396
let rounds_context: Array<C, RoundContextVariable<C>> = builder.dyn_array(input.rounds.len());
400397
let batch_coeffs_offset: Var<C::N> = builder.constant(C::N::ZERO);
398+
399+
builder.cycle_tracker_start("Construct round context");
401400
iter_zip!(builder, input.rounds, rounds_context).for_each(|ptr_vec, builder| {
402401
let round = builder.iter_ptr_get(&input.rounds, ptr_vec[0]);
403402
// This buffer is not initialized here in providing the context.
@@ -465,13 +464,10 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
465464
};
466465
builder.iter_ptr_set(&rounds_context, ptr_vec[1], round_context);
467466
});
468-
builder.cycle_tracker_end("Build round context");
467+
builder.cycle_tracker_end("Construct round context");
469468

470-
builder.cycle_tracker_start("Checking opening proofs");
471469
iter_zip!(builder, input.indices, input.proof.query_opening_proof).for_each(
472470
|ptr_vec, builder| {
473-
builder.cycle_tracker_start("Checking opening proofs (per index)");
474-
builder.cycle_tracker_start("Prepare");
475471
// TODO: change type of input.indices to be `Array<C, Array<C, Var<C::N>>>`
476472
let idx = builder.iter_ptr_get(&input.indices, ptr_vec[0]);
477473
let idx = builder.unsafe_cast_var_to_felt(idx);
@@ -496,9 +492,8 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
496492
builder.set_value(&reduced_codeword_by_height, ptr_vec[0], zero_codeword);
497493
});
498494
let query = builder.iter_ptr_get(&input.proof.query_opening_proof, ptr_vec[1]);
499-
builder.cycle_tracker_end("Prepare");
500495

501-
builder.cycle_tracker_start("MMCS Verify Loop Rounds");
496+
builder.cycle_tracker_start("Batching and first FRI round");
502497
iter_zip!(builder, query.input_proofs, input.rounds, rounds_context).for_each(
503498
|ptr_vec, builder| {
504499
let batch_opening = builder.iter_ptr_get(&query.input_proofs, ptr_vec[0]);
@@ -584,9 +579,7 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
584579
mmcs_verify_batch(builder, mmcs_verifier_input);
585580
},
586581
);
587-
builder.cycle_tracker_end("MMCS Verify Loop Rounds");
588-
589-
builder.cycle_tracker_start("Initial folding");
582+
builder.cycle_tracker_end("Batching and first FRI round");
590583
let opening_ext = query.commit_phase_openings;
591584

592585
// fold 1st codeword
@@ -614,7 +607,6 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
614607
// check commit phases
615608
let commits = &input.proof.commits;
616609
builder.assert_eq::<Var<C::N>>(commits.len(), opening_ext.len());
617-
builder.cycle_tracker_end("Initial folding");
618610
builder.cycle_tracker_start("FRI rounds");
619611
let i: Var<C::N> = builder.constant(C::N::ZERO);
620612
iter_zip!(builder, commits, opening_ext).for_each(|ptr_vec, builder| {
@@ -697,8 +689,6 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
697689
builder.assign(&i, i_plus_one);
698690
});
699691
builder.cycle_tracker_end("FRI rounds");
700-
701-
builder.cycle_tracker_start("Finalizing");
702692
// assert that final_value[i] = folded
703693
let final_idx: Var<C::N> = builder.constant(C::N::ZERO);
704694
builder
@@ -713,13 +703,8 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
713703
});
714704
let final_value = builder.get(&final_codeword.values, final_idx);
715705
builder.assert_eq::<Ext<C::F, C::EF>>(final_value, folded);
716-
builder.cycle_tracker_end("Finalizing");
717-
builder.cycle_tracker_end("Checking opening proofs (per index)");
718706
},
719707
);
720-
builder.cycle_tracker_end("Checking opening proofs");
721-
722-
builder.cycle_tracker_start("Checking sumcheck proofs");
723708
// 1. check initial claim match with first round sumcheck value
724709
let batch_coeffs_offset: Var<C::N> = builder.constant(C::N::ZERO);
725710
let expected_sum: Ext<C::F, C::EF> = builder.constant(C::EF::ZERO);
@@ -766,9 +751,7 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
766751
let right: Ext<C::F, C::EF> = builder.eval(eval0 + eval1);
767752
builder.assert_eq::<Ext<C::F, C::EF>>(left, right);
768753
});
769-
builder.cycle_tracker_end("Checking sumcheck proofs");
770754

771-
builder.cycle_tracker_start("Checking final evaluations");
772755
// 3. check final evaluation are correct
773756
let final_evals = builder
774757
.get(&input.proof.sumcheck_proof, fold_len_minus_one.clone())
@@ -816,7 +799,6 @@ pub(crate) fn batch_verifier_query_phase<C: Config>(
816799
});
817800
builder.assert_eq::<Var<C::N>>(j, input.proof.final_message.len());
818801
builder.assert_eq::<Ext<C::F, C::EF>>(left, right);
819-
builder.cycle_tracker_end("Checking final evaluations");
820802
}
821803

822804
#[cfg(test)]

src/basefold_verifier/rs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use p3_field::FieldAlgebra;
1010
use serde::Deserialize;
1111

1212
use super::structs::*;
13-
use super::utils::{pow_felt, pow_felt_bits};
13+
use super::utils::pow_felt_bits;
1414

1515
pub type F = BabyBear;
1616
pub type E = BinomialExtensionField<F, DEGREE>;

src/basefold_verifier/verifier.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,8 @@ pub mod tests {
392392

393393
let system_config = SystemConfig::default()
394394
.with_public_values(4)
395-
.with_max_segment_len((1 << 25) - 100);
395+
.with_max_segment_len((1 << 25) - 100)
396+
.with_profiling();
396397
let config = NativeConfig::new(system_config, Native);
397398

398399
let executor = VmExecutor::<BabyBear, NativeConfig>::new(config);

src/e2e/mod.rs

Lines changed: 43 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,29 @@
11
use crate::basefold_verifier::basefold::BasefoldCommitment;
2-
use crate::basefold_verifier::query_phase::QueryPhaseVerifierInput;
3-
use crate::tower_verifier::binding::IOPProverMessage;
2+
use crate::tower_verifier::binding::{IOPProverMessage, IOPProverMessageVec};
43
use crate::zkvm_verifier::binding::{
54
GKRProofInput, LayerProofInput, SumcheckLayerProofInput, TowerProofInput, ZKVMChipProofInput,
65
ZKVMProofInput, E, F,
76
};
8-
use crate::zkvm_verifier::verifier::{verify_gkr_circuit, verify_zkvm_proof};
7+
8+
use crate::zkvm_verifier::verifier::verify_zkvm_proof;
99
use ceno_mle::util::ceil_log2;
10-
use ceno_transcript::BasicTranscript;
10+
use ceno_zkvm::scheme::ZKVMProof;
11+
use ceno_zkvm::structs::ZKVMVerifyingKey;
1112
use ff_ext::BabyBearExt4;
12-
use gkr_iop::gkr::{
13-
layer::sumcheck_layer::{SumcheckLayer, SumcheckLayerProof},
14-
GKRCircuit,
15-
};
16-
use itertools::Itertools;
1713
use mpcs::{Basefold, BasefoldRSParams};
18-
use openvm_circuit::arch::{
19-
instructions::program::Program, verify_single, SystemConfig, VirtualMachine, VmExecutor,
20-
};
21-
use openvm_native_circuit::{Native, NativeConfig};
14+
use openvm_circuit::arch::instructions::program::Program;
2215
use openvm_native_compiler::{
2316
asm::AsmBuilder,
2417
conversion::{convert_program, CompilerOptions},
2518
prelude::AsmCompiler,
2619
};
2720
use openvm_native_recursion::hints::Hintable;
2821
use openvm_stark_backend::config::StarkGenericConfig;
29-
use openvm_stark_sdk::{
30-
config::{
31-
baby_bear_poseidon2::{BabyBearPoseidon2Config, BabyBearPoseidon2Engine},
32-
fri_params::standard_fri_params_with_100_bits_conjectured_security,
33-
setup_tracing_with_log_level, FriParameters,
34-
},
35-
engine::StarkFriEngine,
36-
p3_baby_bear::BabyBear,
37-
};
38-
use std::fs::File;
22+
use openvm_stark_sdk::config::baby_bear_poseidon2::BabyBearPoseidon2Config;
3923

4024
type SC = BabyBearPoseidon2Config;
4125
type EF = <SC as StarkGenericConfig>::Challenge;
4226

43-
use ceno_zkvm::{
44-
scheme::{verifier::ZKVMVerifier, ZKVMProof},
45-
structs::{ComposedConstrainSystem, ZKVMVerifyingKey},
46-
};
47-
4827
pub fn parse_zkvm_proof_import(
4928
zkvm_proof: ZKVMProof<BabyBearExt4, Basefold<BabyBearExt4, BasefoldRSParams>>,
5029
vk: &ZKVMVerifyingKey<BabyBearExt4, Basefold<BabyBearExt4, BasefoldRSParams>>,
@@ -112,10 +91,11 @@ pub fn parse_zkvm_proof_import(
11291

11392
// Tower proof
11493
let mut tower_proof = TowerProofInput::default();
115-
let mut proofs: Vec<Vec<IOPProverMessage>> = vec![];
94+
let mut proofs: Vec<IOPProverMessageVec> = vec![];
11695

11796
for proof in &chip_proof.tower_proof.proofs {
118-
let mut proof_messages: Vec<IOPProverMessage> = vec![];
97+
let mut proof_messages: Vec<E> = vec![];
98+
let mut prover_message_size = None;
11999
for m in proof {
120100
let mut evaluations_vec: Vec<E> = vec![];
121101

@@ -124,11 +104,17 @@ pub fn parse_zkvm_proof_import(
124104
serde_json::from_value(serde_json::to_value(v.clone()).unwrap()).unwrap();
125105
evaluations_vec.push(v_e);
126106
}
127-
proof_messages.push(IOPProverMessage {
128-
evaluations: evaluations_vec,
129-
});
107+
if let Some(size) = prover_message_size {
108+
assert_eq!(size, evaluations_vec.len());
109+
} else {
110+
prover_message_size = Some(evaluations_vec.len());
111+
}
112+
proof_messages.extend_from_slice(&evaluations_vec);
130113
}
131-
proofs.push(proof_messages);
114+
proofs.push(IOPProverMessageVec {
115+
prover_message_size: prover_message_size.unwrap(),
116+
data: proof_messages,
117+
});
132118
}
133119
tower_proof.num_proofs = proofs.len();
134120
tower_proof.proofs = proofs;
@@ -149,7 +135,7 @@ pub fn parse_zkvm_proof_import(
149135
prod_specs_eval.push(inner_v);
150136
}
151137
tower_proof.num_prod_specs = prod_specs_eval.len();
152-
tower_proof.prod_specs_eval = prod_specs_eval;
138+
tower_proof.prod_specs_eval = prod_specs_eval.into();
153139

154140
let mut logup_specs_eval: Vec<Vec<Vec<E>>> = vec![];
155141
for inner_val in &chip_proof.tower_proof.logup_specs_eval {
@@ -167,23 +153,36 @@ pub fn parse_zkvm_proof_import(
167153
logup_specs_eval.push(inner_v);
168154
}
169155
tower_proof.num_logup_specs = logup_specs_eval.len();
170-
tower_proof.logup_specs_eval = logup_specs_eval;
156+
tower_proof.logup_specs_eval = logup_specs_eval.into();
171157

172158
// main constraint and select sumcheck proof
173-
let mut main_sumcheck_proofs: Vec<IOPProverMessage> = vec![];
174-
if chip_proof.main_sumcheck_proofs.is_some() {
159+
let main_sumcheck_proofs = if chip_proof.main_sumcheck_proofs.is_some() {
160+
let mut main_sumcheck_proofs: Vec<E> = vec![];
161+
let mut prover_message_size = None;
175162
for m in chip_proof.main_sumcheck_proofs.as_ref().unwrap() {
176163
let mut evaluations_vec: Vec<E> = vec![];
177164
for v in &m.evaluations {
178165
let v_e: E =
179166
serde_json::from_value(serde_json::to_value(v.clone()).unwrap()).unwrap();
180167
evaluations_vec.push(v_e);
181168
}
182-
main_sumcheck_proofs.push(IOPProverMessage {
183-
evaluations: evaluations_vec,
184-
});
169+
main_sumcheck_proofs.extend_from_slice(&evaluations_vec);
170+
if let Some(size) = prover_message_size {
171+
assert_eq!(size, evaluations_vec.len());
172+
} else {
173+
prover_message_size = Some(evaluations_vec.len());
174+
}
185175
}
186-
}
176+
IOPProverMessageVec {
177+
prover_message_size: prover_message_size.unwrap(),
178+
data: main_sumcheck_proofs,
179+
}
180+
} else {
181+
IOPProverMessageVec {
182+
prover_message_size: 0,
183+
data: vec![],
184+
}
185+
};
187186

188187
let mut wits_in_evals: Vec<E> = vec![];
189188
for v in &chip_proof.wits_in_evals {
@@ -242,7 +241,7 @@ pub fn parse_zkvm_proof_import(
242241
(
243242
1,
244243
SumcheckLayerProofInput {
245-
proof: iop_messages,
244+
proof: iop_messages.into(),
246245
evals,
247246
},
248247
)
@@ -270,7 +269,7 @@ pub fn parse_zkvm_proof_import(
270269
}
271270

272271
let main = SumcheckLayerProofInput {
273-
proof: iop_messages,
272+
proof: iop_messages.into(),
274273
evals,
275274
};
276275

0 commit comments

Comments
 (0)