34 const FF& pow_kappa_minus_one,
35 const std::vector<FF>& degree_check_challenges)
const
37 bool degree_check_verified =
true;
38 FF degree_check_diff(0);
39 for (
size_t idx = 0; idx < NUM_WIRES; ++idx) {
40 degree_check_diff += evals[idx] * degree_check_challenges[idx];
42 degree_check_diff -= evals.back() * pow_kappa_minus_one;
43 if constexpr (IsRecursive) {
44 degree_check_diff.assert_equal(
FF(0),
"assert_equal: merge degree identity failed in Merge Verifier");
45 degree_check_verified &= degree_check_diff.get_value() == 0;
47 degree_check_verified &= degree_check_diff == 0;
50 return degree_check_verified;
55 const std::vector<Commitment>& table_commitments,
57 const FF& shplonk_opening_challenge,
58 const std::vector<FF>& shplonk_batching_challenges,
61 const std::vector<FF>& evals)
const
69 for (
auto& commitment : table_commitments) {
72 if constexpr (IsRecursive) {
73 batch_opening_claim.
commitments.emplace_back(Commitment::one(kappa.get_context()));
75 batch_opening_claim.
commitments.emplace_back(Commitment::one());
79 batch_opening_claim.
scalars = { -(shplonk_opening_challenge - kappa) };
80 for (
auto& scalar : shplonk_batching_challenges) {
83 batch_opening_claim.
scalars.back() *=
84 (shplonk_opening_challenge - kappa) * (shplonk_opening_challenge - kappa_inv).invert();
86 batch_opening_claim.
scalars.emplace_back(
FF(0));
87 for (
size_t idx = 0; idx < evals.size(); idx++) {
88 if (idx < evals.size() - 1) {
89 batch_opening_claim.
scalars.back() -= evals[idx] * shplonk_batching_challenges[idx];
91 batch_opening_claim.
scalars.back() -= shplonk_batching_challenges.back() * evals.back() *
92 (shplonk_opening_challenge - kappa) *
93 (shplonk_opening_challenge - kappa_inv).invert();
99 return batch_opening_claim;
116 transcript->load_proof(proof);
121 const FF shift_size = transcript->template receive_from_prover<FF>(
"shift_size");
123 if constexpr (IsRecursive) {
124 BB_ASSERT_GT(uint32_t(shift_size.get_value()), 0U,
"Shift size should always be bigger than 0");
127 BB_ASSERT_GT(shift_size, 0U,
"Shift size should always be bigger than 0");
135 std::vector<Commitment> table_commitments;
136 table_commitments.reserve((3 * NUM_WIRES) + 1);
137 for (
size_t idx = 0; idx < NUM_WIRES; ++idx) {
141 for (
size_t idx = 0; idx < NUM_WIRES; ++idx) {
145 for (
size_t idx = 0; idx < NUM_WIRES; ++idx) {
146 table_commitments.emplace_back(
147 transcript->template receive_from_prover<Commitment>(
"MERGED_TABLE_" +
std::to_string(idx)));
148 merged_table_commitments[idx] = table_commitments.back();
152 std::vector<FF> degree_check_challenges = transcript->template get_challenges<FF>(labels_degree_check);
155 table_commitments.emplace_back(
156 transcript->template receive_from_prover<Commitment>(
"REVERSED_BATCHED_LEFT_TABLES"));
159 std::vector<FF> shplonk_batching_challenges =
160 transcript->template get_challenges<FF>(labels_shplonk_batching_challenges);
163 const FF kappa = transcript->template get_challenge<FF>(
"kappa");
164 const FF kappa_inv = kappa.invert();
165 const FF pow_kappa = kappa.pow(shift_size);
166 const FF pow_kappa_minus_one = pow_kappa * kappa_inv;
169 std::vector<FF> evals;
170 evals.reserve((3 * NUM_WIRES) + 1);
171 for (
size_t idx = 0; idx < NUM_WIRES; ++idx) {
172 evals.emplace_back(transcript->template receive_from_prover<FF>(
"LEFT_TABLE_EVAL_" +
std::to_string(idx)));
174 for (
size_t idx = 0; idx < NUM_WIRES; ++idx) {
175 evals.emplace_back(transcript->template receive_from_prover<FF>(
"RIGHT_TABLE_EVAL_" +
std::to_string(idx)));
177 for (
size_t idx = 0; idx < NUM_WIRES; ++idx) {
178 evals.emplace_back(transcript->template receive_from_prover<FF>(
"MERGED_TABLE_EVAL_" +
std::to_string(idx)));
182 evals.emplace_back(transcript->template receive_from_prover<FF>(
"REVERSED_BATCHED_LEFT_TABLES_EVAL"));
185 bool concatenation_verified = check_concatenation_identities(evals, pow_kappa);
188 bool degree_check_verified = check_degree_identity(evals, pow_kappa_minus_one, degree_check_challenges);
192 transcript->template receive_from_prover<Commitment>(
"SHPLONK_BATCHED_QUOTIENT");
195 FF shplonk_opening_challenge = transcript->template get_challenge<FF>(
"shplonk_opening_challenge");
199 shplonk_batched_quotient,
200 shplonk_opening_challenge,
201 shplonk_batching_challenges,
210 PairingPoints pairing_points = PCS::reduce_verify_batch_opening_claim(
std::move(batch_opening_claim), transcript);
212 return { pairing_points, merged_table_commitments, degree_check_verified, concatenation_verified };
BatchOpeningClaim< Curve > compute_shplonk_opening_claim(const std::vector< Commitment > &table_commitments, const Commitment &shplonk_batched_quotient, const FF &shplonk_opening_challenge, const std::vector< FF > &shplonk_batching_challenges, const FF &kappa, const FF &kappa_inv, const std::vector< FF > &evals) const