Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ZeroMorph working with IPA and integration with ECCVM #5246

Merged
merged 21 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void ipa_verify(State& state) noexcept
auto verifier_transcript = std::make_shared<NativeTranscript>(prover_transcript->proof_data);

state.ResumeTiming();
auto result = IPA<Curve>::verify(vk, opening_claim, verifier_transcript);
auto result = IPA<Curve>::reduce_verify(vk, opening_claim, verifier_transcript);
ASSERT(result);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class ProxyCaller {
const OpeningClaim<Curve>& opening_claim,
const std::shared_ptr<Transcript>& transcript)
{
return IPA<Curve>::verify_internal(vk, opening_claim, transcript);
return IPA<Curve>::reduce_verify_internal(vk, opening_claim, transcript);
}
};
} // namespace bb
Expand Down
37 changes: 20 additions & 17 deletions barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace bb {
*
* @remark IPA is not a very intuitive algorithm, so here are a few things that might help internalize it:
*
*1. Originally we have two vectors \f$\vec{a}\f$ and \f$\vec{b}\f$, which the product of which we want to prove, but
*1. Originally we have two vectors \f$\vec{a}\f$ and \f$\vec{b}\f$, whose product we want to prove, but
*the prover can't just send vector \f$\vec{a}\f$ to the verifier, it can only provide a commitment
\f$\langle\vec{a},\vec{G}\rangle\f$
*2. The verifier computes the \f$C'=C+\langle\vec{a},\vec{b}\rangle\cdot U\f$ to "bind" together the
Expand All @@ -50,8 +50,8 @@ namespace bb {
\alpha^{-1}\langle\vec{a}_{low},\vec{b}_{high}\rangle+\alpha \langle \vec{a}_{high},\vec{b}_{low}\rangle +
\langle\vec{a}_{high},\vec{b}_{high}\rangle=
\langle\vec{a},\vec{b}\rangle+\alpha^{-1}\langle\vec{a}_{low},\vec{b}_{high}\rangle+\alpha \langle
\vec{a}_{high},\vec{b}_{low}\rangle\f$, so if we provide commitments to
\f$\langle\vec{a}_{low},\vec{b}_{high}\rangle\f$ and \f$\langle \vec{a}_{high},\vec{b}_{low}\rangle\f$ the verifier
\vec{a}_{high},\vec{b}_{low}\rangle\f$, so if we provide commitments to the cross-terms
\f$\langle\vec{a}_{low},\vec{b}_{high}\rangle\f$ and \f$\langle \vec{a}_{high},\vec{b}_{low}\rangle\f$, the verifier
can reduce initial commitment to the result \f$\langle \vec{a},\vec{b}\rangle U\f$ to the new commitment \f$\langle
\vec{a}_{new},\vec{b}_{new}\rangle U\f$
*5. Analogously, if \f$\vec{G}_{new}=\vec{G}_{low}+\alpha^{-1}\vec{G}_{high}\f$, then we can reduce the initial
Expand All @@ -71,14 +71,16 @@ namespace bb {
* The old version of documentation is available at <a href="https://hackmd.io/q-A8y6aITWyWJrvsGGMWNA?view">Old IPA
documentation </a>
*/
template <typename Curve> class IPA {
// clang-fromat on
template <typename Curve_> class IPA {
public:
using Curve = Curve_;
using Fr = typename Curve::ScalarField;
using GroupElement = typename Curve::Element;
using Commitment = typename Curve::AffineElement;
using CK = CommitmentKey<Curve>;
using VK = VerifierCommitmentKey<Curve>;
using Polynomial = bb::Polynomial<Fr>;
using VerifierAccumulator = bool;

// These allow access to internal functions so that we can never use a mock transcript unless it's fuzzing or testing of IPA specifically
#ifdef IPA_TEST
Expand Down Expand Up @@ -107,8 +109,10 @@ template <typename Curve> class IPA {
*1. Send the degree of \f$f(x)\f$ plus one, equal to \f$d\f$ to the verifier
*2. Receive the generator challenge \f$u\f$ from the verifier. If it is zero, abort
*3. Compute the auxiliary generator \f$U=u\cdot G\f$, where \f$G\f$ is a generator of \f$E(\mathbb{F}_p)\f$​
*4. Set \f$\vec{G}_{k}=\vec{G}\f$, \f$\vec{a}_{k}=\vec{p}\f$
*5. Compute the vector \f$\vec{b}_{k}=(1,\beta,\beta^2,...,\beta^{d-1})\f$
*4. Set \f$\vec{G}_{k}=\vec{G}\f$, \f$\vec{a}_{k}=\vec{p}\f$ where \f$vec{p}\f$ represent the polynomial's
*coefficients
. *5. Compute the vector \f$\vec{b}_{k}=(1,\beta,\beta^2,...,\beta^{d-1})\f$ where \f$p(\beta)$\f is the
evaluation we wish to prove.
*6. Perform \f$k\f$ rounds (for \f$i \in \{k,...,1\}\f$) of:
* 1. Compute
\f$L_{i-1}=\langle\vec{a}_{i\_low},\vec{G}_{i\_high}\rangle+\langle\vec{a}_{i\_low},\vec{b}_{i\_high}\rangle\cdot
Expand Down Expand Up @@ -328,13 +332,11 @@ template <typename Curve> class IPA {
*9. Receive \f$\vec{a}_{0}\f$ of length 1
*10. Compute \f$C_{right}=a_{0}G_{s}+a_{0}b_{0}U\f$
*11. Check that \f$C_{right} = C_0\f$. If they match, return true. Otherwise return false.
*
*
*/
template <typename Transcript>
static bool verify_internal(const std::shared_ptr<VK>& vk,
const OpeningClaim<Curve>& opening_claim,
const std::shared_ptr<Transcript>& transcript)
static VerifierAccumulator reduce_verify_internal(const std::shared_ptr<VK>& vk,
const OpeningClaim<Curve>& opening_claim,
const std::shared_ptr<Transcript>& transcript)
{
// Step 1.
// Receive polynomial_degree + 1 = d from the prover
Expand All @@ -352,7 +354,6 @@ template <typename Curve> class IPA {
auto aux_generator = Commitment::one() * generator_challenge;

auto log_poly_degree = static_cast<size_t>(numeric::get_msb(poly_length));

// Step 3.
// Compute C' = C + f(\beta) ⋅ U
GroupElement C_prime = opening_claim.commitment + (aux_generator * opening_claim.opening_pair.evaluation);
Expand Down Expand Up @@ -495,11 +496,13 @@ template <typename Curve> class IPA {
*
*@remark The verification procedure documentation is in \link IPA::verify_internal verify_internal \endlink
*/
static bool verify(const std::shared_ptr<VK>& vk,
const OpeningClaim<Curve>& opening_claim,
const std::shared_ptr<NativeTranscript>& transcript)
// TODO(https://github.com/AztecProtocol/barretenberg/issues/912): Return the proper VerifierAccumulator once
// implemented
static VerifierAccumulator reduce_verify(const std::shared_ptr<VK>& vk,
const OpeningClaim<Curve>& opening_claim,
const std::shared_ptr<NativeTranscript>& transcript)
{
return verify_internal(vk, opening_claim, transcript);
return reduce_verify_internal(vk, opening_claim, transcript);
}
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

#include "../gemini/gemini.hpp"
#include "../shplonk/shplonk.hpp"
#include "./mock_transcript.hpp"
Expand Down Expand Up @@ -71,7 +72,7 @@ TEST_F(IPATest, OpenZeroPolynomial)
// initialize verifier transcript from proof data
auto verifier_transcript = std::make_shared<NativeTranscript>(prover_transcript->proof_data);

auto result = IPA::verify(this->vk(), opening_claim, verifier_transcript);
auto result = IPA::reduce_verify(this->vk(), opening_claim, verifier_transcript);
EXPECT_TRUE(result);
}

Expand All @@ -96,7 +97,7 @@ TEST_F(IPATest, OpenAtZero)
// initialize verifier transcript from proof data
auto verifier_transcript = std::make_shared<NativeTranscript>(prover_transcript->proof_data);

auto result = IPA::verify(this->vk(), opening_claim, verifier_transcript);
auto result = IPA::reduce_verify(this->vk(), opening_claim, verifier_transcript);
EXPECT_TRUE(result);
}

Expand Down Expand Up @@ -144,7 +145,7 @@ TEST_F(IPATest, ChallengesAreZero)
auto new_random_vector = random_vector;
new_random_vector[i] = Fr::zero();
transcript->initialize(new_random_vector, lrs, { uint256_t(n) });
EXPECT_ANY_THROW(IPA::verify_internal(this->vk(), opening_claim, transcript));
EXPECT_ANY_THROW(IPA::reduce_verify_internal(this->vk(), opening_claim, transcript));
}
}

Expand Down Expand Up @@ -186,7 +187,7 @@ TEST_F(IPATest, AIsZeroAfterOneRound)
transcript->reset_indices();

// Verify
EXPECT_TRUE(IPA::verify_internal(this->vk(), opening_claim, transcript));
EXPECT_TRUE(IPA::reduce_verify_internal(this->vk(), opening_claim, transcript));
}
#endif
} // namespace bb
Expand Down Expand Up @@ -225,7 +226,7 @@ TEST_F(IPATest, Open)
// initialize verifier transcript from proof data
auto verifier_transcript = std::make_shared<NativeTranscript>(prover_transcript->proof_data);

auto result = IPA::verify(this->vk(), opening_claim, verifier_transcript);
auto result = IPA::reduce_verify(this->vk(), opening_claim, verifier_transcript);
EXPECT_TRUE(result);

EXPECT_EQ(prover_transcript->get_manifest(), verifier_transcript->get_manifest());
Expand Down Expand Up @@ -321,7 +322,7 @@ TEST_F(IPATest, GeminiShplonkIPAWithShift)

const auto shplonk_verifier_claim =
ShplonkVerifier::reduce_verification(this->vk(), gemini_verifier_claim, verifier_transcript);
bool verified = IPA::verify(this->vk(), shplonk_verifier_claim, verifier_transcript);
auto result = IPA::reduce_verify(this->vk(), shplonk_verifier_claim, verifier_transcript);

EXPECT_EQ(verified, true);
EXPECT_EQ(result, true);
}
22 changes: 0 additions & 22 deletions barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,6 @@ template <typename Curve_> class KZG {
prover_trancript->send_to_verifier("KZG:W", quotient_commitment);
};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There isn't an actual need for the "full verificaton" function besides in kzg.test so removed to avoid duplication


/**
* @brief Computes the KZG verification for an opening claim of a single polynomial commitment
*
* @param vk is the verification key which has a pairing check function
* @param claim OpeningClaim ({r, v}, C)
* @return e(P₀,[1]₁)e(P₁,[x]₂)≡ [1]ₜ where
* - P₀ = C − v⋅[1]₁ + r⋅[x]₁
* - P₁ = [Q(x)]₁
*/
static bool verify(const std::shared_ptr<VK>& vk,
const OpeningClaim<Curve>& claim,
const std::shared_ptr<NativeTranscript>& verifier_transcript)
{
auto quotient_commitment = verifier_transcript->template receive_from_prover<Commitment>("KZG:W");
auto lhs = claim.commitment - (GroupElement::one() * claim.opening_pair.evaluation) +
(quotient_commitment * claim.opening_pair.challenge);
auto rhs = -quotient_commitment;

return vk->pairing_check(lhs, rhs);
};

/**
* @brief Computes the input points for the pairing check needed to verify a KZG opening claim of a single
* polynomial commitment. This reduction is non-interactive and always succeeds.
Expand Down Expand Up @@ -102,7 +81,6 @@ template <typename Curve_> class KZG {
}

auto P_1 = -quotient_commitment;

return { P_0, P_1 };
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ TYPED_TEST(KZGTest, single)
KZG::compute_opening_proof(this->ck(), opening_pair, witness, prover_transcript);

auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_transcript);
bool verified = KZG::verify(this->vk(), opening_claim, verifier_transcript);
auto pairing_points = KZG::reduce_verify(opening_claim, verifier_transcript);

EXPECT_EQ(verified, true);
EXPECT_EQ(this->vk()->pairing_check(pairing_points[0], pairing_points[1]), true);
}

/**
Expand Down Expand Up @@ -170,11 +170,11 @@ TYPED_TEST(KZGTest, GeminiShplonkKzgWithShift)

// KZG verifier:
// aggregates inputs [Q] - [Q_z] and [W] into an 'accumulator' (can perform pairing check on result)
bool verified = KZG::verify(this->vk(), shplonk_verifier_claim, verifier_transcript);
auto pairing_points = KZG::reduce_verify(shplonk_verifier_claim, verifier_transcript);

// Final pairing check: e([Q] - [Q_z] + z[W], [1]_2) = e([W], [x]_2)

EXPECT_EQ(verified, true);
EXPECT_EQ(this->vk()->pairing_check(pairing_points[0], pairing_points[1]), true);
}

} // namespace bb
Loading
Loading