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

chore: fixed VK in MegaZK/ECCVM/Translator/Tube Recursive Verifier circuits #11377

Merged
merged 45 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
9a71a91
eccvm sumcheck butchered
iakovenkos Jan 10, 2025
1b18f05
wip wip
iakovenkos Jan 10, 2025
e00dd04
eccvm verifies
iakovenkos Jan 14, 2025
682c075
build fixed recursion failing
iakovenkos Jan 14, 2025
af6d6e6
debugging rec verifier
iakovenkos Jan 14, 2025
9323abe
recursion fix
iakovenkos Jan 14, 2025
230ce10
sumcheck output unified
iakovenkos Jan 14, 2025
f1eb3c5
remove self reduce
iakovenkos Jan 15, 2025
8cb98b0
trying to constify eccvm recursive
iakovenkos Jan 15, 2025
806ef49
Merge branch 'master' into si/fixing-eccvm-zk-sumcheck
iakovenkos Jan 16, 2025
41654f3
Merge branch 'master' into si/fixing-eccvm-zk-sumcheck
iakovenkos Jan 16, 2025
c91f533
build fix
iakovenkos Jan 16, 2025
e1d1d11
Merge branch 'si/fixing-eccvm-zk-sumcheck' of github.com:AztecProtoco…
iakovenkos Jan 16, 2025
7c73666
tests fixed
iakovenkos Jan 16, 2025
f525ef2
Merge branch 'master' into si/fixing-eccvm-zk-sumcheck
iakovenkos Jan 16, 2025
6aec0f7
commited sumcheck test added
iakovenkos Jan 17, 2025
74cd1a8
test cleaned up
iakovenkos Jan 17, 2025
f53a308
creating test for pcs
iakovenkos Jan 17, 2025
2f1f99d
Merge branch 'si/fixing-eccvm-zk-sumcheck' of github.com:AztecProtoco…
iakovenkos Jan 17, 2025
35df724
Merge branch 'master' into si/fixing-eccvm-zk-sumcheck
iakovenkos Jan 17, 2025
f4c3dc8
shplemini test + clean-up + figuring out constness
iakovenkos Jan 18, 2025
1587941
const proof size + clean up + docs
iakovenkos Jan 20, 2025
e94c031
eccvm bench correction
iakovenkos Jan 20, 2025
9e5e4e7
build fix
iakovenkos Jan 20, 2025
51b3766
Merge branch 'master' into si/fixing-eccvm-zk-sumcheck
iakovenkos Jan 20, 2025
6731c5d
more clean-up
iakovenkos Jan 20, 2025
fc108a3
Merge branch 'si/fixing-eccvm-zk-sumcheck' of github.com:AztecProtoco…
iakovenkos Jan 20, 2025
80b6bf0
Merge branch 'master' into si/fixing-eccvm-zk-sumcheck
iakovenkos Jan 20, 2025
48a1a18
eccvm recursive failure tests fixed
iakovenkos Jan 20, 2025
fdb62f1
bug fix
iakovenkos Jan 20, 2025
aa3f90b
MegaZKRecursive const vk fix + test
iakovenkos Jan 21, 2025
d2f4581
translator test added
iakovenkos Jan 21, 2025
4f878ab
eccvm test added
iakovenkos Jan 21, 2025
7ceacea
some renaming
iakovenkos Jan 21, 2025
4a3f07b
resolving comments
iakovenkos Jan 21, 2025
98d304f
killed optional bool in sumcheck output + resolving comments
iakovenkos Jan 22, 2025
6b5691f
Merge remote-tracking branch 'origin/si/fixing-eccvm-zk-sumcheck' int…
iakovenkos Jan 22, 2025
db9c2b1
+tube_vk test
iakovenkos Jan 22, 2025
37cf638
isolated a method that compares recursive verifier circuits in variou…
iakovenkos Jan 22, 2025
c3e438f
Merge branch 'master' into si/tube-const-tests
iakovenkos Jan 22, 2025
1473705
Merge branch 'master' into si/tube-const-tests
iakovenkos Jan 23, 2025
af3b502
bad merge fix
iakovenkos Jan 23, 2025
b811b5e
remove noise in sumcheck docs
iakovenkos Jan 23, 2025
205b858
wrong assert fix
iakovenkos Jan 23, 2025
fcc8df7
clean-up after review
iakovenkos Jan 24, 2025
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 @@ -3,6 +3,7 @@
#include "barretenberg/client_ivc/client_ivc.hpp"
#include "barretenberg/client_ivc/test_bench_shared.hpp"
#include "barretenberg/common/test.hpp"
#include "barretenberg/stdlib/honk_verifier/ultra_verification_keys_comparator.hpp"

