20 std::vector<size_t>& gates_per_opcode,
27 bool has_honk_recursion_constraints = !honk_recursion_data.first.empty();
28 bool has_avm_recursion_constraints = !avm_recursion_data.first.empty();
29 bool has_hn_recursion_constraints = !hn_recursion_data.first.empty();
30 bool has_chonk_recursion_constraints = !chonk_recursion_data.first.empty();
33 BB_ASSERT(!(has_honk_recursion_constraints && has_hn_recursion_constraints),
34 "create_recursion_constraints: invalid circuit - both honk and HN recursion constraints present");
36 !has_avm_recursion_constraints,
37 "create_recursion_constraints: invalid circuit - AVM recursion constraints not supported with MegaBuilder");
38 BB_ASSERT(!has_chonk_recursion_constraints,
39 "create_recursion_constraints: invalid circuit - Chonk recursion constraints not supported with "
44 for (
const auto& [constraint, opcode_idx] :
zip_view(honk_recursion_data.first, honk_recursion_data.second)) {
47 if (constraint.proof_type ==
HONK_ZK) {
48 honk_recursion_constraint =
49 create_honk_recursion_constraints<UltraZKRecursiveFlavor_<MegaCircuitBuilder>,
52 }
else if (constraint.proof_type ==
HONK) {
53 honk_recursion_constraint =
54 create_honk_recursion_constraints<UltraRecursiveFlavor_<MegaCircuitBuilder>,
63 output.
update(honk_recursion_constraint,
false);
64 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
67 if (has_hn_recursion_constraints) {
78 std::vector<size_t>& gates_per_opcode,
85 bool has_honk_recursion_constraints = !honk_recursion_data.first.empty();
86 bool has_avm_recursion_constraints = !avm_recursion_data.first.empty();
87 bool has_hn_recursion_constraints = !hn_recursion_data.first.empty();
88 bool has_chonk_recursion_constraints = !chonk_recursion_data.first.empty();
92 !has_hn_recursion_constraints,
93 "create_recursion_constraints: invalid circuit - HN recursion constraints not supported with UltraBuilder");
94 BB_ASSERT(!(has_chonk_recursion_constraints && has_honk_recursion_constraints),
95 "create_recursion_constraints: invalid circuit - both honk and chonk recursion constraints present");
96 if (has_chonk_recursion_constraints && has_avm_recursion_constraints) {
97 vinfo(
"WARNING: both chonk and avm recursion constraints are present. While we support this combination, we "
98 "expect to see it only in a mock circuit.");
103 for (
const auto& [constraint, opcode_idx] :
zip_view(honk_recursion_data.first, honk_recursion_data.second)) {
106 if (constraint.proof_type ==
HONK_ZK) {
107 honk_recursion_constraint =
108 create_honk_recursion_constraints<UltraZKRecursiveFlavor_<UltraCircuitBuilder>,
111 }
else if (constraint.proof_type ==
HONK) {
112 honk_recursion_constraint =
113 create_honk_recursion_constraints<UltraRecursiveFlavor_<UltraCircuitBuilder>,
118 honk_recursion_constraint =
119 create_honk_recursion_constraints<UltraRecursiveFlavor_<UltraCircuitBuilder>,
126 output.
update(honk_recursion_constraint,
131 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
134 "Root rollup must accumulate two IPA proofs.");
136 for (
const auto& [constraint, opcode_idx] :
zip_view(chonk_recursion_data.first, chonk_recursion_data.second)) {
141 output.
update(honk_output,
true);
143 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
146 for (
const auto& [constraint, opcode_idx] :
zip_view(avm_recursion_data.first, avm_recursion_data.second)) {
151 output.
update(honk_output,
true);
153 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
162 std::vector<size_t>& gates_per_opcode,
172 hn_recursion_data.second.size(),
173 "process_hn_recursion_constraints: hn_recursion_data constraints/indices size mismatch");
179 ivc->verification_queue.size(),
180 "process_hn_recursion_constraints: mismatch in number of recursive verifications during kernel "
185 if (
builder.is_write_vk_mode()) {
187 for (
auto [constraint, queue_entry] :
zip_view(hn_recursion_data.first, ivc->verification_queue)) {
190 builder.set_variable(constraint.key_hash, queue_entry.honk_vk->hash());
197 stdlib_vk_and_hashs.reserve(hn_recursion_data.first.size());
198 for (
const auto& constraint : hn_recursion_data.first) {
201 StdlibVerificationKey::from_witness_indices(
builder, constraint.key)),
202 StdlibFF::from_witness_index(&
builder, constraint.key_hash)));
205 ivc->instantiate_stdlib_verification_queue(
builder, stdlib_vk_and_hashs);
209 hn_recursion_data.first.size(),
210 "process_hn_recursion_constraints: stdlib_verification_queue size mismatch after instantiation");
213 for (
auto [constraint, queue_entry] :
zip_view(hn_recursion_data.first, ivc->stdlib_verification_queue)) {
216 "process_hn_recursion_constraints: ACIR constraint proof_type does not match IVC queue type");
221 BB_ASSERT(constraint.public_inputs.empty(),
222 "process_hn_recursion_constraints: unexpected non-empty public_inputs in HN constraint - "
223 "Noir HN constraints should have empty public_inputs (public inputs are handled by IVC IO)");
226 size_t expected_io_size =
227 queue_entry.is_kernel ? IVCType::KernelIO::PUBLIC_INPUTS_SIZE : IVCType::AppIO::PUBLIC_INPUTS_SIZE;
228 size_t vk_num_public_inputs =
229 static_cast<size_t>(uint64_t(queue_entry.honk_vk_and_hash->vk->num_public_inputs.get_value()));
231 vk_num_public_inputs,
232 "process_hn_recursion_constraints: IO size mismatch with VK num_public_inputs");
237 vk_num_public_inputs,
238 "process_hn_recursion_constraints: proof vector smaller than num_public_inputs - malformed "
243 ivc->complete_kernel_circuit_logic(
builder);
247 gate_counter.
track_diff(gates_per_opcode, hn_recursion_data.second.at(0));
252 if (ivc_base ==
nullptr) {
254 process_with_ivc(mock_ivc);
258 throw_or_abort(
"process_hn_recursion_constraints: ivc_base is not a Chonk instance");
260 process_with_ivc(chonk);
#define BB_ASSERT(expression,...)
#define BB_ASSERT_GTE(left, right,...)
#define BB_ASSERT_EQ(actual, expected,...)
RecursiveFlavor::VerificationKey RecursiveVerificationKey
RecursiveFlavor::VKAndHash RecursiveVKAndHash
typename Curve::ScalarField FF
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 assert_failure(std::string const &err)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Output type for recursive ultra verification.
void throw_or_abort(std::string const &err)