Skip to content

Commit 1e1635b

Browse files
committed
optimize iop_verifier_state_verify
1 parent c2e58cf commit 1e1635b

6 files changed

Lines changed: 120 additions & 24 deletions

File tree

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ceno_recursion/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,12 @@ name = "e2e_aggregate"
5252
path = "src/bin/e2e_aggregate.rs"
5353

5454
[features]
55-
bench-metrics = ["openvm-circuit/metrics"]
55+
bench-metrics = ["openvm-sdk/metrics"]
5656
default = ["parallel", "nightly-features"]
5757
gpu = ["ceno_zkvm/gpu", "openvm-circuit/cuda", "openvm-native-circuit/cuda", "dep:openvm-cuda-backend"]
5858
nightly-features = [
5959
"ceno_zkvm/nightly-features",
6060
"openvm-stark-sdk/nightly-features",
6161
]
6262
parallel = ["openvm-stark-backend/parallel"]
63+
perf-metrics = ["openvm-sdk/perf-metrics"]

ceno_recursion/src/arithmetics/mod.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,52 @@ impl<C: Config> UniPolyExtrapolator<C> {
927927
res
928928
}
929929

930+
pub fn extrapolate_uni_poly_deg1(
931+
&self,
932+
builder: &mut Builder<C>,
933+
p_i_0: Ext<C::F, C::EF>,
934+
p_i_1: Ext<C::F, C::EF>,
935+
eval_at: Ext<C::F, C::EF>,
936+
) -> Ext<C::F, C::EF> {
937+
self.extrapolate_uni_poly_deg_1(builder, p_i_0, p_i_1, eval_at)
938+
}
939+
940+
pub fn extrapolate_uni_poly_deg2(
941+
&self,
942+
builder: &mut Builder<C>,
943+
p_i_0: Ext<C::F, C::EF>,
944+
p_i_1: Ext<C::F, C::EF>,
945+
p_i_2: Ext<C::F, C::EF>,
946+
eval_at: Ext<C::F, C::EF>,
947+
) -> Ext<C::F, C::EF> {
948+
self.extrapolate_uni_poly_deg_2(builder, p_i_0, p_i_1, p_i_2, eval_at)
949+
}
950+
951+
pub fn extrapolate_uni_poly_deg3(
952+
&self,
953+
builder: &mut Builder<C>,
954+
p_i_0: Ext<C::F, C::EF>,
955+
p_i_1: Ext<C::F, C::EF>,
956+
p_i_2: Ext<C::F, C::EF>,
957+
p_i_3: Ext<C::F, C::EF>,
958+
eval_at: Ext<C::F, C::EF>,
959+
) -> Ext<C::F, C::EF> {
960+
self.extrapolate_uni_poly_deg_3(builder, p_i_0, p_i_1, p_i_2, p_i_3, eval_at)
961+
}
962+
963+
pub fn extrapolate_uni_poly_deg4(
964+
&self,
965+
builder: &mut Builder<C>,
966+
p_i_0: Ext<C::F, C::EF>,
967+
p_i_1: Ext<C::F, C::EF>,
968+
p_i_2: Ext<C::F, C::EF>,
969+
p_i_3: Ext<C::F, C::EF>,
970+
p_i_4: Ext<C::F, C::EF>,
971+
eval_at: Ext<C::F, C::EF>,
972+
) -> Ext<C::F, C::EF> {
973+
self.extrapolate_uni_poly_deg_4(builder, p_i_0, p_i_1, p_i_2, p_i_3, p_i_4, eval_at)
974+
}
975+
930976
fn extrapolate_uni_poly_deg_1(
931977
&self,
932978
builder: &mut Builder<C>,

ceno_recursion/src/tower_verifier/program.rs

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use crate::{
55
exts_to_felts,
66
},
77
tower_verifier::binding::IOPProverMessageVecVariable,
8-
transcript::transcript_observe_label,
8+
transcript::{
9+
transcript_label_as_array, transcript_observe_label, transcript_observe_label_felts,
10+
},
911
zkvm_verifier::binding::TowerProofInputVariable,
1012
};
1113
use openvm_native_compiler::prelude::*;
@@ -22,51 +24,78 @@ pub fn iop_verifier_state_verify<C: Config>(
2224
out_claim: &Ext<C::F, C::EF>,
2325
prover_messages: &IOPProverMessageVecVariable<C>,
2426
max_num_variables: Felt<C::F>,
25-
max_degree: Felt<C::F>,
27+
max_degree: usize,
2628
unipoly_extrapolator: &UniPolyExtrapolator<C>,
2729
) -> (
2830
Array<C, Ext<<C as Config>::F, <C as Config>::EF>>,
2931
Ext<<C as Config>::F, <C as Config>::EF>,
3032
) {
31-
// TODO: either store it in a global cache or pass them as parameters
32-
let zero: Ext<C::F, C::EF> = builder.constant(C::EF::ZERO);
3333
let zero_f: Felt<C::F> = builder.constant(C::F::ZERO);
3434

35+
let max_degree_felt: Felt<C::F> = builder.constant(C::F::from_canonical_usize(max_degree));
3536
let max_num_variables_usize: Usize<C::N> =
3637
Usize::from(builder.cast_felt_to_var(max_num_variables));
3738
challenger.observe(builder, max_num_variables);
3839
challenger.observe(builder, zero_f);
39-
challenger.observe(builder, max_degree);
40+
challenger.observe(builder, max_degree_felt);
4041
challenger.observe(builder, zero_f);
4142

4243
builder.assert_var_eq(max_num_variables_usize.get_var(), prover_messages.len());
4344

4445
let challenges: Array<C, Ext<C::F, C::EF>> = builder.dyn_array(max_num_variables_usize.clone());
45-
let expected: Ext<C::F, C::EF> = builder.eval(*out_claim + zero);
46+
let expected: Ext<C::F, C::EF> = builder.eval(*out_claim);
47+
let internal_round_label = transcript_label_as_array(builder, b"Internal round");
4648

4749
builder.cycle_tracker_start("IOPVerifierState::verify_round_and_update_state");
50+
let curr_offset: Var<C::N> = builder.eval(C::N::ZERO);
4851
builder
4952
.range(0, max_num_variables_usize.clone())
5053
.for_each(|i_vec, builder| {
5154
let i = i_vec[0];
5255

53-
// TODO: this takes 7 cycles, can we optimize it?
54-
let prover_msg = prover_messages.get(builder, i.variable());
56+
let next_offset: Var<C::N> =
57+
builder.eval(curr_offset + prover_messages.prover_message_size);
58+
let prover_msg = prover_messages
59+
.evaluations
60+
.slice(builder, curr_offset, next_offset);
61+
builder.assign(&curr_offset, next_offset);
5562

5663
unsafe {
5764
let prover_msg_felts = exts_to_felts(builder, &prover_msg);
5865
challenger_multi_observe(builder, challenger, &prover_msg_felts);
5966
}
6067

61-
transcript_observe_label(builder, challenger, b"Internal round");
68+
transcript_observe_label_felts(builder, challenger, &internal_round_label);
6269
let challenge = challenger.sample_ext(builder);
6370

6471
let e1 = builder.get(&prover_msg, 0);
6572
let e0 = builder.eval(expected - e1);
66-
let p_r =
67-
unipoly_extrapolator.extrapolate_uni_poly(builder, e0, &prover_msg, challenge);
68-
69-
builder.assign(&expected, p_r + zero);
73+
let p_r = match max_degree {
74+
1 => unipoly_extrapolator.extrapolate_uni_poly_deg1(builder, e0, e1, challenge),
75+
2 => {
76+
let p1 = e1;
77+
let p2 = builder.get(&prover_msg, 1);
78+
unipoly_extrapolator.extrapolate_uni_poly_deg2(builder, e0, p1, p2, challenge)
79+
}
80+
3 => {
81+
let p1 = e1;
82+
let p2 = builder.get(&prover_msg, 1);
83+
let p3 = builder.get(&prover_msg, 2);
84+
unipoly_extrapolator
85+
.extrapolate_uni_poly_deg3(builder, e0, p1, p2, p3, challenge)
86+
}
87+
4 => {
88+
let p1 = e1;
89+
let p2 = builder.get(&prover_msg, 1);
90+
let p3 = builder.get(&prover_msg, 2);
91+
let p4 = builder.get(&prover_msg, 3);
92+
unipoly_extrapolator
93+
.extrapolate_uni_poly_deg4(builder, e0, p1, p2, p3, p4, challenge)
94+
}
95+
_ => panic!("unsupported max_degree {max_degree}"),
96+
};
97+
98+
builder.assign(&expected, p_r);
7099
builder.set_value(&challenges, i, challenge);
71100
});
72101
builder.cycle_tracker_end("IOPVerifierState::verify_round_and_update_state");
@@ -258,16 +287,14 @@ pub fn verify_tower_proof<C: Config>(
258287
let max_num_variables: Felt<C::F> = builder.constant(C::F::ONE);
259288
builder.assign(&max_num_variables, max_num_variables + round);
260289

261-
let max_degree = builder.constant(C::F::from_canonical_usize(3));
262-
263290
builder.cycle_tracker_start("sumcheck verify");
264291
let (sub_rt, sub_e) = iop_verifier_state_verify(
265292
builder,
266293
challenger,
267294
out_claim,
268295
&prover_messages,
269296
max_num_variables,
270-
max_degree,
297+
3,
271298
unipoly_extrapolator,
272299
);
273300
builder.cycle_tracker_end("sumcheck verify");

ceno_recursion/src/transcript/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use openvm_native_recursion::challenger::{
55
};
66
use openvm_stark_backend::p3_field::FieldAlgebra;
77

8+
use crate::arithmetics::challenger_multi_observe;
9+
810
pub fn transcript_observe_label<C: Config>(
911
builder: &mut Builder<C>,
1012
challenger: &mut DuplexChallengerVariable<C>,
@@ -17,6 +19,27 @@ pub fn transcript_observe_label<C: Config>(
1719
}
1820
}
1921

22+
pub fn transcript_label_as_array<C: Config>(
23+
builder: &mut Builder<C>,
24+
label: &[u8],
25+
) -> Array<C, Felt<C::F>> {
26+
let label_f = <BabyBearExt4 as CenoExtensionField>::BaseField::bytes_to_field_elements(label);
27+
let arr: Array<C, Felt<C::F>> = builder.dyn_array(label_f.len());
28+
for (idx, n) in label_f.into_iter().enumerate() {
29+
let f: Felt<C::F> = builder.constant(C::F::from_canonical_u64(n.to_canonical_u64()));
30+
builder.set_value(&arr, idx, f);
31+
}
32+
arr
33+
}
34+
35+
pub fn transcript_observe_label_felts<C: Config>(
36+
builder: &mut Builder<C>,
37+
challenger: &mut DuplexChallengerVariable<C>,
38+
label_felts: &Array<C, Felt<C::F>>,
39+
) {
40+
challenger_multi_observe(builder, challenger, label_felts);
41+
}
42+
2043
pub fn transcript_check_pow_witness<C: Config>(
2144
builder: &mut Builder<C>,
2245
challenger: &mut DuplexChallengerVariable<C>,

ceno_recursion/src/zkvm_verifier/verifier.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -953,8 +953,6 @@ pub fn verify_gkr_circuit<C: Config>(
953953
});
954954

955955
// sigma = \sum_b sel(b) * zero_expr(b)
956-
let max_degree = builder.constant(C::F::from_canonical_usize(layer.max_expr_degree + 1));
957-
958956
let max_num_variables_f = builder.unsafe_cast_var_to_felt(max_num_variables.get_var());
959957

960958
let (in_point, expected_evaluation) = iop_verifier_state_verify(
@@ -963,7 +961,7 @@ pub fn verify_gkr_circuit<C: Config>(
963961
&sigma,
964962
&proof,
965963
max_num_variables_f,
966-
max_degree,
964+
layer.max_expr_degree + 1,
967965
unipoly_extrapolator,
968966
);
969967

@@ -1204,15 +1202,14 @@ pub fn verify_rotation<C: Config>(
12041202
let sigma: Ext<C::F, C::EF> = builder.constant(C::EF::ZERO);
12051203

12061204
let max_num_variables = builder.unsafe_cast_var_to_felt(max_num_variables.get_var());
1207-
let max_degree: Felt<C::F> = builder.constant(C::F::TWO);
12081205

12091206
let (origin_point, expected_evaluation) = iop_verifier_state_verify(
12101207
builder,
12111208
challenger,
12121209
&sigma,
12131210
proof,
12141211
max_num_variables,
1215-
max_degree,
1212+
2,
12161213
unipoly_extrapolator,
12171214
);
12181215

@@ -1756,15 +1753,14 @@ pub fn verify_ecc_proof<C: Config>(
17561753

17571754
let one_ext: Ext<C::F, C::EF> = builder.constant(C::EF::ONE);
17581755
let zero_ext: Ext<C::F, C::EF> = builder.constant(C::EF::ZERO);
1759-
let three_f: Felt<C::F> = builder.constant(C::F::from_canonical_u32(3));
17601756
let num_vars_f = builder.unsafe_cast_var_to_felt(num_vars.get_var());
17611757
let (rt, sumcheck_expected_evaluation) = iop_verifier_state_verify(
17621758
builder,
17631759
challenger,
17641760
&zero_ext,
17651761
&proof.zerocheck_proof,
17661762
num_vars_f,
1767-
three_f,
1763+
3,
17681764
unipoly_extrapolator,
17691765
);
17701766

0 commit comments

Comments
 (0)