diff --git a/ceno_recursion/src/aggregation/mod.rs b/ceno_recursion/src/aggregation/mod.rs index 27d6288c0..44291c244 100644 --- a/ceno_recursion/src/aggregation/mod.rs +++ b/ceno_recursion/src/aggregation/mod.rs @@ -377,7 +377,9 @@ impl CenoLeafVmVerifierConfig { let mut builder = Builder::::default(); { + builder.cycle_tracker_start("Read Ceno ZKVM Proof"); let ceno_leaf_input = CenoLeafVmVerifierInput::read(&mut builder); + builder.cycle_tracker_end("Read Ceno ZKVM Proof"); let stark_pvs = VmVerifierPvs::>::uninit(&mut builder); builder.cycle_tracker_start("Verify Ceno ZKVM Proof"); diff --git a/ceno_recursion/src/tower_verifier/program.rs b/ceno_recursion/src/tower_verifier/program.rs index 33efc16d8..cf38b3f27 100644 --- a/ceno_recursion/src/tower_verifier/program.rs +++ b/ceno_recursion/src/tower_verifier/program.rs @@ -427,73 +427,7 @@ pub fn verify_tower_proof( &next_layer_evals, ); - let next_round = builder.eval_expr(round_var + RVar::from(1)); - builder - .range(0, num_prod_spec.clone()) - .for_each(|i_vec, builder| { - let spec_index = i_vec[0]; - let skip = builder.get(&should_skip, spec_index); - let max_round = builder.get(&num_variables, spec_index); - let round_limit: RVar = builder.eval_expr(max_round - RVar::from(1)); - - // now skip is 0 if and only if current round_var is smaller than round_limit. - builder.if_eq(skip, var_zero).then(|builder| { - builder.if_eq(next_round, round_limit).then(|builder| { - let evals_idx: Usize = builder.eval(spec_index + Usize::from(1)); - let evals = builder.get(&next_layer_evals, evals_idx); - - let point_and_eval: PointAndEvalVariable = - builder.eval(PointAndEvalVariable { - point: PointVariable { - fs: rt_prime.clone(), - }, - eval: evals, - }); - builder.set_value(&prod_spec_point_n_eval, spec_index, point_and_eval); - }); - }); - }); - - let num_variables_len = num_variables.len(); - let logup_num_variables_slice = - num_variables.slice(builder, num_prod_spec.clone(), num_variables_len.clone()); - - builder - .range(0, num_logup_spec.clone()) - .for_each(|i_vec, builder| { - let spec_index = i_vec[0]; - let max_round = builder.get(&logup_num_variables_slice, spec_index); - let round_limit: RVar = builder.eval_expr(max_round - RVar::from(1)); - let idx: Var = builder.eval(spec_index.variable() + num_prod_spec.get_var()); - let skip = builder.get(&should_skip, idx); - - // now skip is 0 if and only if current round_var is smaller than round_limit. - builder.if_eq(skip, var_zero).then(|builder| { - builder.if_eq(next_round, round_limit).then(|builder| { - let p_idx: Usize = builder.eval(idx + Usize::from(1)); - let q_idx: Usize = - builder.eval(idx + Usize::from(1) + num_logup_spec.clone()); - let p_eval = builder.get(&next_layer_evals, p_idx); - let q_eval = builder.get(&next_layer_evals, q_idx); - - let p_eval: PointAndEvalVariable = builder.eval(PointAndEvalVariable { - point: PointVariable { - fs: rt_prime.clone(), - }, - eval: p_eval, - }); - let q_eval: PointAndEvalVariable = builder.eval(PointAndEvalVariable { - point: PointVariable { - fs: rt_prime.clone(), - }, - eval: q_eval, - }); - builder.set_value(&logup_spec_p_point_n_eval, spec_index, p_eval); - builder.set_value(&logup_spec_q_point_n_eval, spec_index, q_eval); - }); - }); - }); - + // extract next layer's expected sum let output_eval = builder.get(&next_layer_evals, 0); builder.assign(&curr_pt, rt_prime.clone()); builder.assign(&curr_eval, output_eval); @@ -512,6 +446,53 @@ pub fn verify_tower_proof( ); }); + builder.if_ne(op_range, Usize::from(0)).then(|builder| { + // update prod_spec and logup_spec evaluations at next_rt + let product_evals = { + let start: Var = builder.eval(Usize::from(1)); + let end: Var = builder.eval(start + num_prod_spec.clone()); + next_layer_evals.slice(builder, start, end) + }; + let logup_evals = { + let start: Var = builder.eval(Usize::from(1) + num_prod_spec.clone()); + let end: Var = builder.eval(start + Usize::from(2) * num_logup_spec.clone()); + next_layer_evals.slice(builder, start, end) + }; + + builder + .range(0, num_prod_spec.clone()) + .for_each(|i_vec, builder| { + let i = i_vec[0]; + let eval = builder.get(&product_evals, i); + + let point_and_eval: PointAndEvalVariable = builder.eval(PointAndEvalVariable { + point: next_rt.point.clone(), + eval, + }); + builder.set_value(&prod_spec_point_n_eval, i, point_and_eval); + }); + builder + .range(0, num_logup_spec.clone()) + .for_each(|i_vec, builder| { + let i = i_vec[0]; + let p_idx = i; + let q_idx: Var = builder.eval(num_logup_spec.clone() + i); + let p_eval = builder.get(&logup_evals, p_idx); + let q_eval = builder.get(&logup_evals, q_idx); + + let p_eval: PointAndEvalVariable = builder.eval(PointAndEvalVariable { + point: next_rt.point.clone(), + eval: p_eval, + }); + let q_eval: PointAndEvalVariable = builder.eval(PointAndEvalVariable { + point: next_rt.point.clone(), + eval: q_eval, + }); + builder.set_value(&logup_spec_p_point_n_eval, i, p_eval); + builder.set_value(&logup_spec_q_point_n_eval, i, q_eval); + }); + }); + ( next_rt.point, prod_spec_point_n_eval,