namespace bb::stdlib::recursion::honk {
class ClientIVCRecursionTests : public testing::Test {
Expand All @@ -11,9 +12,9 @@ class ClientIVCRecursionTests : public testing::Test {
using ClientIVCVerifier = ClientIVCRecursiveVerifier;
using FoldVerifierInput = ClientIVCVerifier::FoldVerifierInput;
using Proof = ClientIVC::Proof;
using Flavor = UltraRollupRecursiveFlavor_<Builder>;
using NativeFlavor = Flavor::NativeFlavor;
using UltraRecursiveVerifier = UltraRecursiveVerifier_<Flavor>;
using RollupFlavor = UltraRollupRecursiveFlavor_<Builder>;
using NativeFlavor = RollupFlavor::NativeFlavor;
using UltraRecursiveVerifier = UltraRecursiveVerifier_<RollupFlavor>;
using MockCircuitProducer = PrivateFunctionExecutionMockCircuitProducer;
using IVCVerificationKey = ClientIVC::VerificationKey;

Expand All @@ -34,11 +35,11 @@ class ClientIVCRecursionTests : public testing::Test {
* @brief Construct a genuine ClientIVC prover output based on accumulation of an arbitrary set of mock circuits
*
*/
static ClientIVCProverOutput construct_client_ivc_prover_output(ClientIVC& ivc)
static ClientIVCProverOutput construct_client_ivc_prover_output(ClientIVC& ivc, const size_t NUM_CIRCUITS = 2)
{
// Construct and accumulate a series of mocked private function execution circuits
MockCircuitProducer circuit_producer;
size_t NUM_CIRCUITS = 2;

for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
auto circuit = circuit_producer.create_next_circuit(ivc);
ivc.accumulate(circuit);
Expand Down Expand Up @@ -120,6 +121,7 @@ TEST_F(ClientIVCRecursionTests, ClientTubeBase)
// Construct and verify a proof for the ClientIVC Recursive Verifier circuit
auto proving_key = std::make_shared<DeciderProvingKey_<NativeFlavor>>(*tube_builder);
UltraProver_<NativeFlavor> tube_prover{ proving_key };
// Prove the CIVCRecursiveVerifier circuit
auto native_tube_proof = tube_prover.construct_proof();

// Natively verify the tube proof
Expand All @@ -130,13 +132,13 @@ TEST_F(ClientIVCRecursionTests, ClientTubeBase)

// Construct a base rollup circuit that recursively verifies the tube proof and forwards the IPA proof.
Builder base_builder;
auto native_vk = std::make_shared<NativeFlavor::VerificationKey>(proving_key->proving_key);
auto vk = std::make_shared<Flavor::VerificationKey>(&base_builder, native_vk);
auto tube_proof = bb::convert_native_proof_to_stdlib(&base_builder, native_tube_proof);
UltraRecursiveVerifier base_verifier{ &base_builder, vk };
UltraRecursiveVerifierOutput<Flavor> output = base_verifier.verify_proof(
tube_proof, stdlib::recursion::init_default_aggregation_state<Builder, Flavor::Curve>(base_builder));
info("UH Recursive Verifier: num prefinalized gates = ", base_builder.num_gates);
auto tube_vk = std::make_shared<NativeFlavor::VerificationKey>(proving_key->proving_key);
auto base_vk = std::make_shared<RollupFlavor::VerificationKey>(&base_builder, tube_vk);
auto base_tube_proof = bb::convert_native_proof_to_stdlib(&base_builder, native_tube_proof);
UltraRecursiveVerifier base_verifier{ &base_builder, base_vk };
UltraRecursiveVerifierOutput<RollupFlavor> output = base_verifier.verify_proof(
base_tube_proof, stdlib::recursion::init_default_aggregation_state<Builder, RollupFlavor::Curve>(base_builder));
info("Tube UH Recursive Verifier: num prefinalized gates = ", base_builder.num_gates);
base_builder.add_pairing_point_accumulator(output.agg_obj.get_witness_indices());
base_builder.add_ipa_claim(output.ipa_opening_claim.get_witness_indices());
base_builder.ipa_proof = tube_prover.proving_key->proving_key.ipa_proof;
Expand All @@ -150,4 +152,48 @@ TEST_F(ClientIVCRecursionTests, ClientTubeBase)
ipa_verification_key, output.ipa_opening_claim.get_native_opening_claim(), ipa_transcript);
}

// Ensure that the Client IVC Recursive Verifier Circuit does not depend on the Client IVC input
TEST_F(ClientIVCRecursionTests, TubeVKIndependentOfInputCircuits)
{

// Retrieves the trace blocks (each consisting of a specific gate) from the recursive verifier circuit
auto get_blocks = [](size_t inner_size)
-> std::tuple<typename Builder::ExecutionTrace, std::shared_ptr<NativeFlavor::VerificationKey>> {
ClientIVC ivc{ trace_settings };

auto [proof, ivc_vk] = construct_client_ivc_prover_output(ivc, inner_size);

auto tube_builder = std::make_shared<Builder>();
ClientIVCVerifier verifier{ tube_builder, ivc_vk };

auto client_ivc_rec_verifier_output = verifier.verify(proof);

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1069): fix this by taking it from the output
// instead of
// just using default.
tube_builder->add_pairing_point_accumulator(
stdlib::recursion::init_default_agg_obj_indices<Builder>(*tube_builder));
// The tube only calls an IPA recursive verifier once, so we can just add this IPA claim and proof
tube_builder->add_ipa_claim(client_ivc_rec_verifier_output.opening_claim.get_witness_indices());
tube_builder->ipa_proof =
convert_stdlib_proof_to_native(client_ivc_rec_verifier_output.ipa_transcript->proof_data);

info("ClientIVC Recursive Verifier: num prefinalized gates = ", tube_builder->num_gates);

EXPECT_EQ(tube_builder->failed(), false) << tube_builder->err();

// Construct and verify a proof for the ClientIVC Recursive Verifier circuit
auto proving_key = std::make_shared<DeciderProvingKey_<NativeFlavor>>(*tube_builder);

auto tube_vk = std::make_shared<NativeFlavor::VerificationKey>(proving_key->proving_key);

return { tube_builder->blocks, tube_vk };
};

auto [blocks_2, verification_key_2] = get_blocks(2);
auto [blocks_4, verification_key_4] = get_blocks(4);

compare_ultra_blocks_and_verification_keys<NativeFlavor>({ blocks_2, blocks_4 },
{ verification_key_2, verification_key_4 });
}
} // namespace bb::stdlib::recursion::honk
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "barretenberg/circuit_checker/circuit_checker.hpp"
#include "barretenberg/eccvm/eccvm_prover.hpp"
#include "barretenberg/eccvm/eccvm_verifier.hpp"
#include "barretenberg/stdlib/honk_verifier/ultra_verification_keys_comparator.hpp"
#include "barretenberg/ultra_honk/ultra_prover.hpp"
#include "barretenberg/ultra_honk/ultra_verifier.hpp"

Expand All @@ -20,6 +21,8 @@ template <typename RecursiveFlavor> class ECCVMRecursiveTests : public ::testing
using InnerG1 = InnerFlavor::Commitment;
using InnerFF = InnerFlavor::FF;
using InnerBF = InnerFlavor::BF;
using InnerPK = InnerFlavor::ProvingKey;
using InnerVK = InnerFlavor::VerificationKey;

using Transcript = InnerFlavor::Transcript;

Expand All @@ -42,7 +45,7 @@ template <typename RecursiveFlavor> class ECCVMRecursiveTests : public ::testing
* @param engine
* @return ECCVMCircuitBuilder
*/
static InnerBuilder generate_circuit(numeric::RNG* engine = nullptr)
static InnerBuilder generate_circuit(numeric::RNG* engine = nullptr, const size_t num_iterations = 1)
{
using Curve = curve::BN254;
using G1 = Curve::Element;
Expand All @@ -54,21 +57,22 @@ template <typename RecursiveFlavor> class ECCVMRecursiveTests : public ::testing
G1 c = G1::random_element(engine);
Fr x = Fr::random_element(engine);
Fr y = Fr::random_element(engine);

op_queue->add_accumulate(a);
op_queue->mul_accumulate(a, x);
op_queue->mul_accumulate(b, x);
op_queue->mul_accumulate(b, y);
op_queue->add_accumulate(a);
op_queue->mul_accumulate(b, x);
op_queue->eq_and_reset();
op_queue->add_accumulate(c);
op_queue->mul_accumulate(a, x);
op_queue->mul_accumulate(b, x);
op_queue->eq_and_reset();
op_queue->mul_accumulate(a, x);
op_queue->mul_accumulate(b, x);
op_queue->mul_accumulate(c, x);
for (size_t idx = 0; idx < num_iterations; idx++) {
op_queue->add_accumulate(a);
op_queue->mul_accumulate(a, x);
op_queue->mul_accumulate(b, x);
op_queue->mul_accumulate(b, y);
op_queue->add_accumulate(a);
op_queue->mul_accumulate(b, x);
op_queue->eq_and_reset();
op_queue->add_accumulate(c);
op_queue->mul_accumulate(a, x);
op_queue->mul_accumulate(b, x);
op_queue->eq_and_reset();
op_queue->mul_accumulate(a, x);
op_queue->mul_accumulate(b, x);
op_queue->mul_accumulate(c, x);
}
InnerBuilder builder{ op_queue };
return builder;
}
Expand Down Expand Up @@ -140,6 +144,40 @@ template <typename RecursiveFlavor> class ECCVMRecursiveTests : public ::testing
// Check for a failure flag in the recursive verifier circuit
EXPECT_FALSE(CircuitChecker::check(outer_circuit));
}

