-
Notifications
You must be signed in to change notification settings - Fork 296
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: sumcheck part of ECCVM recursive verifier instantiated as an UltraCircuit #6413
Changes from 48 commits
f3571c6
927b78b
8b3a8cd
1afccd1
0e368c1
e512732
1ea0798
d3a94e4
3a0d99f
79e448a
0b8a833
038ca2c
c89511f
1b12784
b5f4daf
76239b2
b685b09
5105e9c
f923145
c4a5d0a
50bb183
db48cd7
5b82114
75cd6a3
5b59b40
3204ef1
7bf7eae
038de13
88affab
955cad0
3405b61
9ea8d2b
a2bcef8
c776938
3f898b2
4710dd1
221afd4
0e507c0
660074d
9388d5f
bb424aa
995bea2
a176c23
46aa627
f67297d
7ccaca1
8d855ab
82919be
083ce09
3c5413d
4da1bce
dc0f0fc
0b68af5
08f6c88
35e63ac
fea7c51
d53f8a8
ce88bb0
a9f3b86
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,120 +17,28 @@ bool ECCVMVerifier::verify_proof(const HonkProof& proof) | |
CommitmentLabels commitment_labels; | ||
|
||
const auto circuit_size = transcript->template receive_from_prover<uint32_t>("circuit_size"); | ||
ASSERT(circuit_size == key->circuit_size); | ||
|
||
if (circuit_size != key->circuit_size) { | ||
return false; | ||
for (auto [comm, label] : zip_view(commitments.get_wires(), commitment_labels.get_wires())) { | ||
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. nice |
||
comm = transcript->template receive_from_prover<Commitment>(label); | ||
} | ||
|
||
// Utility for extracting commitments from transcript | ||
const auto receive_commitment = [&](const std::string& label) { | ||
return transcript->template receive_from_prover<Commitment>(label); | ||
}; | ||
|
||
// Get commitments to VM wires | ||
commitments.transcript_add = receive_commitment(commitment_labels.transcript_add); | ||
commitments.transcript_mul = receive_commitment(commitment_labels.transcript_mul); | ||
commitments.transcript_eq = receive_commitment(commitment_labels.transcript_eq); | ||
commitments.transcript_msm_transition = receive_commitment(commitment_labels.transcript_msm_transition); | ||
commitments.transcript_pc = receive_commitment(commitment_labels.transcript_pc); | ||
commitments.transcript_msm_count = receive_commitment(commitment_labels.transcript_msm_count); | ||
commitments.transcript_Px = receive_commitment(commitment_labels.transcript_Px); | ||
commitments.transcript_Py = receive_commitment(commitment_labels.transcript_Py); | ||
commitments.transcript_z1 = receive_commitment(commitment_labels.transcript_z1); | ||
commitments.transcript_z2 = receive_commitment(commitment_labels.transcript_z2); | ||
commitments.transcript_z1zero = receive_commitment(commitment_labels.transcript_z1zero); | ||
commitments.transcript_z2zero = receive_commitment(commitment_labels.transcript_z2zero); | ||
commitments.transcript_op = receive_commitment(commitment_labels.transcript_op); | ||
commitments.transcript_accumulator_x = receive_commitment(commitment_labels.transcript_accumulator_x); | ||
commitments.transcript_accumulator_y = receive_commitment(commitment_labels.transcript_accumulator_y); | ||
commitments.transcript_msm_x = receive_commitment(commitment_labels.transcript_msm_x); | ||
commitments.transcript_msm_y = receive_commitment(commitment_labels.transcript_msm_y); | ||
commitments.precompute_pc = receive_commitment(commitment_labels.precompute_pc); | ||
commitments.precompute_point_transition = receive_commitment(commitment_labels.precompute_point_transition); | ||
commitments.precompute_round = receive_commitment(commitment_labels.precompute_round); | ||
commitments.precompute_scalar_sum = receive_commitment(commitment_labels.precompute_scalar_sum); | ||
commitments.precompute_s1hi = receive_commitment(commitment_labels.precompute_s1hi); | ||
commitments.precompute_s1lo = receive_commitment(commitment_labels.precompute_s1lo); | ||
commitments.precompute_s2hi = receive_commitment(commitment_labels.precompute_s2hi); | ||
commitments.precompute_s2lo = receive_commitment(commitment_labels.precompute_s2lo); | ||
commitments.precompute_s3hi = receive_commitment(commitment_labels.precompute_s3hi); | ||
commitments.precompute_s3lo = receive_commitment(commitment_labels.precompute_s3lo); | ||
commitments.precompute_s4hi = receive_commitment(commitment_labels.precompute_s4hi); | ||
commitments.precompute_s4lo = receive_commitment(commitment_labels.precompute_s4lo); | ||
commitments.precompute_skew = receive_commitment(commitment_labels.precompute_skew); | ||
commitments.precompute_dx = receive_commitment(commitment_labels.precompute_dx); | ||
commitments.precompute_dy = receive_commitment(commitment_labels.precompute_dy); | ||
commitments.precompute_tx = receive_commitment(commitment_labels.precompute_tx); | ||
commitments.precompute_ty = receive_commitment(commitment_labels.precompute_ty); | ||
commitments.msm_transition = receive_commitment(commitment_labels.msm_transition); | ||
commitments.msm_add = receive_commitment(commitment_labels.msm_add); | ||
commitments.msm_double = receive_commitment(commitment_labels.msm_double); | ||
commitments.msm_skew = receive_commitment(commitment_labels.msm_skew); | ||
commitments.msm_accumulator_x = receive_commitment(commitment_labels.msm_accumulator_x); | ||
commitments.msm_accumulator_y = receive_commitment(commitment_labels.msm_accumulator_y); | ||
commitments.msm_pc = receive_commitment(commitment_labels.msm_pc); | ||
commitments.msm_size_of_msm = receive_commitment(commitment_labels.msm_size_of_msm); | ||
commitments.msm_count = receive_commitment(commitment_labels.msm_count); | ||
commitments.msm_round = receive_commitment(commitment_labels.msm_round); | ||
commitments.msm_add1 = receive_commitment(commitment_labels.msm_add1); | ||
commitments.msm_add2 = receive_commitment(commitment_labels.msm_add2); | ||
commitments.msm_add3 = receive_commitment(commitment_labels.msm_add3); | ||
commitments.msm_add4 = receive_commitment(commitment_labels.msm_add4); | ||
commitments.msm_x1 = receive_commitment(commitment_labels.msm_x1); | ||
commitments.msm_y1 = receive_commitment(commitment_labels.msm_y1); | ||
commitments.msm_x2 = receive_commitment(commitment_labels.msm_x2); | ||
commitments.msm_y2 = receive_commitment(commitment_labels.msm_y2); | ||
commitments.msm_x3 = receive_commitment(commitment_labels.msm_x3); | ||
commitments.msm_y3 = receive_commitment(commitment_labels.msm_y3); | ||
commitments.msm_x4 = receive_commitment(commitment_labels.msm_x4); | ||
commitments.msm_y4 = receive_commitment(commitment_labels.msm_y4); | ||
commitments.msm_collision_x1 = receive_commitment(commitment_labels.msm_collision_x1); | ||
commitments.msm_collision_x2 = receive_commitment(commitment_labels.msm_collision_x2); | ||
commitments.msm_collision_x3 = receive_commitment(commitment_labels.msm_collision_x3); | ||
commitments.msm_collision_x4 = receive_commitment(commitment_labels.msm_collision_x4); | ||
commitments.msm_lambda1 = receive_commitment(commitment_labels.msm_lambda1); | ||
commitments.msm_lambda2 = receive_commitment(commitment_labels.msm_lambda2); | ||
commitments.msm_lambda3 = receive_commitment(commitment_labels.msm_lambda3); | ||
commitments.msm_lambda4 = receive_commitment(commitment_labels.msm_lambda4); | ||
commitments.msm_slice1 = receive_commitment(commitment_labels.msm_slice1); | ||
commitments.msm_slice2 = receive_commitment(commitment_labels.msm_slice2); | ||
commitments.msm_slice3 = receive_commitment(commitment_labels.msm_slice3); | ||
commitments.msm_slice4 = receive_commitment(commitment_labels.msm_slice4); | ||
commitments.transcript_accumulator_empty = receive_commitment(commitment_labels.transcript_accumulator_empty); | ||
commitments.transcript_reset_accumulator = receive_commitment(commitment_labels.transcript_reset_accumulator); | ||
commitments.precompute_select = receive_commitment(commitment_labels.precompute_select); | ||
commitments.lookup_read_counts_0 = receive_commitment(commitment_labels.lookup_read_counts_0); | ||
commitments.lookup_read_counts_1 = receive_commitment(commitment_labels.lookup_read_counts_1); | ||
commitments.transcript_base_infinity = receive_commitment(commitment_labels.transcript_base_infinity); | ||
commitments.transcript_base_x_inverse = receive_commitment(commitment_labels.transcript_base_x_inverse); | ||
commitments.transcript_base_y_inverse = receive_commitment(commitment_labels.transcript_base_y_inverse); | ||
commitments.transcript_add_x_equal = receive_commitment(commitment_labels.transcript_add_x_equal); | ||
commitments.transcript_add_y_equal = receive_commitment(commitment_labels.transcript_add_y_equal); | ||
commitments.transcript_add_lambda = receive_commitment(commitment_labels.transcript_add_lambda); | ||
commitments.transcript_msm_intermediate_x = receive_commitment(commitment_labels.transcript_msm_intermediate_x); | ||
commitments.transcript_msm_intermediate_y = receive_commitment(commitment_labels.transcript_msm_intermediate_y); | ||
commitments.transcript_msm_infinity = receive_commitment(commitment_labels.transcript_msm_infinity); | ||
commitments.transcript_msm_x_inverse = receive_commitment(commitment_labels.transcript_msm_x_inverse); | ||
commitments.transcript_msm_count_zero_at_transition = | ||
receive_commitment(commitment_labels.transcript_msm_count_zero_at_transition); | ||
commitments.transcript_msm_count_at_transition_inverse = | ||
receive_commitment(commitment_labels.transcript_msm_count_at_transition_inverse); | ||
|
||
// Get challenge for sorted list batching and wire four memory records | ||
auto [beta, gamma] = transcript->template get_challenges<FF>("beta", "gamma"); | ||
|
||
relation_parameters.gamma = gamma; | ||
auto beta_sqr = beta * beta; | ||
relation_parameters.gamma = gamma; | ||
relation_parameters.beta = beta; | ||
relation_parameters.beta_sqr = beta_sqr; | ||
relation_parameters.beta_sqr = beta * beta; | ||
relation_parameters.beta_cube = beta_sqr * beta; | ||
relation_parameters.eccvm_set_permutation_delta = | ||
gamma * (gamma + beta_sqr) * (gamma + beta_sqr + beta_sqr) * (gamma + beta_sqr + beta_sqr + beta_sqr); | ||
relation_parameters.eccvm_set_permutation_delta = relation_parameters.eccvm_set_permutation_delta.invert(); | ||
|
||
// Get commitment to permutation and lookup grand products | ||
commitments.lookup_inverses = receive_commitment(commitment_labels.lookup_inverses); | ||
commitments.z_perm = receive_commitment(commitment_labels.z_perm); | ||
commitments.lookup_inverses = | ||
transcript->template receive_from_prover<Commitment>(commitment_labels.lookup_inverses); | ||
commitments.z_perm = transcript->template receive_from_prover<Commitment>(commitment_labels.z_perm); | ||
|
||
// Execute Sumcheck Verifier | ||
const size_t log_circuit_size = numeric::get_msb(circuit_size); | ||
|
@@ -160,7 +68,7 @@ bool ECCVMVerifier::verify_proof(const HonkProof& proof) | |
// TODO(#768): Find a better way to do this. See issue for details. | ||
bool univariate_opening_verified = false; | ||
{ | ||
auto hack_commitment = receive_commitment("Translation:hack_commitment"); | ||
auto hack_commitment = transcript->template receive_from_prover<Commitment>("Translation:hack_commitment"); | ||
|
||
FF evaluation_challenge_x = transcript->template get_challenge<FF>("Translation:evaluation_challenge_x"); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
barretenberg_module(eccvm_recursion eccvm stdlib_circuit_builders stdlib_primitives) | ||
barretenberg_module(eccvm_recursion eccvm stdlib_honk_recursion) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#include "barretenberg/eccvm_recursion/eccvm_recursive_flavor.hpp" | ||
#include "barretenberg/flavor/relation_definitions.hpp" | ||
#include "barretenberg/relations/ecc_vm/ecc_bools_relation_impl.hpp" | ||
#include "barretenberg/stdlib/primitives/bigfield/bigfield.hpp" | ||
|
||
namespace bb { | ||
template class ECCVMBoolsRelationImpl<stdlib::bigfield<UltraCircuitBuilder, bb::Bn254FqParams>>; | ||
template class ECCVMBoolsRelationImpl<stdlib::bigfield<MegaCircuitBuilder, bb::Bn254FqParams>>; | ||
DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(ECCVMBoolsRelationImpl, ECCVMRecursiveFlavor_<UltraCircuitBuilder>); | ||
DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(ECCVMBoolsRelationImpl, ECCVMRecursiveFlavor_<MegaCircuitBuilder>); | ||
} // namespace bb |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,8 +22,10 @@ namespace bb { | |
template <typename BuilderType> class ECCVMRecursiveFlavor_ { | ||
public: | ||
using CircuitBuilder = BuilderType; // determines the arithmetisation of recursive verifier | ||
using FF = stdlib::bigfield<CircuitBuilder, bb::Bn254FqParams>; | ||
using BF = stdlib::field_t<CircuitBuilder>; | ||
using Curve = stdlib::bn254<CircuitBuilder, true>; | ||
using Commitment = Curve::AffineElement; | ||
using FF = Curve::ScalarField; | ||
using BF = Curve::BaseField; | ||
using RelationSeparator = FF; | ||
using NativeFlavor = ECCVMFlavor; | ||
using NativeVerificationKey = NativeFlavor::VerificationKey; | ||
|
@@ -70,6 +72,59 @@ template <typename BuilderType> class ECCVMRecursiveFlavor_ { | |
using Base::Base; | ||
}; | ||
|
||
using VerifierCommitmentKey = VerifierCommitmentKey<Curve>; | ||
/** | ||
* @brief The verification key is responsible for storing the the commitments to the precomputed (non-witnessk) | ||
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. typo (witnessk) |
||
* polynomials used by the verifier. | ||
* | ||
* @note Note the discrepancy with what sort of data is stored here vs in the proving key. We may want to | ||
* resolve that, and split out separate PrecomputedPolynom ials/Commitments data for clarity but also for | ||
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. space typo |
||
* portability of our circuits. | ||
*/ | ||
class VerificationKey | ||
: public VerificationKey_<ECCVMFlavor::PrecomputedEntities<Commitment>, VerifierCommitmentKey> { | ||
public: | ||
VerificationKey(const size_t circuit_size, const size_t num_public_inputs) | ||
{ | ||
this->circuit_size = circuit_size; | ||
this->log_circuit_size = numeric::get_msb(circuit_size); | ||
this->num_public_inputs = num_public_inputs; | ||
}; | ||
|
||
/** | ||
* @brief Construct a new Verification Key with stdlib types from a provided native verification | ||
* key | ||
* | ||
* @param builder | ||
* @param native_key Native verification key from which to extract the precomputed commitments | ||
*/ | ||
|
||
VerificationKey(CircuitBuilder* builder, const std::shared_ptr<NativeVerificationKey>& native_key) | ||
{ | ||
this->pcs_verification_key = std::make_shared<VerifierCommitmentKey>( | ||
builder, native_key->circuit_size, native_key->pcs_verification_key); | ||
this->circuit_size = native_key->circuit_size; | ||
this->log_circuit_size = numeric::get_msb(this->circuit_size); | ||
this->num_public_inputs = native_key->num_public_inputs; | ||
this->pub_inputs_offset = native_key->pub_inputs_offset; | ||
|
||
for (auto [native_commitment, commitment] : zip_view(native_key->get_all(), this->get_all())) { | ||
commitment = Commitment::from_witness(builder, native_commitment); | ||
} | ||
} | ||
}; | ||
|
||
/** | ||
* @brief A container for the witness commitments. | ||
*/ | ||
using WitnessCommitments = ECCVMFlavor::WitnessEntities<Commitment>; | ||
|
||
using CommitmentLabels = ECCVMFlavor::CommitmentLabels; | ||
// Reuse the VerifierCommitments from ECCVM | ||
using VerifierCommitments = ECCVMFlavor::VerifierCommitments_<Commitment, VerificationKey>; | ||
// Reuse the transcript from ECCVM | ||
using Transcript = bb::BaseTranscript<bb::stdlib::recursion::honk::StdlibTranscriptParams<CircuitBuilder>>; | ||
|
||
}; // NOLINTEND(cppcoreguidelines-avoid-const-or-ref-data-members) | ||
|
||
} // namespace bb |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#include "./eccvm_recursive_verifier.hpp" | ||
#include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" | ||
#include "barretenberg/sumcheck/sumcheck.hpp" | ||
#include "barretenberg/transcript/transcript.hpp" | ||
|
||
namespace bb { | ||
|
||
template <typename Flavor> | ||
ECCVMRecursiveVerifier_<Flavor>::ECCVMRecursiveVerifier_( | ||
Builder* builder, const std::shared_ptr<NativeVerificationKey>& native_verifier_key) | ||
: key(std::make_shared<VerificationKey>(builder, native_verifier_key)) | ||
, builder(builder) | ||
{} | ||
|
||
/** | ||
* @brief This function verifies an ECCVM Honk proof for given program settings up to sumcheck. | ||
*/ | ||
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1007): Finish this | ||
template <typename Flavor> bool ECCVMRecursiveVerifier_<Flavor>::verify_proof(const HonkProof& proof) | ||
{ | ||
|
||
RelationParameters<FF> relation_parameters; | ||
|
||
StdlibProof<Builder> stdlib_proof = bb::convert_proof_to_witness(builder, proof); | ||
transcript = std::make_shared<Transcript>(stdlib_proof); | ||
|
||
VerifierCommitments commitments{ key }; | ||
CommitmentLabels commitment_labels; | ||
|
||
const auto circuit_size = transcript->template receive_from_prover<BF>("circuit_size"); | ||
for (auto [comm, label] : zip_view(commitments.get_wires(), commitment_labels.get_wires())) { | ||
comm = transcript->template receive_from_prover<Commitment>(label); | ||
} | ||
|
||
// Get challenge for sorted list batching and wire four memory records | ||
auto [beta, gamma] = transcript->template get_challenges<FF>("beta", "gamma"); | ||
|
||
auto beta_sqr = beta * beta; | ||
|
||
relation_parameters.gamma = gamma; | ||
relation_parameters.beta = beta; | ||
relation_parameters.beta_sqr = beta * beta; | ||
relation_parameters.beta_cube = beta_sqr * beta; | ||
relation_parameters.eccvm_set_permutation_delta = | ||
gamma * (gamma + beta_sqr) * (gamma + beta_sqr + beta_sqr) * (gamma + beta_sqr + beta_sqr + beta_sqr); | ||
relation_parameters.eccvm_set_permutation_delta = relation_parameters.eccvm_set_permutation_delta.invert(); | ||
|
||
// Get commitment to permutation and lookup grand products | ||
commitments.lookup_inverses = | ||
transcript->template receive_from_prover<Commitment>(commitment_labels.lookup_inverses); | ||
commitments.z_perm = transcript->template receive_from_prover<Commitment>(commitment_labels.z_perm); | ||
|
||
// Execute Sumcheck Verifier | ||
const size_t log_circuit_size = numeric::get_msb(static_cast<uint32_t>(circuit_size.get_value())); | ||
auto sumcheck = SumcheckVerifier<Flavor>(log_circuit_size, transcript, FF(0)); | ||
FF alpha = transcript->template get_challenge<FF>("Sumcheck:alpha"); | ||
std::vector<FF> gate_challenges(static_cast<size_t>(numeric::get_msb(key->circuit_size))); | ||
for (size_t idx = 0; idx < gate_challenges.size(); idx++) { | ||
gate_challenges[idx] = transcript->template get_challenge<FF>("Sumcheck:gate_challenge_" + std::to_string(idx)); | ||
} | ||
|
||
auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = | ||
sumcheck.verify(relation_parameters, alpha, gate_challenges); | ||
|
||
return sumcheck_verified.value(); | ||
} | ||
|
||
template class ECCVMRecursiveVerifier_<ECCVMRecursiveFlavor_<UltraCircuitBuilder>>; | ||
} // namespace bb |
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.
Why did you change this?
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.
To make it uniform to the recursive verifier but can revert