Skip to content

Commit df73c05

Browse files
authored
feat: Refactor IPA claim handling in acir format to support them for AVM (#13547)
Refactor where we handle IPA claim handling to be at the acir_format level instead in within `process_honk_recursion_constraints`. This is needed to handle circuits like the public base which will have AVM recursion constraints and RollupHonk recursion constraints, which will now BOTH produce IPA claims/proofs. Fix Goblin AVM recursive verifier test and clean some small type-related things.
1 parent 1dc92ef commit df73c05

14 files changed

+159
-160
lines changed

barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_ultra_recursive_verifier.test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ template <typename RecursiveFlavor> class BoomerangRecursiveVerifierTest : publi
4646
using VerificationKey = typename RecursiveVerifier::VerificationKey;
4747

4848
using AggState = aggregation_state<OuterBuilder>;
49-
using VerifierOutput = bb::stdlib::recursion::honk::UltraRecursiveVerifierOutput<RecursiveFlavor>;
49+
using VerifierOutput = bb::stdlib::recursion::honk::UltraRecursiveVerifierOutput<OuterBuilder>;
5050

5151
/**
5252
* @brief Create a non-trivial arbitrary inner circuit, the proof of which will be recursively verified
@@ -125,7 +125,7 @@ template <typename RecursiveFlavor> class BoomerangRecursiveVerifierTest : publi
125125
pairing_points.P1.x.fix_witness();
126126
pairing_points.P1.y.fix_witness();
127127
if constexpr (HasIPAAccumulator<OuterFlavor>) {
128-
output.ipa_opening_claim.set_public();
128+
output.ipa_claim.set_public();
129129
outer_circuit.ipa_proof = convert_stdlib_proof_to_native(output.ipa_proof);
130130
}
131131
info("Recursive Verifier: num gates = ", outer_circuit.get_estimated_num_finalized_gates());

barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp

Lines changed: 127 additions & 85 deletions
Large diffs are not rendered by default.

barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -270,29 +270,4 @@ template <typename Builder> class GateCounter {
270270
size_t prev_gate_count{};
271271
};
272272

273-
void process_plonk_recursion_constraints(Builder& builder,
274-
AcirFormat& constraint_system,
275-
bool has_valid_witness_assignments,
276-
GateCounter<Builder>& gate_counter);
277-
void process_honk_recursion_constraints(Builder& builder,
278-
AcirFormat& constraint_system,
279-
bool has_valid_witness_assignments,
280-
GateCounter<Builder>& gate_counter,
281-
uint32_t honk_recursion);
282-
283-
void process_ivc_recursion_constraints(MegaCircuitBuilder& builder,
284-
AcirFormat& constraints,
285-
ClientIVC* ivc,
286-
bool has_valid_witness_assignments,
287-
GateCounter<MegaCircuitBuilder>& gate_counter);
288-
289-
#ifndef DISABLE_AZTEC_VM
290-
stdlib::recursion::aggregation_state<Builder> process_avm_recursion_constraints(
291-
Builder& builder,
292-
AcirFormat& constraint_system,
293-
bool has_valid_witness_assignments,
294-
GateCounter<Builder>& gate_counter,
295-
stdlib::recursion::aggregation_state<Builder> current_aggregation_object);
296-
#endif
297-
298273
} // namespace acir_format

barretenberg/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,12 +224,10 @@ HonkRecursionConstraintOutput<Builder> create_avm2_recursion_constraints_goblin(
224224
// Execute the Goblin AVM2 recursive verifier
225225
RecursiveVerifier verifier(builder, key_fields);
226226

227-
auto output_agg_object = verifier.verify_proof(
227+
bb::avm2::AvmGoblinRecursiveVerifier::RecursiveAvmGoblinOutput output = verifier.verify_proof(
228228
proof_fields, bb::avm2::PublicInputs::flat_to_columns(public_inputs_flattened), input_aggregation_object);
229229

230-
return { .agg_obj = output_agg_object.aggregation_object,
231-
.ipa_claim = output_agg_object.ipa_claim,
232-
.ipa_proof = output_agg_object.ipa_proof };
230+
return output;
233231
}
234232

235233
} // namespace acir_format

barretenberg/cpp/src/barretenberg/dsl/acir_format/avm2_recursion_constraint.test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ TEST_F(AcirAvm2RecursionConstraint, TestGenerateVKFromConstraintsWithoutWitness)
159159
std::shared_ptr<OuterVerificationKey> expected_vk;
160160
{
161161
AcirProgram avm_verifier_program = construct_avm_verifier_program({ avm_prover_output });
162-
const ProgramMetadata metadata{ .honk_recursion = 1 };
162+
const ProgramMetadata metadata{ .honk_recursion = 2 };
163163
auto layer_2_circuit = create_circuit(avm_verifier_program, metadata);
164164

165165
info("circuit gates = ", layer_2_circuit.get_estimated_num_finalized_gates());
@@ -182,7 +182,7 @@ TEST_F(AcirAvm2RecursionConstraint, TestGenerateVKFromConstraintsWithoutWitness)
182182

183183
// Clear the program witness then construct the bberg circuit as normal
184184
avm_verifier_program.witness.clear();
185-
const ProgramMetadata metadata{ .honk_recursion = 1 };
185+
const ProgramMetadata metadata{ .honk_recursion = 2 };
186186
auto layer_2_circuit = create_circuit(avm_verifier_program, metadata);
187187

188188
info("circuit gates = ", layer_2_circuit.get_estimated_num_finalized_gates());

barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,14 @@ HonkRecursionConstraintOutput<typename Flavor::CircuitBuilder> create_honk_recur
264264
auto vkey = std::make_shared<RecursiveVerificationKey>(builder, key_fields);
265265
RecursiveVerifier verifier(&builder, vkey);
266266
HonkRecursionConstraintOutput<Builder> output;
267-
UltraRecursiveVerifierOutput<Flavor> verifier_output = verifier.verify_proof(proof_fields, input_agg_obj);
267+
UltraRecursiveVerifierOutput<Builder> verifier_output = verifier.verify_proof(proof_fields, input_agg_obj);
268268
// TODO(https://github.com/AztecProtocol/barretenberg/issues/996): investigate whether assert_equal on public inputs
269269
// is important, like what the plonk recursion constraint does.
270270

271271
output.agg_obj = verifier_output.agg_obj;
272272
if constexpr (HasIPAAccumulator<Flavor>) {
273273
ASSERT(HasIPAAccumulator<Flavor>);
274-
output.ipa_claim = verifier_output.ipa_opening_claim;
274+
output.ipa_claim = verifier_output.ipa_claim;
275275
output.ipa_proof = verifier_output.ipa_proof;
276276
}
277277
return output;

barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.hpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "barretenberg/commitment_schemes/claim.hpp"
33
#include "barretenberg/dsl/acir_format/recursion_constraint.hpp"
44
#include "barretenberg/honk/proof_system/types/proof.hpp"
5+
#include "barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.hpp"
56
#include "barretenberg/stdlib/plonk_recursion/aggregation_state/aggregation_state.hpp"
67
#include "barretenberg/stdlib/primitives/bigfield/bigfield.hpp"
78
#include "barretenberg/stdlib/primitives/curves/grumpkin.hpp"
@@ -11,11 +12,8 @@ namespace acir_format {
1112

1213
using namespace bb;
1314

14-
template <typename Builder> struct HonkRecursionConstraintOutput {
15-
stdlib::recursion::aggregation_state<Builder> agg_obj;
16-
OpeningClaim<stdlib::grumpkin<Builder>> ipa_claim;
17-
StdlibProof<Builder> ipa_proof;
18-
};
15+
template <typename Builder>
16+
using HonkRecursionConstraintOutput = bb::stdlib::recursion::honk::UltraRecursiveVerifierOutput<Builder>;
1917

2018
template <typename Flavor>
2119
HonkRecursionConstraintOutput<typename Flavor::CircuitBuilder> create_honk_recursion_constraints(

barretenberg/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class IvcRecursionConstraintTest : public ::testing::Test {
8181

8282
{
8383
using RecursiveFlavor = UltraRecursiveFlavor_<Builder>;
84-
using VerifierOutput = bb::stdlib::recursion::honk::UltraRecursiveVerifierOutput<RecursiveFlavor>;
84+
using VerifierOutput = bb::stdlib::recursion::honk::UltraRecursiveVerifierOutput<Builder>;
8585
using OuterAggState = bb::stdlib::recursion::aggregation_state<Builder>;
8686

8787
// Create an arbitrary inner circuit

barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.test.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@ TEST_F(ClientIVCRecursionTests, ClientTubeBase)
136136
auto base_vk = std::make_shared<RollupFlavor::VerificationKey>(&base_builder, tube_vk);
137137
auto base_tube_proof = bb::convert_native_proof_to_stdlib(&base_builder, native_tube_proof);
138138
UltraRecursiveVerifier base_verifier{ &base_builder, base_vk };
139-
UltraRecursiveVerifierOutput<RollupFlavor> output =
139+
UltraRecursiveVerifierOutput<Builder> output =
140140
base_verifier.verify_proof(base_tube_proof, AggregationObject::construct_default(base_builder));
141141
info("Tube UH Recursive Verifier: num prefinalized gates = ", base_builder.num_gates);
142142
output.agg_obj.set_public();
143-
output.ipa_opening_claim.set_public();
143+
output.ipa_claim.set_public();
144144
base_builder.ipa_proof = tube_prover.proving_key->proving_key.ipa_proof;
145145
EXPECT_EQ(base_builder.failed(), false) << base_builder.err();
146146
EXPECT_TRUE(CircuitChecker::check(base_builder));
@@ -149,7 +149,7 @@ TEST_F(ClientIVCRecursionTests, ClientTubeBase)
149149
auto base_proving_key = std::make_shared<DeciderProvingKey_<NativeFlavor>>(base_builder);
150150
auto ipa_transcript = std::make_shared<NativeTranscript>(base_proving_key->proving_key.ipa_proof);
151151
IPA<curve::Grumpkin>::reduce_verify(
152-
ipa_verification_key, output.ipa_opening_claim.get_native_opening_claim(), ipa_transcript);
152+
ipa_verification_key, output.ipa_claim.get_native_opening_claim(), ipa_transcript);
153153
}
154154

155155
// Ensure that the Client IVC Recursive Verifier Circuit does not depend on the Client IVC input

barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ UltraRecursiveVerifier_<Flavor>::Output UltraRecursiveVerifier_<Flavor>::verify_
142142
if (verification_key->verification_key->contains_ipa_claim) {
143143
PublicComponentKey ipa_claim_key{ verification_key->verification_key->ipa_claim_public_input_indices[0],
144144
true };
145-
output.ipa_opening_claim = PublicIpaClaim::reconstruct(verification_key->public_inputs, ipa_claim_key);
145+
output.ipa_claim = PublicIpaClaim::reconstruct(verification_key->public_inputs, ipa_claim_key);
146146
}
147147
}
148148

barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.hpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@
1111

1212
namespace bb::stdlib::recursion::honk {
1313

14-
template <typename Flavor> struct UltraRecursiveVerifierOutput {
15-
using Builder = typename Flavor::CircuitBuilder;
14+
template <typename Builder> struct UltraRecursiveVerifierOutput {
1615
aggregation_state<Builder> agg_obj;
17-
OpeningClaim<grumpkin<Builder>> ipa_opening_claim;
16+
OpeningClaim<grumpkin<Builder>> ipa_claim;
1817
StdlibProof<Builder> ipa_proof;
1918
};
2019
template <typename Flavor> class UltraRecursiveVerifier_ {
@@ -31,7 +30,7 @@ template <typename Flavor> class UltraRecursiveVerifier_ {
3130
using AggregationObject = aggregation_state<Builder>;
3231
using Transcript = bb::BaseTranscript<bb::stdlib::recursion::honk::StdlibTranscriptParams<Builder>>;
3332
using OinkVerifier = OinkRecursiveVerifier_<Flavor>;
34-
using Output = UltraRecursiveVerifierOutput<Flavor>;
33+
using Output = UltraRecursiveVerifierOutput<Builder>;
3534

3635
explicit UltraRecursiveVerifier_(Builder* builder,
3736
const std::shared_ptr<NativeVerificationKey>& native_verifier_key);

barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ template <typename RecursiveFlavor> class RecursiveVerifierTest : public testing
4444
using VerificationKey = typename RecursiveVerifier::VerificationKey;
4545

4646
using AggState = aggregation_state<OuterBuilder>;
47-
using VerifierOutput = bb::stdlib::recursion::honk::UltraRecursiveVerifierOutput<RecursiveFlavor>;
47+
using VerifierOutput = bb::stdlib::recursion::honk::UltraRecursiveVerifierOutput<OuterBuilder>;
4848
/**
4949
* @brief Create a non-trivial arbitrary inner circuit, the proof of which will be recursively verified
5050
*
@@ -163,7 +163,7 @@ template <typename RecursiveFlavor> class RecursiveVerifierTest : public testing
163163
typename RecursiveVerifier::Output verifier_output =
164164
verifier.verify_proof(inner_proof, AggState::construct_default(outer_circuit));
165165
if constexpr (HasIPAAccumulator<OuterFlavor>) {
166-
verifier_output.ipa_opening_claim.set_public();
166+
verifier_output.ipa_claim.set_public();
167167
outer_circuit.ipa_proof = convert_stdlib_proof_to_native(verifier_output.ipa_proof);
168168
}
169169

@@ -204,7 +204,7 @@ template <typename RecursiveFlavor> class RecursiveVerifierTest : public testing
204204
VerifierOutput output = verifier.verify_proof(inner_proof, agg_obj);
205205
AggState pairing_points = output.agg_obj;
206206
if constexpr (HasIPAAccumulator<OuterFlavor>) {
207-
output.ipa_opening_claim.set_public();
207+
output.ipa_claim.set_public();
208208
outer_circuit.ipa_proof = convert_stdlib_proof_to_native(output.ipa_proof);
209209
}
210210
info("Recursive Verifier: num gates = ", outer_circuit.get_estimated_num_finalized_gates());

barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,7 @@ class AvmGoblinRecursiveVerifier {
5252

5353
// The structure of the final output of the goblinized AVM2 recursive verifier. The IPA data comes from recursive
5454
// verification of the ECCVM proof as part of Goblin recursive verification.
55-
struct RecursiveAvmGoblinOutput {
56-
std::vector<UltraFF> ipa_proof;
57-
OpeningClaim<stdlib::grumpkin<UltraBuilder>> ipa_claim;
58-
stdlib::recursion::aggregation_state<UltraBuilder> aggregation_object;
59-
};
55+
using RecursiveAvmGoblinOutput = stdlib::recursion::honk::UltraRecursiveVerifierOutput<UltraBuilder>;
6056

6157
// Output of prover for inner Mega-arithmetized AVM recursive verifier circuit; input to the outer verifier
6258
struct InnerProverOutput {
@@ -145,26 +141,17 @@ class AvmGoblinRecursiveVerifier {
145141
GoblinRecursiveVerifier goblin_verifier{ &ultra_builder, inner_output.goblin_vk };
146142
GoblinRecursiveVerifierOutput goblin_verifier_output = goblin_verifier.verify(inner_output.goblin_proof);
147143

148-
// Propagate the IPA claim via the public inputs of the outer circuit
149-
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1306): Determine the right location/entity to
150-
// handle this IPA data propagation.
151-
152-
// TODO(jeamon): Restore ipa_claim and ipa_proof integration in the builder. While running ./bootstrap.sh,
153-
// for the mock-protocol-circuits, we hit an assertion at circuit_builder_base_impl.hpp:262 ("added IPA claim
154-
// when one already exists")
155-
// ultra_builder.add_ipa_claim(goblin_verifier_output.opening_claim.get_witness_indices());
156-
// ultra_builder.ipa_proof = convert_stdlib_proof_to_native(goblin_verifier_output.ipa_transcript->proof_data);
157-
// ASSERT(ultra_builder.ipa_proof.size() && "IPA proof should not be empty");
158-
159144
// Validate the consistency of the AVM2 verifier inputs {\pi, pub_inputs, VK}_{AVM2} between the inner (Mega)
160145
// circuit and the outer (Ultra) by asserting equality on the independently computed hashes of this data.
161146
const FF ultra_hash = stdlib::poseidon2<UltraBuilder>::hash(ultra_builder, hash_buffer);
162147
mega_proof[inner_output.mega_hash_public_input_index].assert_equal(ultra_hash);
163148

164149
// Return ipa proof, ipa claim and output aggregation object produced from verifying the Mega + Goblin proofs
165-
return RecursiveAvmGoblinOutput{ .ipa_proof = goblin_verifier_output.ipa_transcript->proof_data,
166-
.ipa_claim = goblin_verifier_output.opening_claim,
167-
.aggregation_object = mega_verifier_output.agg_obj };
150+
return RecursiveAvmGoblinOutput{
151+
.agg_obj = mega_verifier_output.agg_obj,
152+
.ipa_claim = goblin_verifier_output.opening_claim,
153+
.ipa_proof = goblin_verifier_output.ipa_transcript->proof_data,
154+
};
168155
}
169156

170157
/**

barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/recursive_verifier.test.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,6 @@ TEST_F(AvmRecursiveTests, StandardRecursion)
159159
*/
160160
TEST_F(AvmRecursiveTests, GoblinRecursion)
161161
{
162-
GTEST_SKIP(); // TODO: Fix this test. At the moment, we hit an assertion in the UltraProver.
163-
// Assertion `(proving_key->proving_key.ipa_proof.size() == IPA_PROOF_LENGTH)' failed.
164-
165162
// Type aliases specific to GoblinRecursion test
166163
using AvmRecursiveVerifier = AvmGoblinRecursiveVerifier;
167164
using UltraRollupRecursiveFlavor = UltraRollupRecursiveFlavor_<UltraRollupFlavor::CircuitBuilder>;
@@ -204,9 +201,12 @@ TEST_F(AvmRecursiveTests, GoblinRecursion)
204201
return avm_rec_verifier.verify_proof(stdlib_proof, public_inputs_ct, agg_object);
205202
}();
206203

204+
verifier_output.ipa_claim.set_public();
205+
outer_circuit.ipa_proof = convert_stdlib_proof_to_native(verifier_output.ipa_proof);
206+
207207
// Ensure that the pairing check is satisfied on the outputs of the recursive verifier
208208
bool agg_output_valid = verification_key->pcs_verification_key->pairing_check(
209-
verifier_output.aggregation_object.P0.get_value(), verifier_output.aggregation_object.P1.get_value());
209+
verifier_output.agg_obj.P0.get_value(), verifier_output.agg_obj.P1.get_value());
210210
ASSERT_TRUE(agg_output_valid) << "Pairing points (aggregation state) are not valid.";
211211
ASSERT_FALSE(outer_circuit.failed()) << "Outer circuit has failed.";
212212

0 commit comments

Comments
 (0)