Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
recursion_constraint_output.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Planned, auditors: [], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
8
9namespace acir_format {
10
11template <typename Builder>
13 bool update_ipa_data)
14{
15 // Update points accumulator
16 if (this->points_accumulator.has_data) {
17 this->points_accumulator.aggregate(other.points_accumulator);
18 } else {
19 this->points_accumulator = other.points_accumulator;
20 }
21
22 if (update_ipa_data) {
23 // Update ipa proofs and claims
24 this->nested_ipa_proofs.push_back(other.ipa_proof);
25 this->nested_ipa_claims.push_back(other.ipa_claim);
26 }
27}
28
29template <typename Builder>
31 bool update_ipa_data)
32{
33 // Update points accumulator
34 if (this->points_accumulator.has_data) {
35 this->points_accumulator.aggregate(other.points_accumulator);
36 } else {
37 this->points_accumulator = other.points_accumulator;
38 }
39
40 if (update_ipa_data) {
41 // Update ipa proofs and claims (if other has no proofs/claims, we are not appending anything)
42 this->nested_ipa_proofs.insert(
43 this->nested_ipa_proofs.end(), other.nested_ipa_proofs.begin(), other.nested_ipa_proofs.end());
44 this->nested_ipa_claims.insert(
45 this->nested_ipa_claims.end(), other.nested_ipa_claims.begin(), other.nested_ipa_claims.end());
46 }
47}
48
49template <>
51 UltraCircuitBuilder>::perform_IPA_accumulation(UltraCircuitBuilder& builder) const
52{
54 nested_ipa_claims.size(), nested_ipa_proofs.size(), "Mismatched number of nested IPA claims and proofs.");
55
57 HonkProof final_ipa_proof;
58
59 if (nested_ipa_claims.size() == 2) {
60 // If we have two claims, accumulate.
61 CommitmentKey<curve::Grumpkin> commitment_key(1 << CONST_ECCVM_LOG_N);
63
64 auto ipa_transcript_1 = std::make_shared<StdlibTranscript>(nested_ipa_proofs[0]);
65 auto ipa_transcript_2 = std::make_shared<StdlibTranscript>(nested_ipa_proofs[1]);
66 auto [ipa_claim, ipa_proof] = IPA<stdlib::grumpkin<UltraCircuitBuilder>>::accumulate(
67 commitment_key, ipa_transcript_1, nested_ipa_claims[0], ipa_transcript_2, nested_ipa_claims[1]);
68
69 final_ipa_claim = ipa_claim;
70 final_ipa_proof = ipa_proof;
71 } else if (nested_ipa_claims.size() == 1) {
72 // If we have one claim, just forward it along.
73 final_ipa_claim = nested_ipa_claims[0];
74 // This conversion looks suspicious but there's no need to make this an output of the circuit since
75 // its a proof that will be checked anyway.
76 final_ipa_proof = nested_ipa_proofs[0].get_value();
77 } else if (nested_ipa_claims.empty()) {
78 // If we don't have any claims, we may need to inject a fake one if we're proving with
79 // UltraRollupHonk, indicated by the manual setting of the honk_recursion metadata to 2.
80 info("Proving with UltraRollupHonk but no IPA claims exist.");
81 auto [stdlib_opening_claim, ipa_proof] =
82 IPA<stdlib::grumpkin<UltraCircuitBuilder>>::create_random_valid_ipa_claim_and_proof(builder);
83
84 final_ipa_claim = stdlib_opening_claim;
85 final_ipa_proof = ipa_proof;
86 } else {
87 // We don't support and shouldn't expect to support circuits with 3+ IPA recursive verifiers.
88 throw_or_abort("Too many nested IPA claims to accumulate");
89 }
90
91 BB_ASSERT_EQ(final_ipa_proof.size(), IPA_PROOF_LENGTH);
92
93 // Return the IPA claim and proof
94 return { final_ipa_claim, final_ipa_proof };
95}
96
97template <>
100{
102
104 nested_ipa_claims.size(), nested_ipa_proofs.size(), "Mismatched number of nested IPA claims and proofs.");
105 BB_ASSERT_EQ(nested_ipa_claims.size(), 2U, "Root rollup must have two nested IPA claims.");
106
107 auto [ipa_claim, ipa_proof] = perform_IPA_accumulation(builder);
108
109 // IPA verification
111 &builder, 1 << CONST_ECCVM_LOG_N, VerifierCommitmentKey<curve::Grumpkin>(1 << CONST_ECCVM_LOG_N));
112
113 auto accumulated_ipa_transcript =
115 IPA<stdlib::grumpkin<UltraCircuitBuilder>>::full_verify_recursive(
116 verifier_commitment_key, ipa_claim, accumulated_ipa_transcript);
117}
118
119template <>
121 [[maybe_unused]] bool is_hn_recursion_constraints,
122 [[maybe_unused]] bool has_ipa_claim)
123{
124 if (has_ipa_claim) {
126
127 // We have multiple IPA claims, we need to accumulate them
128 auto [ipa_claim, ipa_proof] = perform_IPA_accumulation(builder);
129
130 // Set proof
131 builder.ipa_proof = ipa_proof;
132
133 // Propagate pairing points and ipa claim
134 IO inputs;
135 inputs.pairing_inputs =
136 points_accumulator.has_data
137 ? points_accumulator
139 inputs.ipa_claim = ipa_claim;
140 inputs.set_public();
141 } else {
143
144 if (is_root_rollup) {
145 // The root rollup performs full IPA verification
146 perform_full_IPA_verification(builder);
147 } else {
148 // We shouldn't accidentally have IPA proofs.
149 BB_ASSERT_EQ(nested_ipa_proofs.size(), static_cast<size_t>(0), "IPA proofs present when not expected.");
150 }
151
152 // Propagate public inputs
153 if (points_accumulator.has_data) {
154 IO inputs;
155 inputs.pairing_inputs = points_accumulator;
156 inputs.set_public();
157 } else {
158 IO::add_default(builder);
159 }
160 }
161}
162
163template <>
165 [[maybe_unused]] bool is_hn_recursion_constraints,
166 [[maybe_unused]] bool has_ipa_claim)
167{
169
171 nested_ipa_claims.size(), static_cast<size_t>(0), "IPA claims present when not expected in MegaBuilder.");
172
173 // If the recursion constraints from HN, the public inputs have already been set. Otherwise, we need to propagate
174 // the pairing points
175 if (!is_hn_recursion_constraints) {
176 if (points_accumulator.has_data) {
177 IO inputs;
178 inputs.pairing_inputs = points_accumulator;
179 inputs.set_public();
180 } else {
181 IO::add_default(builder);
182 }
183 }
184}
185
188
191
194
197
198} // namespace acir_format
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:93
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
CommitmentKey object over a pairing group 𝔾₁.
IPA (inner product argument) commitment scheme class.
Definition ipa.hpp:93
Unverified claim (C,r,v) for some witness polynomial p(X) such that.
Definition claim.hpp:53
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
A simple wrapper around a vector of stdlib field elements representing a proof.
Definition proof.hpp:19
Manages the data that is propagated on the public inputs of an application/function circuit.
The data that is propagated on the public inputs of a rollup circuit.
void info(Args... args)
Definition log.hpp:89
AluTraceBuilder builder
Definition alu.test.cpp:124
AvmProvingInputs inputs
DefaultIO< MegaCircuitBuilder > AppIO
The data that is propagated on the public inputs of an application/function circuit.
std::vector< fr > HonkProof
Definition proof.hpp:15
BaseTranscript< stdlib::StdlibCodec< stdlib::field_t< UltraCircuitBuilder > >, stdlib::poseidon2< UltraCircuitBuilder > > UltraStdlibTranscript
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Container for the output of multiple recursive verifications.
void finalize(Builder &builder, bool is_hn_recursion_constraints=false, bool has_ipa_claim=false)
Finalize the output by accumulating IPA claims/proofs, performing full IPA verification,...
std::vector< stdlib::Proof< Builder > > nested_ipa_proofs
void perform_full_IPA_verification(Builder &builder) const
Perform full IPA recursive verification of the IPA claims and proofs contained in this output.
stdlib::recursion::PairingPoints< stdlib::bn254< Builder > > points_accumulator
std::vector< OpeningClaim< stdlib::grumpkin< Builder > > > nested_ipa_claims
void update(const HonkRecursionConstraintOutput< Builder > &other, bool update_ipa_data)
Update the current output with another recursion constraint output.
An object storing two EC points that represent the inputs to a pairing check.
Output type for recursive ultra verification.
void throw_or_abort(std::string const &err)