-
Notifications
You must be signed in to change notification settings - Fork 234
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: handle consecutive kernels in IVC #8924
Changes from all commits
6f94376
f05da38
94ea7cd
ee0652b
0f313c1
bb65732
c53a2a6
81609eb
1c9b7b1
77b4c5f
4c7ee0b
b8244f2
58462e4
f98a43f
39efe09
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 |
---|---|---|
|
@@ -38,7 +38,7 @@ class ClientIVCAutoVerifyTests : public ::testing::Test { | |
* polynomials will bump size to next power of 2) | ||
* | ||
*/ | ||
static Builder create_mock_circuit(ClientIVC& ivc, size_t log2_num_gates = 16) | ||
static Builder create_mock_circuit(ClientIVC& ivc, bool is_kernel, size_t log2_num_gates = 16) | ||
{ | ||
Builder circuit{ ivc.goblin.op_queue }; | ||
MockCircuits::construct_arithmetic_circuit(circuit, log2_num_gates); | ||
|
@@ -49,6 +49,8 @@ class ClientIVCAutoVerifyTests : public ::testing::Test { | |
// circuits (where we don't explicitly need to add goblin ops), in ClientIVC merge proving happens prior to | ||
// folding where the absense of goblin ecc ops will result in zero commitments. | ||
MockCircuits::construct_goblin_ecc_op_circuit(circuit); | ||
|
||
circuit.databus_propagation_data.is_kernel = is_kernel; | ||
return circuit; | ||
} | ||
}; | ||
|
@@ -62,17 +64,37 @@ TEST_F(ClientIVCAutoVerifyTests, Basic) | |
ClientIVC ivc; | ||
ivc.auto_verify_mode = true; | ||
|
||
{ | ||
// Initialize the IVC with an arbitrary circuit | ||
Builder circuit_0 = create_mock_circuit(ivc); | ||
ivc.accumulate(circuit_0); | ||
} | ||
// Initialize the IVC with an arbitrary circuit | ||
Builder circuit_0 = create_mock_circuit(ivc, /*is_kernel=*/false); | ||
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. Couldn't you have 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. I could but the method already has a 3rd argument with a default value and I try to avoid having methods with multiple default arguments when possible. This whole test suite will be deleted soon enough anyway |
||
ivc.accumulate(circuit_0); | ||
|
||
{ | ||
// Create another circuit and accumulate | ||
Builder circuit_1 = create_mock_circuit(ivc); | ||
ivc.accumulate(circuit_1); | ||
} | ||
// Create another circuit and accumulate | ||
Builder circuit_1 = create_mock_circuit(ivc, /*is_kernel=*/true); | ||
ivc.accumulate(circuit_1); | ||
|
||
EXPECT_TRUE(ivc.prove_and_verify()); | ||
}; | ||
|
||
/** | ||
* @brief The number of circuits processed can be odd as long as the last one is a kernel | ||
* | ||
*/ | ||
TEST_F(ClientIVCAutoVerifyTests, BasicOdd) | ||
{ | ||
ClientIVC ivc; | ||
ivc.auto_verify_mode = true; | ||
|
||
// Initialize the IVC with an arbitrary circuit | ||
Builder circuit_0 = create_mock_circuit(ivc, /*is_kernel=*/false); | ||
ivc.accumulate(circuit_0); | ||
|
||
// Create another circuit and accumulate | ||
Builder circuit_1 = create_mock_circuit(ivc, /*is_kernel=*/true); | ||
ivc.accumulate(circuit_1); | ||
|
||
// Create another circuit and accumulate | ||
Builder circuit_2 = create_mock_circuit(ivc, /*is_kernel=*/true); | ||
ivc.accumulate(circuit_2); | ||
|
||
EXPECT_TRUE(ivc.prove_and_verify()); | ||
}; | ||
|
@@ -90,7 +112,8 @@ TEST_F(ClientIVCAutoVerifyTests, BasicLarge) | |
size_t NUM_CIRCUITS = 6; | ||
std::vector<Builder> circuits; | ||
for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) { | ||
circuits.emplace_back(create_mock_circuit(ivc)); | ||
bool is_kernel = (idx % 2 == 1); // every second circuit is a kernel | ||
circuits.emplace_back(create_mock_circuit(ivc, is_kernel)); | ||
} | ||
|
||
// Accumulate each circuit | ||
|
@@ -112,10 +135,10 @@ TEST_F(ClientIVCAutoVerifyTests, BasicStructured) | |
ivc.trace_structure = TraceStructure::SMALL_TEST; | ||
|
||
// Construct some circuits of varying size | ||
Builder circuit_0 = create_mock_circuit(ivc, /*log2_num_gates=*/5); | ||
Builder circuit_1 = create_mock_circuit(ivc, /*log2_num_gates=*/8); | ||
Builder circuit_2 = create_mock_circuit(ivc, /*log2_num_gates=*/11); | ||
Builder circuit_3 = create_mock_circuit(ivc, /*log2_num_gates=*/11); | ||
Builder circuit_0 = create_mock_circuit(ivc, /*is_kernel=*/false, /*log2_num_gates=*/5); | ||
Builder circuit_1 = create_mock_circuit(ivc, /*is_kernel=*/true, /*log2_num_gates=*/8); | ||
Builder circuit_2 = create_mock_circuit(ivc, /*is_kernel=*/false, /*log2_num_gates=*/11); | ||
Builder circuit_3 = create_mock_circuit(ivc, /*is_kernel=*/true, /*log2_num_gates=*/11); | ||
|
||
// The circuits can be accumulated as normal due to the structured trace | ||
ivc.accumulate(circuit_0); | ||
|
@@ -139,7 +162,8 @@ TEST_F(ClientIVCAutoVerifyTests, PrecomputedVerificationKeys) | |
size_t NUM_CIRCUITS = 4; | ||
std::vector<Builder> circuits; | ||
for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) { | ||
circuits.emplace_back(create_mock_circuit(ivc)); | ||
bool is_kernel = (idx % 2 == 1); // every second circuit is a kernel | ||
circuits.emplace_back(create_mock_circuit(ivc, is_kernel)); | ||
} | ||
|
||
// Precompute the verification keys that will be needed for the IVC | ||
|
@@ -167,7 +191,8 @@ TEST_F(ClientIVCAutoVerifyTests, StructuredPrecomputedVKs) | |
size_t NUM_CIRCUITS = 4; | ||
std::vector<Builder> circuits; | ||
for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) { | ||
circuits.emplace_back(create_mock_circuit(ivc, /*log2_num_gates=*/5)); | ||
bool is_kernel = (idx % 2 == 1); // every second circuit is a kernel | ||
circuits.emplace_back(create_mock_circuit(ivc, is_kernel, /*log2_num_gates=*/5)); | ||
} | ||
|
||
// Precompute the (structured) verification keys that will be needed for the IVC | ||
|
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.
This is the main point of this PR. IVC will non longer internally assume that every other circuit is a kernel. Instead it will check
circuit.databus_propagation_data.is_kernel
. This tag will be set to true automatically in ACIR land when the corresponding noir program uses calldata (since only kernels use calldata). Everywhere else (e.g. random test suites), the tag must be set manually for now.