static void test_independent_vk_hash()
{

// Retrieves the trace blocks (each consisting of a specific gate) from the recursive verifier circuit
auto get_blocks = [](size_t inner_size) -> std::tuple<typename OuterBuilder::ExecutionTrace,
std::shared_ptr<typename OuterFlavor::VerificationKey>> {
auto inner_circuit = generate_circuit(&engine, inner_size);
InnerProver inner_prover(inner_circuit);
info("test circuit size: ", inner_prover.key->circuit_size);

ECCVMProof inner_proof = inner_prover.construct_proof();
auto verification_key = std::make_shared<typename InnerFlavor::VerificationKey>(inner_prover.key);

// Create a recursive verification circuit for the proof of the inner circuit
OuterBuilder outer_circuit;

RecursiveVerifier verifier{ &outer_circuit, verification_key };

auto [opening_claim, ipa_transcript] = verifier.verify_proof(inner_proof);

auto outer_proving_key = std::make_shared<OuterDeciderProvingKey>(outer_circuit);
auto outer_verification_key =
std::make_shared<typename OuterFlavor::VerificationKey>(outer_proving_key->proving_key);

return { outer_circuit.blocks, outer_verification_key };
};

auto [blocks_20, verification_key_20] = get_blocks(20);
auto [blocks_40, verification_key_40] = get_blocks(40);

compare_ultra_blocks_and_verification_keys<OuterFlavor>({ blocks_20, blocks_40 },
{ verification_key_20, verification_key_40 });
};
};
using FlavorTypes = testing::Types<ECCVMRecursiveFlavor_<UltraCircuitBuilder>>;

