-
Notifications
You must be signed in to change notification settings - Fork 184
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: naive structured execution trace #5853
Changes from all commits
e1450b6
5d392aa
518dfaf
19731c3
3518868
de1a886
328d3b9
0c86f48
39d91fa
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 |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
#include "barretenberg/protogalaxy/decider_verifier.hpp" | ||
#include "barretenberg/protogalaxy/protogalaxy_prover.hpp" | ||
#include "barretenberg/protogalaxy/protogalaxy_verifier.hpp" | ||
#include "barretenberg/stdlib_circuit_builders/mock_circuits.hpp" | ||
|
||
#include <gtest/gtest.h> | ||
|
||
|
@@ -43,36 +44,35 @@ template <typename Flavor> class ProtoGalaxyTests : public testing::Test { | |
|
||
static void construct_circuit(Builder& builder) | ||
{ | ||
MockCircuits::add_arithmetic_gates(builder); | ||
if constexpr (IsGoblinFlavor<Flavor>) { | ||
GoblinMockCircuits::construct_simple_circuit(builder); | ||
} else { | ||
FF a = FF::random_element(); | ||
FF b = FF::random_element(); | ||
FF c = FF::random_element(); | ||
FF d = a + b + c; | ||
uint32_t a_idx = builder.add_public_variable(a); | ||
uint32_t b_idx = builder.add_variable(b); | ||
uint32_t c_idx = builder.add_variable(c); | ||
uint32_t d_idx = builder.add_variable(d); | ||
|
||
builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, FF(1), FF(1), FF(1), FF(-1), FF(0) }); | ||
GoblinMockCircuits::add_some_ecc_op_gates(builder); | ||
} | ||
} | ||
|
||
// Construct prover and verifier instance for a provided circuit and add to tuple | ||
static void construct_prover_and_verifier_instance(TupleOfInstances& instances, | ||
Builder& builder, | ||
bool structured = false) | ||
{ | ||
|
||
auto prover_instance = std::make_shared<ProverInstance>(builder, structured); | ||
auto verification_key = std::make_shared<VerificationKey>(prover_instance->proving_key); | ||
auto verifier_instance = std::make_shared<VerifierInstance>(verification_key); | ||
get<0>(instances).emplace_back(prover_instance); | ||
get<1>(instances).emplace_back(verifier_instance); | ||
} | ||
|
||
// constructs num_insts number of prover and verifier instances | ||
static TupleOfInstances construct_instances(size_t num_insts) | ||
static TupleOfInstances construct_instances(size_t num_insts, bool structured = false) | ||
{ | ||
TupleOfInstances instances; | ||
// TODO(https://github.com/AztecProtocol/barretenberg/issues/938): Parallelize this loop | ||
for (size_t idx = 0; idx < num_insts; idx++) { | ||
auto builder = typename Flavor::CircuitBuilder(); | ||
construct_circuit(builder); | ||
|
||
auto prover_instance = std::make_shared<ProverInstance>(builder); | ||
auto verification_key = std::make_shared<VerificationKey>(prover_instance->proving_key); | ||
auto verifier_instance = std::make_shared<VerifierInstance>(verification_key); | ||
get<0>(instances).emplace_back(prover_instance); | ||
get<1>(instances).emplace_back(verifier_instance); | ||
construct_prover_and_verifier_instance(instances, builder, structured); | ||
} | ||
return instances; | ||
} | ||
|
@@ -332,6 +332,73 @@ template <typename Flavor> class ProtoGalaxyTests : public testing::Test { | |
decide_and_verify(prover_accumulator_2, verifier_accumulator_2, true); | ||
} | ||
|
||
/** | ||
* @brief Testing two valid rounds of folding followed by the decider for a structured trace. | ||
* | ||
*/ | ||
static void test_full_protogalaxy_structured_trace() | ||
{ | ||
bool structured = true; | ||
TupleOfInstances instances = construct_instances(2, structured); | ||
|
||
auto [prover_accumulator, verifier_accumulator] = fold_and_verify(get<0>(instances), get<1>(instances)); | ||
check_accumulator_target_sum_manual(prover_accumulator, true); | ||
|
||
TupleOfInstances instances_2 = construct_instances(1, structured); // just one set of prover/verifier instances | ||
|
||
auto [prover_accumulator_2, verifier_accumulator_2] = fold_and_verify( | ||
{ prover_accumulator, get<0>(instances_2)[0] }, { verifier_accumulator, get<1>(instances_2)[0] }); | ||
check_accumulator_target_sum_manual(prover_accumulator_2, true); | ||
info(prover_accumulator_2->proving_key.circuit_size); | ||
decide_and_verify(prover_accumulator_2, verifier_accumulator_2, true); | ||
} | ||
|
||
/** | ||
* @brief Testing two valid rounds of folding followed by the decider for a structured trace. | ||
* @details Here we're interested in folding inhomogeneous circuits, i.e. circuits with different numbers of | ||
* constraints, which should be automatically handled by the structured trace | ||
* | ||
*/ | ||
static void test_full_protogalaxy_structured_trace_inhomogeneous_circuits() | ||
{ | ||
bool structured = true; | ||
|
||
// Construct three circuits to be folded, each with a different number of constraints | ||
Builder builder1; | ||
Builder builder2; | ||
Builder builder3; | ||
construct_circuit(builder1); | ||
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. It would probably be more readable if we just add the number of gates as a parameter to construct_circuit, these for loops are a bit unreadable 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. fair enough. I'll just rework it so it's only adding arithmetic gates which still gets the point across and is a bit more explicit 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. all of the mock circuit stuff could use an overhaul |
||
construct_circuit(builder2); | ||
construct_circuit(builder3); | ||
|
||
// Create inhomogenous circuits by adding a different number of add gates to each | ||
MockCircuits::add_arithmetic_gates(builder1, 10); | ||
MockCircuits::add_arithmetic_gates(builder2, 100); | ||
MockCircuits::add_arithmetic_gates(builder3, 1000); | ||
|
||
// Construct the Prover/Verifier instances for the first two circuits | ||
TupleOfInstances instances; | ||
construct_prover_and_verifier_instance(instances, builder1, structured); | ||
construct_prover_and_verifier_instance(instances, builder2, structured); | ||
|
||
// Fold the first two instances | ||
auto [prover_accumulator, verifier_accumulator] = fold_and_verify(get<0>(instances), get<1>(instances)); | ||
check_accumulator_target_sum_manual(prover_accumulator, true); | ||
|
||
// Construct the Prover/Verifier instance for the third circuit | ||
TupleOfInstances instances_2; | ||
construct_prover_and_verifier_instance(instances_2, builder3, structured); | ||
|
||
// Fold 3rd instance into accumulator | ||
auto [prover_accumulator_2, verifier_accumulator_2] = fold_and_verify( | ||
{ prover_accumulator, get<0>(instances_2)[0] }, { verifier_accumulator, get<1>(instances_2)[0] }); | ||
check_accumulator_target_sum_manual(prover_accumulator_2, true); | ||
info(prover_accumulator_2->proving_key.circuit_size); | ||
|
||
// Decide on final accumulator | ||
decide_and_verify(prover_accumulator_2, verifier_accumulator_2, true); | ||
} | ||
|
||
/** | ||
* @brief Ensure tampering a commitment and then calling the decider causes the decider verification to fail. | ||
* | ||
|
@@ -431,6 +498,15 @@ TYPED_TEST(ProtoGalaxyTests, FullProtogalaxyTest) | |
TestFixture::test_full_protogalaxy(); | ||
} | ||
|
||
TYPED_TEST(ProtoGalaxyTests, FullProtogalaxyStructuredTrace) | ||
{ | ||
TestFixture::test_full_protogalaxy_structured_trace(); | ||
} | ||
TYPED_TEST(ProtoGalaxyTests, FullProtogalaxyStructuredTraceInhomogeneous) | ||
{ | ||
TestFixture::test_full_protogalaxy_structured_trace_inhomogeneous_circuits(); | ||
} | ||
|
||
TYPED_TEST(ProtoGalaxyTests, TamperedCommitment) | ||
{ | ||
TestFixture::test_tampered_commitment(); | ||
|
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.
I think this is a good place to explain why the trace would need to be structured, just a concise sentence should be fine
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.
good idea, done