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);
135 "Root rollup must accumulate two IPA proofs.");
137 for (
const auto& [constraint, opcode_idx] :
zip_view(chonk_recursion_data.first, chonk_recursion_data.second)) {
142 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
145 for (
const auto& [constraint, opcode_idx] :
zip_view(avm_recursion_data.first, avm_recursion_data.second)) {
150 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
159 std::vector<size_t>& gates_per_opcode,
171 hn_recursion_data.second.size(),
172 "process_hn_recursion_constraints: hn_recursion_data constraints/indices size mismatch");
178 ivc->verification_queue.size(),
179 "process_hn_recursion_constraints: mismatch in number of recursive verifications during kernel "
184 if (
builder.is_write_vk_mode()) {
185 for (
auto [constraint, queue_entry] :
zip_view(hn_recursion_data.first, ivc->verification_queue)) {
188 builder.set_variable(constraint.key_hash, queue_entry.vk_hash());
193 stdlib_vk_and_hashs.reserve(hn_recursion_data.first.size());
194 for (
auto [constraint, queue_entry] :
zip_view(hn_recursion_data.first, ivc->verification_queue)) {
195 auto hash = StdlibFF::from_witness_index(&
builder, constraint.key_hash);
196 if (queue_entry.is_kernel()) {
206 ivc->instantiate_stdlib_verification_queue(
builder, stdlib_vk_and_hashs);
210 hn_recursion_data.first.size(),
211 "process_hn_recursion_constraints: stdlib_verification_queue size mismatch after instantiation");
214 size_t group_index = 0;
215 for (
auto [constraint, queue_entry] :
zip_view(hn_recursion_data.first, ivc->stdlib_verification_queue)) {
220 static_cast<PROOF_TYPE>(constraint.proof_type),
222 "process_hn_recursion_constraints: ACIR proof_type disagrees with circuit-kinds-derived state");
226 "process_hn_recursion_constraints: queue entry kind disagrees with circuit-kinds-derived position");
231 BB_ASSERT(constraint.public_inputs.empty(),
232 "process_hn_recursion_constraints: unexpected non-empty public_inputs in HN constraint - "
233 "Noir HN constraints should have empty public_inputs (public inputs are handled by IVC IO)");
237 queue_entry.kind, [&]<
bb::CircuitKind K>() ->
size_t { return bb::io_for<K>::PUBLIC_INPUTS_SIZE; });
238 const size_t vk_num_public_inputs = queue_entry.vk_num_public_inputs();
240 vk_num_public_inputs,
241 "process_hn_recursion_constraints: IO size mismatch with VK num_public_inputs");
246 vk_num_public_inputs,
247 "process_hn_recursion_constraints: proof vector smaller than num_public_inputs - malformed "
253 ivc->complete_kernel_circuit_logic(
builder);
257 gate_counter.
track_diff(gates_per_opcode, hn_recursion_data.second.at(0));
262 if (ivc_base ==
nullptr) {
265 process_with_ivc(ivc_base);
#define BB_ASSERT(expression,...)
#define BB_ASSERT_GTE(left, right,...)
#define BB_ASSERT_EQ(actual, expected,...)
KernelRecursiveFlavor::FF StdlibFF
AppRecursiveFlavor::VKAndHash AppRecursiveVKAndHash
KernelRecursiveFlavor::VKAndHash KernelRecursiveVKAndHash
StdlibVerificationKey_< CircuitBuilder, NativeFlavor::PrecomputedEntities< Commitment >, NativeFlavor::VerificationKey > VerificationKey
StdlibVerificationKey_< CircuitBuilder, NativeFlavor::PrecomputedEntities< Commitment >, NativeFlavor::VerificationKey > VerificationKey
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) dispatch_kind(CircuitKind kind, F &&f)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Output type for recursive ultra verification.