Expand All @@ -154,4 +192,9 @@ TYPED_TEST(ECCVMRecursiveTests, SingleRecursiveVerificationFailure)
{
TestFixture::test_recursive_verification_failure();
};

TYPED_TEST(ECCVMRecursiveTests, IndependentVKHash)
{
TestFixture::test_independent_vk_hash();
};
} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "barretenberg/stdlib_circuit_builders/ultra_rollup_recursive_flavor.hpp"
#include "barretenberg/ultra_honk/ultra_prover.hpp"
#include "barretenberg/ultra_honk/ultra_verifier.hpp"
#include "ultra_verification_keys_comparator.hpp"

namespace bb::stdlib::recursion::honk {

Expand Down Expand Up @@ -137,7 +138,7 @@ template <typename RecursiveFlavor> class RecursiveVerifierTest : public testing

/**
* @brief Ensures that the recursive verifier circuit for two inner circuits of different size is the same as the
* proofs are currently constant. This is done by taking each trace block in part and checking all it's selector
* proofs are currently constant. This is done by taking each trace block in part and checking all its selector
* values.
*
*/
Expand All @@ -160,7 +161,6 @@ template <typename RecursiveFlavor> class RecursiveVerifierTest : public testing
// Create a recursive verification circuit for the proof of the inner circuit
OuterBuilder outer_circuit;
RecursiveVerifier verifier{ &outer_circuit, verification_key };
HonkProof honk_proof;

typename RecursiveVerifier::Output verifier_output = verifier.verify_proof(
inner_proof,
Expand All @@ -177,44 +177,11 @@ template <typename RecursiveFlavor> class RecursiveVerifierTest : public testing
return { outer_circuit.blocks, outer_verification_key };
};

bool broke(false);
auto check_eq = [&broke](auto& p1, auto& p2) {
EXPECT_TRUE(p1.size() == p2.size());
for (size_t idx = 0; idx < p1.size(); idx++) {
if (p1[idx] != p2[idx]) {
broke = true;
break;
}
}
};

auto [blocks_10, verification_key_10] = get_blocks(10);
auto [blocks_11, verification_key_11] = get_blocks(11);

size_t block_idx = 0;
for (auto [b_10, b_11] : zip_view(blocks_10.get(), blocks_11.get())) {
info("block index: ", block_idx);
EXPECT_TRUE(b_10.selectors.size() == 13);
EXPECT_TRUE(b_11.selectors.size() == 13);
for (auto [p_10, p_11] : zip_view(b_10.selectors, b_11.selectors)) {
check_eq(p_10, p_11);
}
block_idx++;
}

typename OuterFlavor::CommitmentLabels labels;
for (auto [vk_10, vk_11, label] :
zip_view(verification_key_10->get_all(), verification_key_11->get_all(), labels.get_precomputed())) {
if (vk_10 != vk_11) {
broke = true;
info("Mismatch verification key label: ", label, " left: ", vk_10, " right: ", vk_11);
}
}

EXPECT_TRUE(verification_key_10->circuit_size == verification_key_11->circuit_size);
EXPECT_TRUE(verification_key_10->num_public_inputs == verification_key_11->num_public_inputs);

EXPECT_FALSE(broke);
compare_ultra_blocks_and_verification_keys<OuterFlavor>({ blocks_10, blocks_11 },
{ verification_key_10, verification_key_11 });
}

