28template <
typename Curve_,
size_t log_poly_length>
class TripleIPA {
48 static_assert(log_poly_length >= 1,
"log_poly_length must be at least 1");
80 return eq_weight * ShiftedEq::evaluate_eq_folded(point, ipa_round_challenges_inv) +
88 return IPAProtocol::evaluate_challenge_poly(
89 std::vector<Fr>(ipa_round_challenges_inv.begin(), ipa_round_challenges_inv.end()), challenge);
116 zeta[2].sqr(), zeta[0] * zeta[1],
117 zeta[0] * zeta[2], zeta[1] * zeta[2] };
119 diagonal_evaluations[2], cross_sums[0],
120 cross_sums[1], cross_sums[2] };
122 return Fr::mult_madd(
123 std::vector<Fr>(weights.begin(), weights.end()), std::vector<Fr>(values.begin(), values.end()), {});
126 for (
size_t idx = 0; idx < weights.size(); ++idx) {
127 result += weights[idx] * values[idx];
144 const auto& multilinear_challenge = input.
claim_data.unshifted.multilinear_challenge;
145 const auto& univariate_challenge = input.
claim_data.univariate.opening_pair.challenge;
147 const Fr unshifted_against_shift =
149 const Fr unshifted_against_pow = unshifted_witness.
evaluate(univariate_challenge);
151 const auto& shifted = input.
claim_data.shifted;
152 Fr shifted_against_eq =
154 for (
size_t idx = 0; idx < shifted.source_unshifted_evaluations.size(); ++idx) {
155 shifted_against_eq += shifted.rho_powers[idx] * shifted.source_unshifted_evaluations[idx];
158 const Fr shifted_against_pow = shifted_witness.
evaluate(univariate_challenge);
159 const Fr univariate_against_eq =
161 const Fr univariate_against_shift =
164 return { unshifted_against_shift + shifted_against_eq,
165 unshifted_against_pow + univariate_against_eq,
166 shifted_against_pow + univariate_against_shift };
181 .univariate_challenge = claim.
univariate.opening_pair.challenge,
182 .eq_weight = zeta[0],
183 .shifted_eq_weight = zeta[1],
184 .powers_weight = zeta[2] },
188 template <
typename Transcript>
190 const std::shared_ptr<Transcript>& transcript)
195 transcript->template receive_from_prover<Fr>(
"TripleIPA:cross_F_shift"),
196 transcript->template receive_from_prover<Fr>(
"TripleIPA:cross_F_P"),
197 transcript->template receive_from_prover<Fr>(
"TripleIPA:cross_shift_P")
199 const auto zeta = transcript->template get_challenges<Fr>(
203 return combined_claim;
207 template <
typename Transcript>
210 const std::shared_ptr<Transcript>& transcript)
241 const auto cross_sums =
compute_cross_sums(input, unshifted_witness, shifted_witness, eq_tensor);
242 transcript->send_to_verifier(
"TripleIPA:cross_F_shift", cross_sums[0]);
243 transcript->send_to_verifier(
"TripleIPA:cross_F_P", cross_sums[1]);
244 transcript->send_to_verifier(
"TripleIPA:cross_shift_P", cross_sums[2]);
246 const auto zeta = transcript->template get_challenges<Fr>(
261 IPAProtocol::compute_inner_product_proof_internal(
ck, combined_witness,
std::move(b_poly), transcript);
269 template <
typename Transcript>
280 return IPAProtocol::reduce_verify_inner_product_recursive(
281 combined_claim.commitment,
282 combined_claim.evaluation,
284 return combined_claim.opening_vector.evaluate_folded(round_challenges_inv);
302 return IPAProtocol::verify_accumulator(
vk, accumulator);
308 return IPAProtocol::batch_verify_accumulators(
vk, accumulators);
312 template <
typename Transcript>
317 transcript->add_to_hash_buffer(
"TripleIPA:F_shift:commitment", claim.
shifted_commitment);
318 transcript->add_to_hash_buffer(
"TripleIPA:F_shift:evaluation", claim.
shifted_evaluation);
319 transcript->add_to_hash_buffer(
"TripleIPA:P:commitment", claim.
univariate.commitment);
320 transcript->add_to_hash_buffer(
"TripleIPA:P:evaluation", claim.
univariate.opening_pair.evaluation);
321 transcript->add_to_hash_buffer(
"TripleIPA:P:x", claim.
univariate.opening_pair.challenge);
324 for (
size_t coordinate_idx = 0; coordinate_idx < log_poly_length; ++coordinate_idx) {
325 transcript->add_to_hash_buffer(
"TripleIPA:u_" +
std::to_string(coordinate_idx),
330 template <
typename Transcript>
332 const std::shared_ptr<Transcript>& transcript)
334 transcript->add_to_hash_buffer(
"TripleIPA:combined:commitment", opening_claim.
commitment);
335 transcript->add_to_hash_buffer(
"TripleIPA:combined:evaluation", opening_claim.
evaluation);
344 const auto& transcript)
348 auto data = IPAProtocol::read_inner_product_transcript_data(
349 opening_claim.commitment,
350 opening_claim.evaluation,
352 return opening_claim.opening_vector.evaluate_folded(round_challenges_inv);
357 const Commitment aux_generator = Commitment::one() *
data.gen_challenge;
359 data.G_zero_from_prover *
data.a_zero + aux_generator *
data.a_zero *
data.b_zero;
360 const bool relation_succeeded =
data.C_zero.normalize() == right_hand_side.normalize();
362 return {
std::move(
data.round_challenges_inv),
data.G_zero_from_prover, relation_succeeded };
#define BB_BENCH_NAME(name)
CommitmentKey object over a pairing group 𝔾₁.
IPA (inner product argument) commitment scheme class.
static bb::Polynomial< Fr > powers_tensor(const Fr &r)
The power tensor (1, r, r^2, ..., r^{poly_length-1}), the IPA b-vector for a univariate opening.
Fr evaluate(const Fr &z) const
Fr evaluate_mle(std::span< const Fr > evaluation_points, bool shift=false) const
evaluate multi-linear extension p(X_0,…,X_{n-1}) = \sum_i a_i*L_i(X_0,…,X_{n-1}) at u = (u_0,...
static Polynomial< FF > construct(std::span< const FF > challenges, size_t log_num_monomials)
Construct eq(X, r) coefficient table over Boolean hypercube {0,1}^d.
static FF evaluate_from_eq(const Polynomial &eq, const Polynomial &witness)
static void add_scaled(Polynomial &result, const Polynomial &eq, const FF &scaling_factor)
typename IPAProtocol::NativeAccumulator NativeAccumulator
static NativeAccumulator reduce_to_accumulator(const TripleIpaClaim &claim, const auto &transcript)
typename Curve::Element GroupElement
typename Curve::ScalarField Fr
static bool batch_verify_accumulators(const VK &vk, std::span< const NativeAccumulator > accumulators)
static constexpr size_t NUM_TENSORS
static bool verify_accumulator(const VK &vk, const NativeAccumulator &accumulator)
static void add_claim_to_hash_buffer(const TripleIpaClaim &claim, const std::shared_ptr< Transcript > &transcript)
static bool reduce_verify(const VK &vk, const TripleIpaClaim &claim, const std::shared_ptr< Transcript > &transcript)
static std::array< Fr, NUM_CROSS_SUMS > compute_cross_sums(const TripleIpaInput &input, const Polynomial &unshifted_witness, const Polynomial &shifted_witness, const Polynomial &eq_tensor)
Compute the three cross-sums from already-built batched witnesses F and F'.
typename Curve::AffineElement Commitment
static constexpr size_t NUM_CROSS_SUMS
static NativeAccumulator reduce_to_accumulator_internal(const IpaVerifierClaim &opening_claim, const auto &transcript)
Native reduction to a deferrable accumulator: checks the cheap IPA group relation against the prover-...
static void compute_opening_proof(const CK &ck, const TripleIpaInput &input, const std::shared_ptr< Transcript > &transcript)
static void add_claim_to_hash_buffer(const IpaVerifierClaim &opening_claim, const std::shared_ptr< Transcript > &transcript)
std::conditional_t< Curve::is_stdlib_type, typename IPAProtocol::VerifierAccumulator, NativeAccumulator > VerifierAccumulator
static VerifierAccumulator reduce_verify(const TripleIpaClaim &claim, const auto &transcript)
static Fr combined_inner_product(const std::array< Fr, NUM_TENSORS > &diagonal_evaluations, const std::array< Fr, NUM_TENSORS > &zeta, const std::array< Fr, NUM_CROSS_SUMS > &cross_sums)
static IpaVerifierClaim combine_into_ipa_claim(const TripleIpaClaim &claim, const std::array< Fr, NUM_TENSORS > &zeta, const std::array< Fr, NUM_CROSS_SUMS > &cross_sums)
static constexpr size_t poly_length
static IpaVerifierClaim compute_ipa_verifier_claim(const TripleIpaClaim &claim, const std::shared_ptr< Transcript > &transcript)
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
typename Group::element Element
static constexpr bool is_stdlib_type
typename Group::affine_element AffineElement
Entry point for Barretenberg command-line interface.
void add_scaled_batch(Polynomial< Fr > &dst, std::span< const PolynomialSpan< const Fr > > sources, std::span< const Fr > scalars)
Fused parallel batched add: dst += sum_i scalars[i] * sources[i].
CommitmentKey< Curve > ck
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::string to_string(bb::avm2::ValueTag tag)
Deferred native IPA verification state — the native counterpart of VerifierAccumulator.
Fr evaluate_folded(std::span< const Fr > ipa_round_challenges_inv) const
static Fr evaluate_pow_folded(const Fr &challenge, std::span< const Fr > ipa_round_challenges_inv)
std::vector< Fr > multilinear_challenge
Polynomial construct_combined_tensor(const Polynomial &eq) const
IpaOpeningVector opening_vector
Pre-batch verifier-side claim data: per-polynomial commitments/evaluations before Stage-1 rho-batchin...
The compact TripleIPA opening claim: the statement that crosses verifier boundaries.
std::vector< Fr > multilinear_challenge
Commitment unshifted_commitment
Commitment shifted_commitment
OpeningClaim< Curve > univariate
static constexpr field zero()