Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 33 additions & 17 deletions ceno_zkvm/src/scheme/cpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,42 +482,58 @@ impl CpuTowerProver {

proofs.push_sumcheck_proofs(sumcheck_proofs.proofs);

// rt' = r_merge || rt
let r_merge = transcript.sample_and_append_vec(b"merge", log_num_fanin);
let rt_prime = [state.collect_raw_challenges(), r_merge].concat();

// generate next round challenge
let next_alpha_pows = get_challenge_pows(
prod_specs_len + logup_specs_len * 2, /* logup occupy 2 sumcheck: numerator and denominator */
transcript,
);
let evals = state.get_mle_flatten_final_evaluations();
// Bind prod/logup evals into transcript before sampling r_merge (Fiat-Shamir soundness).
// retrieve final evaluation to proof
let mut prod_evals_per_spec = Vec::with_capacity(prod_specs_len);
for (i, witness_prod_expr) in witness_prod_expr.iter().enumerate().take(prod_specs_len)
{
let evals = witness_prod_expr
let spec_evals = witness_prod_expr
.iter()
.map(|expr| match expr {
Expression::WitIn(wit_id) => evals[*wit_id as usize],
_ => unreachable!(),
})
.collect_vec();
if !evals.is_empty() {
assert_eq!(evals.len(), num_fanin);
proofs.push_prod_evals_and_point(i, evals, rt_prime.clone());
if !spec_evals.is_empty() {
assert_eq!(spec_evals.len(), num_fanin);
transcript.append_field_element_exts(&spec_evals);
}
prod_evals_per_spec.push((i, spec_evals));
}
let mut logup_evals_per_spec = Vec::with_capacity(logup_specs_len);
for (i, witness_lk_expr) in witness_lk_expr.iter().enumerate().take(logup_specs_len) {
let evals = witness_lk_expr
let spec_evals = witness_lk_expr
.iter()
.map(|expr| match expr {
Expression::WitIn(wit_id) => evals[*wit_id as usize],
_ => unreachable!(),
})
.collect_vec();
if !evals.is_empty() {
assert_eq!(evals.len(), 4); // p1, p2, q1, q2
proofs.push_logup_evals_and_point(i, evals, rt_prime.clone());
if !spec_evals.is_empty() {
assert_eq!(spec_evals.len(), 4); // p1, p2, q1, q2
transcript.append_field_element_exts(&spec_evals);
}
logup_evals_per_spec.push((i, spec_evals));
Comment thread
hero78119 marked this conversation as resolved.
Outdated
}

// rt' = r_merge || rt
let r_merge = transcript.sample_and_append_vec(b"merge", log_num_fanin);
let rt_prime = [state.collect_raw_challenges(), r_merge].concat();

// generate next round challenge
let next_alpha_pows = get_challenge_pows(
prod_specs_len + logup_specs_len * 2, /* logup occupy 2 sumcheck: numerator and denominator */
transcript,
);
for (i, spec_evals) in prod_evals_per_spec {
if !spec_evals.is_empty() {
proofs.push_prod_evals_and_point(i, spec_evals, rt_prime.clone());
}
}
for (i, spec_evals) in logup_evals_per_spec {
if !spec_evals.is_empty() {
proofs.push_logup_evals_and_point(i, spec_evals, rt_prime.clone());
}
}
out_rt = rt_prime;
Expand Down
12 changes: 12 additions & 0 deletions ceno_zkvm/src/scheme/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,18 @@ impl TowerVerify {
let rt: Point<E> = sumcheck_claim.point.iter().map(|c| c.elements).collect();
let eq = eq_eval(out_rt, &rt);

// Bind prover-supplied prod/logup evals into transcript (Fiat-Shamir soundness).
for spec_index in 0..num_prod_spec {
if round < num_variables[spec_index] - 1 {
transcript.append_field_element_exts(&tower_proofs.prod_specs_eval[spec_index][round]);
}
}
for spec_index in 0..num_logup_spec {
if round < num_variables[num_prod_spec + spec_index] - 1 {
transcript.append_field_element_exts(&tower_proofs.logup_specs_eval[spec_index][round]);
}
}

let expected_evaluation: E = (0..num_prod_spec)
.zip(alpha_pows.iter())
.zip(num_variables.iter())
Expand Down
9 changes: 5 additions & 4 deletions gkr_iop/src/gkr/layer/cpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,10 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> SumcheckLayerProver<
builder.to_virtual_polys(&[layer.exprs[0].clone()], challenges),
transcript,
);
let evals = prover_state.get_mle_flatten_final_evaluations();
transcript.append_field_element_exts(&evals);
LayerProof {
main: SumcheckLayerProof {
proof,
evals: prover_state.get_mle_flatten_final_evaluations(),
},
main: SumcheckLayerProof { proof, evals },
rotation: None,
}
}
Expand Down Expand Up @@ -262,6 +261,7 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZerocheckLayerProver
);

let evals = prover_state.get_mle_flatten_final_evaluations();
transcript.append_field_element_exts(&evals);
exit_span!(span);
(
LayerProof {
Expand Down Expand Up @@ -409,6 +409,7 @@ pub(crate) fn prove_rotation<E: ExtensionField, PCS: PolynomialCommitmentScheme<
})
.collect::<Vec<E>>();
exit_span!(span);
transcript.append_field_element_exts(&evals);
(
SumcheckLayerProof {
proof: rotation_proof,
Expand Down
2 changes: 2 additions & 0 deletions gkr_iop/src/gkr/layer/gpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZerocheckLayerProver
let row_challenges_e =
unsafe { std::mem::transmute::<Vec<BB31Ext>, Vec<E>>(row_challenges) };

transcript.append_field_element_exts(&evals_gpu_e);
exit_span!(span);
(
LayerProof {
Expand Down Expand Up @@ -467,6 +468,7 @@ pub(crate) fn prove_rotation_gpu<E: ExtensionField, PCS: PolynomialCommitmentSch
})
.collect::<Vec<E>>();
exit_span!(span);
transcript.append_field_element_exts(&evals);

(
SumcheckLayerProof {
Expand Down
3 changes: 3 additions & 0 deletions gkr_iop/src/gkr/layer/sumcheck_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ impl<E: ExtensionField> SumcheckLayer<E> for Layer<E> {
transcript,
);

// Bind the prover-supplied evaluations into the transcript (Fiat-Shamir soundness).
transcript.append_field_element_exts(&evals);

// Check the final evaluations.
let got_claim =
eval_by_expr_with_instance(&[], &evals, &[], &[], challenges, &self.exprs[0])
Expand Down
6 changes: 6 additions & 0 deletions gkr_iop/src/gkr/layer/zerocheck_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,9 @@ impl<E: ExtensionField> ZerocheckLayer<E> for Layer<E> {
);
let in_point = in_point.into_iter().map(|c| c.elements).collect_vec();

// Bind the prover-supplied evaluations into the transcript (Fiat-Shamir soundness).
transcript.append_field_element_exts(&main_evals);

let structural_witin_offset = self.n_witin + self.n_fixed + self.n_instance;
// eval selector and set to respective witin
izip!(
Expand Down Expand Up @@ -742,6 +745,9 @@ fn verify_rotation<E: ExtensionField>(
);
let origin_point = in_point.into_iter().map(|c| c.elements).collect_vec();

// Bind the prover-supplied rotation evaluations into the transcript (Fiat-Shamir soundness).
transcript.append_field_element_exts(&evals);

// compute the selector evaluation
let bh = BooleanHypercube::new(rotation_cyclic_group_log2);
let selector_eval = rotation_selector_eval(
Expand Down
Loading