/**
Expand Down Expand Up @@ -360,7 +327,8 @@ HEAVY_TYPED_TEST(RecursiveVerifierTest, IndependentVKHash)
{
if constexpr (IsAnyOf<TypeParam,
UltraRecursiveFlavor_<UltraCircuitBuilder>,
UltraRollupRecursiveFlavor_<UltraCircuitBuilder>>) {
UltraRollupRecursiveFlavor_<UltraCircuitBuilder>,
MegaZKRecursiveFlavor_<UltraCircuitBuilder>>) {
TestFixture::test_independent_vk_hash();
} else {
GTEST_SKIP() << "Not built for this parameter";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@


#include "barretenberg/common/assert.hpp"
#include "barretenberg/common/log.hpp"
#include <array>
#include <memory>
namespace bb {

template <typename OuterFlavor>
static void compare_ultra_blocks_and_verification_keys(
std::array<typename OuterFlavor::CircuitBuilder::ExecutionTrace, 2> blocks,
std::array<std::shared_ptr<typename OuterFlavor::VerificationKey>, 2> verification_keys)
{

// Retrieves the trace blocks (each consisting of a specific gate) from the recursive verifier circuit

bool broke(false);
auto check_eq = [&broke](auto& p1, auto& p2, size_t block_idx, size_t selector_idx) {
ASSERT(p1.size() == p2.size());
for (size_t idx = 0; idx < p1.size(); idx++) {
if (p1[idx] != p2[idx]) {
info("Mismatch selector ", selector_idx, " in block ", block_idx, ", at ", idx);
broke = true;
iakovenkos marked this conversation as resolved.
Show resolved Hide resolved
break;
}
}
};

size_t block_idx = 0;
for (auto [block_0, block_1] : zip_view(blocks[0].get(), blocks[1].get())) {
ASSERT(block_0.selectors.size() == 13);
ASSERT(block_1.selectors.size() == 13);
size_t selector_idx = 0;
for (auto [p_10, p_11] : zip_view(block_0.selectors, block_1.selectors)) {
check_eq(p_10, p_11, block_idx, selector_idx);
selector_idx++;
}
block_idx++;
}

typename OuterFlavor::CommitmentLabels labels;
for (auto [vk_0, vk_1, label] :
zip_view(verification_keys[0]->get_all(), verification_keys[1]->get_all(), labels.get_precomputed())) {
if (vk_0 != vk_1) {
broke = true;
info("Mismatch verification key label: ", label, " left: ", vk_0, " right: ", vk_1);
}
}

ASSERT(verification_keys[0]->circuit_size == verification_keys[1]->circuit_size);
ASSERT(verification_keys[0]->num_public_inputs == verification_keys[1]->num_public_inputs);
iakovenkos marked this conversation as resolved.
Show resolved Hide resolved
ASSERT(verification_keys[0]->pub_inputs_offset == verification_keys[1]->pub_inputs_offset);

ASSERT(!broke);
}

} // namespace bb
Loading
Loading