-
Notifications
You must be signed in to change notification settings - Fork 266
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: Elliptic Curve Virtual Machine Circuit #1268
Merged
Merged
Changes from 36 commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
a3cc4fb
merge zw/eccvm-v5
zac-williamson 0fdf507
compiler fix
zac-williamson d946923
compiler f ix
zac-williamson e49e082
compiler fix
zac-williamson 60fbe4b
added missing relations into eccvm
zac-williamson dafabbb
add transcript_collision_check
zac-williamson d23eb2e
updated eccvm transcript relation
zac-williamson 0c12334
renamed permutation_offset to eccvm_set_permutation_delta
zac-williamson a6ca881
fixed some TODOs
zac-williamson 2faac93
formatting pass
zac-williamson fdc1e5d
merge zw/eccvm-v5
zac-williamson 14e4a74
compiler fix
zac-williamson 5a91b27
compiler f ix
zac-williamson 7875c7c
compiler fix
zac-williamson 15d00d7
added missing relations into eccvm
zac-williamson 99f0cef
add transcript_collision_check
zac-williamson a492ba1
updated eccvm transcript relation
zac-williamson 4b313be
renamed permutation_offset to eccvm_set_permutation_delta
zac-williamson ce89fbf
fixed some TODOs
zac-williamson f98d105
formatting pass
zac-williamson b8aed61
eccvm now supports both bn254 and grumpkin curves (tests updated to r…
zac-williamson 8cfc14a
Merge branch 'zw/eccvm-v5' of github.com:AztecProtocol/aztec-packages…
zac-williamson 5a0026d
renamed eccvm columns to be more descriptive
zac-williamson 2487948
Merge branch 'master' into zw/eccvm-v5
zac-williamson b921726
fixed compiler errors
zac-williamson ef7064b
wip
zac-williamson 208270c
wip
zac-williamson 6b5b54e
wip
zac-williamson 7bf27d7
wip
zac-williamson aa9cc99
wip
zac-williamson 038fd88
Merge branch 'master' into zw/eccvm-v5
zac-williamson 0f34d1f
Merge branch 'master' into zw/eccvm-v5
Rumata888 ac3b92e
Merge branch 'master' into zw/eccvm-v5
zac-williamson 71d8178
compiler fixes
zac-williamson 7bf7120
compiler fixes
zac-williamson 991c495
merge/compiler fixes
zac-williamson e6ae6c9
updated to reflect PR comments
zac-williamson e405884
TODOs and comments
zac-williamson 8b6adb4
comments
zac-williamson e43680e
comments, todos, issues
zac-williamson 3266e8b
removed comment
zac-williamson c188bf4
PR fixes
zac-williamson 38a419f
Merge remote-tracking branch 'origin/master' into zw/eccvm-v5
charlielye File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
circuits/cpp/barretenberg/cpp/src/barretenberg/honk/composer/eccvm_composer.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
#include "./eccvm_composer.hpp" | ||
#include "barretenberg/honk/proof_system/ultra_prover.hpp" | ||
#include "barretenberg/proof_system/composer/composer_lib.hpp" | ||
#include "barretenberg/proof_system/composer/permutation_lib.hpp" | ||
|
||
namespace proof_system::honk { | ||
|
||
/** | ||
* @brief Compute witness polynomials | ||
* | ||
*/ | ||
template <ECCVMFlavor Flavor> void ECCVMComposer_<Flavor>::compute_witness(CircuitConstructor& circuit_constructor) | ||
{ | ||
if (computed_witness) { | ||
return; | ||
} | ||
|
||
auto polynomials = circuit_constructor.compute_full_polynomials(); | ||
|
||
auto key_wires = proving_key->get_wires(); | ||
auto poly_wires = polynomials.get_wires(); | ||
|
||
for (size_t i = 0; i < key_wires.size(); ++i) { | ||
std::copy(poly_wires[i].begin(), poly_wires[i].end(), key_wires[i].begin()); | ||
} | ||
|
||
computed_witness = true; | ||
} | ||
|
||
template <ECCVMFlavor Flavor> | ||
ECCVMProver_<Flavor> ECCVMComposer_<Flavor>::create_prover(CircuitConstructor& circuit_constructor) | ||
{ | ||
compute_proving_key(circuit_constructor); | ||
compute_witness(circuit_constructor); | ||
compute_commitment_key(proving_key->circuit_size); | ||
|
||
ECCVMProver_<Flavor> output_state(proving_key, commitment_key); | ||
|
||
return output_state; | ||
} | ||
|
||
/** | ||
* Create verifier: compute verification key, | ||
* initialize verifier with it and an initial manifest and initialize commitment_scheme. | ||
* | ||
* @return The verifier. | ||
* */ | ||
template <ECCVMFlavor Flavor> | ||
ECCVMVerifier_<Flavor> ECCVMComposer_<Flavor>::create_verifier(CircuitConstructor& circuit_constructor) | ||
{ | ||
auto verification_key = compute_verification_key(circuit_constructor); | ||
|
||
ECCVMVerifier_<Flavor> output_state(verification_key); | ||
|
||
auto pcs_verification_key = std::make_unique<VerifierCommitmentKey>(verification_key->circuit_size, crs_factory_); | ||
|
||
output_state.pcs_verification_key = std::move(pcs_verification_key); | ||
|
||
return output_state; | ||
} | ||
|
||
template <ECCVMFlavor Flavor> | ||
std::shared_ptr<typename Flavor::ProvingKey> ECCVMComposer_<Flavor>::compute_proving_key( | ||
CircuitConstructor& circuit_constructor) | ||
{ | ||
if (proving_key) { | ||
return proving_key; | ||
} | ||
|
||
// Initialize proving_key | ||
{ | ||
const size_t subgroup_size = circuit_constructor.get_circuit_subgroup_size(circuit_constructor.get_num_gates()); | ||
proving_key = std::make_shared<typename Flavor::ProvingKey>(subgroup_size, 0); | ||
} | ||
|
||
// TODO(@zac-williamson): We don't enforce nonzero selectors atm. Will create problems in recursive setting. | ||
// Fix once we have a stable base to work off of | ||
// enforce_nonzero_polynomial_selectors(circuit_constructor, proving_key.get()); | ||
|
||
compute_first_and_last_lagrange_polynomials<Flavor>(proving_key.get()); | ||
{ | ||
const size_t n = proving_key->circuit_size; | ||
typename Flavor::Polynomial lagrange_polynomial_second(n); | ||
lagrange_polynomial_second[1] = 1; | ||
proving_key->lagrange_second = lagrange_polynomial_second; | ||
} | ||
|
||
proving_key->contains_recursive_proof = false; | ||
|
||
return proving_key; | ||
} | ||
|
||
/** | ||
* Compute verification key consisting of selector precommitments. | ||
* | ||
* @return Pointer to created circuit verification key. | ||
* */ | ||
template <ECCVMFlavor Flavor> | ||
std::shared_ptr<typename Flavor::VerificationKey> ECCVMComposer_<Flavor>::compute_verification_key( | ||
CircuitConstructor& circuit_constructor) | ||
{ | ||
if (verification_key) { | ||
return verification_key; | ||
} | ||
|
||
if (!proving_key) { | ||
compute_proving_key(circuit_constructor); | ||
} | ||
|
||
verification_key = | ||
std::make_shared<typename Flavor::VerificationKey>(proving_key->circuit_size, proving_key->num_public_inputs); | ||
|
||
verification_key->lagrange_first = commitment_key->commit(proving_key->lagrange_first); | ||
verification_key->lagrange_second = commitment_key->commit(proving_key->lagrange_second); | ||
verification_key->lagrange_last = commitment_key->commit(proving_key->lagrange_last); | ||
return verification_key; | ||
} | ||
template class ECCVMComposer_<honk::flavor::ECCVM>; | ||
template class ECCVMComposer_<honk::flavor::ECCVMGrumpkin>; | ||
|
||
} // namespace proof_system::honk |
80 changes: 80 additions & 0 deletions
80
circuits/cpp/barretenberg/cpp/src/barretenberg/honk/composer/eccvm_composer.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#pragma once | ||
|
||
#include "barretenberg/honk/proof_system/eccvm_prover.hpp" | ||
#include "barretenberg/honk/proof_system/eccvm_verifier.hpp" | ||
#include "barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp" | ||
#include "barretenberg/proof_system/composer/composer_lib.hpp" | ||
#include "barretenberg/srs/factories/file_crs_factory.hpp" | ||
|
||
namespace proof_system::honk { | ||
template <ECCVMFlavor Flavor> class ECCVMComposer_ { | ||
public: | ||
using CircuitConstructor = ECCVMCircuitBuilder<Flavor>; | ||
using ProvingKey = typename Flavor::ProvingKey; | ||
using VerificationKey = typename Flavor::VerificationKey; | ||
using PCS = typename Flavor::PCS; | ||
using CommitmentKey = typename Flavor::CommitmentKey; | ||
using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; | ||
|
||
static constexpr std::string_view NAME_STRING = "ECCVM"; | ||
static constexpr size_t NUM_RESERVED_GATES = 0; // equal to the number of multilinear evaluations leaked | ||
static constexpr size_t NUM_WIRES = CircuitConstructor::NUM_WIRES; | ||
std::shared_ptr<ProvingKey> proving_key; | ||
std::shared_ptr<VerificationKey> verification_key; | ||
|
||
// The crs_factory holds the path to the srs and exposes methods to extract the srs elements | ||
std::shared_ptr<srs::factories::CrsFactory<typename Flavor::Curve>> crs_factory_; | ||
|
||
// The commitment key is passed to the prover but also used herein to compute the verfication key commitments | ||
std::shared_ptr<CommitmentKey> commitment_key; | ||
|
||
std::vector<uint32_t> recursive_proof_public_input_indices; | ||
bool contains_recursive_proof = false; | ||
bool computed_witness = false; | ||
ECCVMComposer_() requires(std::same_as<Flavor, honk::flavor::ECCVMGrumpkin>) | ||
{ | ||
crs_factory_ = barretenberg::srs::get_grumpkin_crs_factory(); | ||
}; | ||
ECCVMComposer_() requires(std::same_as<Flavor, honk::flavor::ECCVM>) | ||
{ | ||
crs_factory_ = barretenberg::srs::get_crs_factory(); | ||
}; | ||
|
||
explicit ECCVMComposer_(std::shared_ptr<srs::factories::CrsFactory<typename Flavor::Curve>> crs_factory) | ||
: crs_factory_(std::move(crs_factory)) | ||
{} | ||
|
||
ECCVMComposer_(std::shared_ptr<ProvingKey> p_key, std::shared_ptr<VerificationKey> v_key) | ||
: proving_key(std::move(p_key)) | ||
, verification_key(std::move(v_key)) | ||
{} | ||
|
||
ECCVMComposer_(ECCVMComposer_&& other) noexcept = default; | ||
ECCVMComposer_(ECCVMComposer_ const& other) noexcept = default; | ||
ECCVMComposer_& operator=(ECCVMComposer_&& other) noexcept = default; | ||
ECCVMComposer_& operator=(ECCVMComposer_ const& other) noexcept = default; | ||
~ECCVMComposer_() = default; | ||
|
||
std::shared_ptr<ProvingKey> compute_proving_key(CircuitConstructor& circuit_constructor); | ||
std::shared_ptr<VerificationKey> compute_verification_key(CircuitConstructor& circuit_constructor); | ||
|
||
void compute_witness(CircuitConstructor& circuit_constructor); | ||
|
||
ECCVMProver_<Flavor> create_prover(CircuitConstructor& circuit_constructor); | ||
ECCVMVerifier_<Flavor> create_verifier(CircuitConstructor& circuit_constructor); | ||
|
||
void add_table_column_selector_poly_to_proving_key(polynomial& small, const std::string& tag); | ||
|
||
void compute_commitment_key(size_t circuit_size) | ||
{ | ||
commitment_key = std::make_shared<CommitmentKey>(circuit_size, crs_factory_); | ||
}; | ||
}; | ||
extern template class ECCVMComposer_<honk::flavor::ECCVM>; | ||
extern template class ECCVMComposer_<honk::flavor::ECCVMGrumpkin>; | ||
|
||
// TODO(#532): this pattern is weird; is this not instantiating the templates? | ||
using ECCVMComposer = ECCVMComposer_<honk::flavor::ECCVM>; | ||
using ECCVMGrumpkinComposer = ECCVMComposer_<honk::flavor::ECCVMGrumpkin>; | ||
|
||
} // namespace proof_system::honk |
115 changes: 115 additions & 0 deletions
115
circuits/cpp/barretenberg/cpp/src/barretenberg/honk/composer/eccvm_composer.test.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
#include <cstddef> | ||
#include <cstdint> | ||
#include <gtest/gtest.h> | ||
#include <vector> | ||
|
||
#include "barretenberg/honk/composer/eccvm_composer.hpp" | ||
#include "barretenberg/honk/proof_system/prover.hpp" | ||
#include "barretenberg/honk/sumcheck/sumcheck_round.hpp" | ||
#include "barretenberg/honk/utils/grand_product_delta.hpp" | ||
#include "barretenberg/numeric/uint256/uint256.hpp" | ||
#include "barretenberg/polynomials/polynomial.hpp" | ||
#include "barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp" | ||
#include "barretenberg/proof_system/relations/permutation_relation.hpp" | ||
#include "barretenberg/proof_system/relations/relation_parameters.hpp" | ||
|
||
using namespace proof_system::honk; | ||
|
||
namespace test_standard_honk_composer { | ||
|
||
template <typename Flavor> class ECCVMComposerTests : public ::testing::Test { | ||
protected: | ||
// TODO(640): The Standard Honk on Grumpkin test suite fails unless the SRS is initialised for every test. | ||
void SetUp() override | ||
{ | ||
if constexpr (std::is_same<Flavor, flavor::ECCVMGrumpkin>::value) { | ||
barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); | ||
} else { | ||
barretenberg::srs::init_crs_factory("../srs_db/ignition"); | ||
} | ||
}; | ||
}; | ||
|
||
using FlavorTypes = ::testing::Types<flavor::ECCVM, flavor::ECCVMGrumpkin>; | ||
TYPED_TEST_SUITE(ECCVMComposerTests, FlavorTypes); | ||
|
||
namespace { | ||
auto& engine = numeric::random::get_debug_engine(); | ||
} | ||
template <typename Flavor> | ||
proof_system::ECCVMCircuitBuilder<Flavor> generate_trace(numeric::random::Engine* engine = nullptr) | ||
{ | ||
proof_system::ECCVMCircuitBuilder<Flavor> result; | ||
using G1 = typename Flavor::CycleGroup; | ||
using Fr = typename G1::Fr; | ||
|
||
auto generators = G1::template derive_generators<3>(); | ||
|
||
typename G1::element a = generators[0]; | ||
typename G1::element b = generators[1]; | ||
typename G1::element c = generators[2]; | ||
Fr x = Fr::random_element(engine); | ||
Fr y = Fr::random_element(engine); | ||
|
||
typename G1::element expected_1 = (a * x) + a + a + (b * y) + (b * x) + (b * x); | ||
typename G1::element expected_2 = (a * x) + c + (b * x); | ||
|
||
result.add_accumulate(a); | ||
result.mul_accumulate(a, x); | ||
result.mul_accumulate(b, x); | ||
result.mul_accumulate(b, y); | ||
result.add_accumulate(a); | ||
result.mul_accumulate(b, x); | ||
result.eq(expected_1); | ||
result.add_accumulate(c); | ||
result.mul_accumulate(a, x); | ||
result.mul_accumulate(b, x); | ||
result.eq(expected_2); | ||
result.mul_accumulate(a, x); | ||
result.mul_accumulate(b, x); | ||
result.mul_accumulate(c, x); | ||
|
||
return result; | ||
} | ||
|
||
TYPED_TEST(ECCVMComposerTests, BaseCase) | ||
{ | ||
using Flavor = TypeParam; | ||
|
||
auto circuit_constructor = generate_trace<Flavor>(&engine); | ||
|
||
auto composer = ECCVMComposer_<Flavor>(); | ||
auto prover = composer.create_prover(circuit_constructor); | ||
|
||
// / size_t pidx = 0; | ||
// for (auto& p : prover.prover_polynomials) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you want to leave it in? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no, will remove |
||
// size_t count = 0; | ||
// for (auto& x : p) { | ||
// std::cout << "poly[" << pidx << "][" << count << "] = " << x << std::endl; | ||
// count++; | ||
// } | ||
// pidx++; | ||
// } | ||
auto proof = prover.construct_proof(); | ||
auto verifier = composer.create_verifier(circuit_constructor); | ||
bool verified = verifier.verify_proof(proof); | ||
ASSERT_TRUE(verified); | ||
} | ||
|
||
TYPED_TEST(ECCVMComposerTests, EqFails) | ||
{ | ||
using Flavor = TypeParam; | ||
|
||
using G1 = typename Flavor::CycleGroup; | ||
auto circuit_constructor = generate_trace<Flavor>(&engine); | ||
// create an eq opcode that is not satisfied | ||
circuit_constructor.eq(G1::affine_one); | ||
auto composer = ECCVMComposer_<Flavor>(); | ||
auto prover = composer.create_prover(circuit_constructor); | ||
|
||
auto proof = prover.construct_proof(); | ||
auto verifier = composer.create_verifier(circuit_constructor); | ||
bool verified = verifier.verify_proof(proof); | ||
ASSERT_FALSE(verified); | ||
} | ||
} // namespace test_standard_honk_composer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no test for the reset operation