Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
kzg.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Complete, auditors: [Khashayar], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
8
17
18#include <memory>
19#include <utility>
20
21namespace bb {
22
23template <typename Curve_> class KZG {
24 public:
25 using Curve = Curve_;
28 using Fr = typename Curve::ScalarField;
30 using GroupElement = typename Curve::Element;
34
43 template <typename Transcript>
44 static void compute_opening_proof(const CK& ck,
45 const ProverOpeningClaim<Curve>& opening_claim,
46 const std::shared_ptr<Transcript>& prover_trancript)
47 {
48 BB_BENCH_NAME("KZG::compute_opening_proof");
49 Polynomial quotient = opening_claim.polynomial;
50 OpeningPair<Curve> pair = opening_claim.opening_pair;
51 Commitment quotient_commitment;
52
53 if (opening_claim.polynomial.is_empty()) {
54 // We treat the empty polynomial as the zero polynomial
55 quotient_commitment = Commitment::infinity();
56 } else {
57 quotient.at(0) = quotient[0] - pair.evaluation;
58 // Computes the coefficients for the quotient polynomial q(X) = (p(X) - v) / (X - r) through an FFT
59 quotient.factor_roots(pair.challenge);
60 quotient_commitment = ck.commit(quotient);
61 }
62
63 // TODO(#479): for now we compute the KZG commitment directly to unify the KZG and IPA interfaces but in the
64 // future we might need to adjust this to use the incoming alternative to work queue (i.e. variation of
65 // pthreads) or even the work queue itself
66 prover_trancript->send_to_verifier("KZG:W", quotient_commitment);
67 };
68
79 template <typename Transcript>
81 const std::shared_ptr<Transcript>& verifier_transcript)
82 {
83 auto quotient_commitment = verifier_transcript->template receive_from_prover<Commitment>("KZG:W");
84
85 // Note: The pairing check can be expressed naturally as
86 // e(C - v * [1]_1, [1]_2) = e([W]_1, [X - r]_2) where C =[p(X)]_1. This can be rearranged (e.g. see the plonk
87 // paper) as e(C + r*[W]_1 - v*[1]_1, [1]_2) * e(-[W]_1, [X]_2) = 1, or e(P_0, [1]_2) * e(P_1, [X]_2) = 1
88 GroupElement P_0;
89 if constexpr (Curve::is_stdlib_type) {
90 // Express operation as a batch_mul in order to use Goblinization if available
91 auto builder = quotient_commitment.get_context();
92 auto one = Fr(builder, 1);
93 std::vector<GroupElement> commitments = { claim.commitment,
94 quotient_commitment,
95 GroupElement::one(builder) };
96 std::vector<Fr> scalars = { one, claim.opening_pair.challenge, -claim.opening_pair.evaluation };
97
98 // Compute C + r*[W]_1 + (-v)*[1]_1 as a batch_mul, no need of edge case handling since we don't expect the
99 // points to be linearly dependent.
100 P_0 = GroupElement::batch_mul(commitments, scalars, /*max_num_bits=*/0, /*with_edgecases=*/false);
101
102 } else {
103 P_0 = claim.commitment;
104 P_0 += quotient_commitment * claim.opening_pair.challenge;
105 P_0 -= GroupElement::one() * claim.opening_pair.evaluation;
106 }
107
108 auto P_1 = -quotient_commitment;
109 return PairingPointsType(P_0, P_1);
110 };
111
131 template <typename Transcript>
133 const std::shared_ptr<Transcript>& transcript,
134 const size_t expected_final_msm_size = 0)
135 {
136 auto quotient_commitment = transcript->template receive_from_prover<Commitment>("KZG:W");
137
138 // OriginTag suppression: The tag system flags patterns like A*α + B where A, B are
139 // prover-supplied and α is a challenge derived without hashing them. The quotient commitment
140 // W is prover-supplied and scaled by z in C + W·z, so it triggers this pattern.
141 // This is a false positive: the pairing check e(C + W·z, [1]₂) · e(−W, [x]₂) = 1 forces W
142 // to be the honest quotient commitment, so the prover cannot tamper with it.
143 // We assign W the tag of z (evaluation_point): the challenge it is scaled by,
144 // so the tag system does not flag the multiplication.
145 if constexpr (Curve::is_stdlib_type) {
146 const auto challenge_tag = batch_opening_claim.evaluation_point.get_origin_tag();
147 quotient_commitment.set_origin_tag(challenge_tag);
148 }
149
150 // The pairing check can be expressed as
151 // e(C + [W]₁ ⋅ z, [1]₂) * e(−[W]₁, [X]₂) = 1, where C = ∑ commitmentsᵢ ⋅ scalarsᵢ.
152 GroupElement P_0;
153 // Place the commitment to W to 'commitments'
154 batch_opening_claim.commitments.emplace_back(quotient_commitment);
155 // Update the scalars by adding the Shplonk evaluation challenge z
156 batch_opening_claim.scalars.emplace_back(batch_opening_claim.evaluation_point);
157
158 // Validate the final MSM size if expected size is provided
159 if (expected_final_msm_size != 0) {
160 if (batch_opening_claim.commitments.size() != expected_final_msm_size) {
161 throw_or_abort("KZG verification: unexpected final MSM size " +
162 std::to_string(batch_opening_claim.commitments.size()) + " (expected " +
163 std::to_string(expected_final_msm_size) + ")");
164 }
165 }
166
167 // Compute C + [W]₁ ⋅ z
168 BB_ASSERT_EQ(batch_opening_claim.commitments.size(),
169 batch_opening_claim.scalars.size(),
170 "BatchOpeningClaim: commitments and scalars must have equal length");
171 P_0 = GroupElement::batch_mul(batch_opening_claim.commitments,
172 batch_opening_claim.scalars,
173 /*max_num_bits=*/0,
174 /*with_edgecases=*/true);
175 auto P_1 = -quotient_commitment;
176
177 return PairingPointsType(P_0, P_1);
178 }
179};
180
181} // namespace bb
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:83
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:264
CommitmentKey object over a pairing group 𝔾₁.
typename Curve::AffineElement Commitment
Definition kzg.hpp:29
typename Curve::Element GroupElement
Definition kzg.hpp:30
Curve_ Curve
Definition kzg.hpp:25
static PairingPointsType reduce_verify(const OpeningClaim< Curve > &claim, const std::shared_ptr< Transcript > &verifier_transcript)
Computes the input points for the pairing check needed to verify a KZG opening claim of a single poly...
Definition kzg.hpp:80
typename Curve::ScalarField Fr
Definition kzg.hpp:28
std::conditional_t< Curve::is_stdlib_type, stdlib::recursion::PairingPoints< Curve >, bb::PairingPoints< Curve > > PairingPointsType
Definition kzg.hpp:33
static PairingPointsType reduce_verify_batch_opening_claim(BatchOpeningClaim< Curve > batch_opening_claim, const std::shared_ptr< Transcript > &transcript, const size_t expected_final_msm_size=0)
Computes the input points for the pairing check needed to verify a KZG opening claim obtained from a ...
Definition kzg.hpp:132
static void compute_opening_proof(const CK &ck, const ProverOpeningClaim< Curve > &opening_claim, const std::shared_ptr< Transcript > &prover_trancript)
Computes the KZG commitment to an opening proof polynomial at a single evaluation point.
Definition kzg.hpp:44
Unverified claim (C,r,v) for some witness polynomial p(X) such that.
Definition claim.hpp:55
OpeningPair< Curve > opening_pair
Definition claim.hpp:64
Commitment commitment
Definition claim.hpp:66
Opening pair (r,v) for some witness polynomial p(X) such that p(r) = v.
Definition claim.hpp:21
An object storing two EC points that represent the inputs to a pairing check.
bool is_empty() const
Fr & at(size_t index)
Our mutable accessor, unlike operator[]. We abuse precedent a bit to differentiate at() and operator[...
void factor_roots(const Fr &root)
Divides p(X) by (X-r) in-place. Assumes that p(rⱼ)=0 for all j.
Polynomial p and an opening pair (r,v) such that p(r) = v.
Definition claim.hpp:36
Polynomial polynomial
Definition claim.hpp:41
OpeningPair< Curve > opening_pair
Definition claim.hpp:42
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
typename Group::element Element
Definition grumpkin.hpp:63
static constexpr bool is_stdlib_type
Definition grumpkin.hpp:67
typename Group::affine_element AffineElement
Definition grumpkin.hpp:64
AluTraceBuilder builder
Definition alu.test.cpp:124
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
CommitmentKey< Curve > ck
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
An accumulator consisting of the Shplonk evaluation challenge and vectors of commitments and scalars.
Definition claim.hpp:156
std::vector< Commitment > commitments
Definition claim.hpp:161
std::vector< Scalar > scalars
Definition claim.hpp:162
void throw_or_abort(std::string const &err)