29 using ClaimBatch =
typename ClaimBatcher::Batch;
34 transcript->load_proof(proof);
37 transcript->add_to_hash_buffer(
"vk_hash", vk_hash);
38 vinfo(
"ECCVM vk hash: ", vk_hash);
44 commitments.gemini_masking_poly = transcript->template receive_from_prover<Commitment>(
"Gemini:masking_poly_comm");
45 for (
auto [comm, label] :
zip_view(commitments.get_wires(), commitment_labels.get_wires())) {
46 comm = transcript->template receive_from_prover<Commitment>(label);
52 auto beta_sqr = beta * beta;
53 auto beta_quartic = beta_sqr * beta_sqr;
54 relation_parameters.
gamma = gamma;
55 relation_parameters.
beta = beta;
56 relation_parameters.
beta_sqr = beta_sqr;
57 relation_parameters.
beta_cube = beta_sqr * beta;
59 auto first_term_tag = beta_quartic;
61 (gamma + beta_sqr + beta_sqr + first_term_tag) *
62 (gamma + beta_sqr + beta_sqr + beta_sqr + first_term_tag);
66 commitments.lookup_inverses =
67 transcript->template receive_from_prover<Commitment>(commitment_labels.lookup_inverses);
68 commitments.z_perm = transcript->template receive_from_prover<Commitment>(commitment_labels.z_perm);
72 const FF alpha = transcript->template get_challenge<FF>(
"Sumcheck:alpha");
77 std::vector<FF> gate_challenges =
78 transcript->template get_dyadic_powers_of_challenge<FF>(
"Sumcheck:gate_challenge", CONST_ECCVM_LOG_N);
81 std::array<Commitment, NUM_LIBRA_COMMITMENTS> libra_commitments = {};
83 libra_commitments[0] = transcript->template receive_from_prover<Commitment>(
"Libra:concatenation_commitment");
84 auto sumcheck_output = sumcheck.
verify(relation_parameters, gate_challenges);
86 libra_commitments[1] = transcript->template receive_from_prover<Commitment>(
"Libra:grand_sum_commitment");
87 libra_commitments[2] = transcript->template receive_from_prover<Commitment>(
"Libra:quotient_commitment");
92 ClaimBatcher claim_batcher{
93 .unshifted = ClaimBatch{ commitments.get_unshifted(), sumcheck_output.claimed_evaluations.get_unshifted() },
94 .shifted = ClaimBatch{ commitments.get_to_be_shifted(), sumcheck_output.claimed_evaluations.get_shifted() }
97 auto [sumcheck_batch_opening_claims, consistency_checked] =
98 Shplemini::compute_batch_opening_claim(claim_batcher,
99 sumcheck_output.challenge,
104 sumcheck_output.claimed_libra_evaluation,
105 sumcheck_output.round_univariate_commitments,
106 sumcheck_output.round_univariate_evaluations);
110 PCS::reduce_batch_opening_claim(sumcheck_batch_opening_claims);
115 std::vector<Commitment> translation_commitments = { commitments.transcript_op,
116 commitments.transcript_Px,
117 commitments.transcript_Py,
118 commitments.transcript_z1,
119 commitments.transcript_z2 };
120 compute_translation_opening_claims(translation_commitments);
122 opening_claims.back() = multivariate_to_univariate_opening_claim;
125 const OpeningClaim batch_opening_claim = Shplonk::reduce_verification(pcs_g1_identity, opening_claims, transcript);
127 bool sumcheck_verified = sumcheck_output.verified;
128 vinfo(
"ECCVM Verifier: sumcheck verified: ", sumcheck_verified);
129 vinfo(
"ECCVM Verifier: consistency checked: ", consistency_checked);
130 vinfo(
"ECCVM Verifier: translation masking consistency checked: ", translation_masking_consistency_checked);
132 compute_accumulated_result();
134 return { batch_opening_claim, sumcheck_verified && consistency_checked && translation_masking_consistency_checked };
155 const auto labels = SmallIPA::evaluation_labels(
"Translation:");
160 transcript->template receive_from_prover<Commitment>(
"Translation:concatenated_masking_term_commitment");
163 evaluation_challenge_x = transcript->template get_challenge<FF>(
"Translation:evaluation_challenge_x");
166 for (
auto [eval, label] :
zip_view(translation_evaluations.get_all(), translation_evaluations.labels)) {
167 eval = transcript->template receive_from_prover<FF>(label);
171 batching_challenge_v = transcript->template get_challenge<FF>(
"Translation:batching_challenge_v");
174 translation_masking_term_eval = transcript->template receive_from_prover<FF>(
"Translation:masking_term_eval");
178 transcript->template receive_from_prover<Commitment>(
"Translation:grand_sum_commitment");
180 transcript->template receive_from_prover<Commitment>(
"Translation:quotient_commitment");
184 const FF small_ipa_evaluation_challenge =
185 transcript->template get_challenge<FF>(
"Translation:small_ipa_evaluation_challenge");
189 SmallIPA::evaluation_points(small_ipa_evaluation_challenge);
192 for (
size_t idx = 0; idx < NUM_SMALL_IPA_EVALUATIONS; idx++) {
193 small_ipa_evaluations[idx] = transcript->template receive_from_prover<FF>(labels[idx]);
194 opening_claims[idx] = { { evaluation_points[idx], small_ipa_evaluations[idx] },
195 small_ipa_commitments.
get_all()[idx] };
200 if constexpr (IsRecursive) {
201 for (
auto& eval : small_ipa_evaluations) {
202 eval.clear_round_provenance();
208 translation_masking_consistency_checked =
209 SmallIPA::check_eccvm_evaluations_consistency(small_ipa_evaluations,
210 small_ipa_evaluation_challenge,
211 evaluation_challenge_x,
212 batching_challenge_v,
213 translation_masking_term_eval);
216 FF batched_translation_evaluation = translation_evaluations.get_all()[0];
217 FF batching_scalar = batching_challenge_v;
219 std::vector<FF> batching_challenges = {
FF::one() };
220 for (
size_t idx = 1; idx < NUM_TRANSLATION_EVALUATIONS; ++idx) {
221 batched_translation_evaluation += batching_scalar * translation_evaluations.get_all()[idx];
222 batching_challenges.push_back(batching_scalar);
223 batching_scalar *= batching_challenge_v;
225 Commitment batched_commitment = Commitment::batch_mul(translation_commitments, batching_challenges);
228 opening_claims[NUM_SMALL_IPA_EVALUATIONS] = { { evaluation_challenge_x, batched_translation_evaluation },
229 batched_commitment };
240 FF v = batching_challenge_v;
241 FF v_squared = v * v;
242 FF v_cubed = v_squared * v;
243 FF v_fourth = v_cubed * v;
247 if constexpr (IsRecursive) {
248 translation_masking_term_eval.set_origin_tag(batching_challenge_v.get_origin_tag());
251 FF batched_eval_minus_masking = translation_evaluations.op + v * translation_evaluations.Px +
252 v_squared * translation_evaluations.Py + v_cubed * translation_evaluations.z1 +
253 v_fourth * translation_evaluations.z2 - translation_masking_term_eval;
256 FF x_power = evaluation_challenge_x;
258 x_power *= evaluation_challenge_x;
260 accumulated_result = batched_eval_minus_masking / x_power;