19 std::vector<size_t>& gates_per_opcode,
26 bool has_honk_recursion_constraints = !honk_recursion_data.first.empty();
27 bool has_avm_recursion_constraints = !avm_recursion_data.first.empty();
28 bool has_hn_recursion_constraints = !hn_recursion_data.first.empty();
29 bool has_chonk_recursion_constraints = !chonk_recursion_data.first.empty();
32 BB_ASSERT(!has_honk_recursion_constraints || !has_hn_recursion_constraints,
33 "Invalid circuit: both honk and ivc recursion constraints present.");
36 "Invalid circuit: avm recursion constraints are not supported with MegaBuilder.");
39 BB_ASSERT(!has_chonk_recursion_constraints,
40 "Invalid circuit: chonk recursion constraints are not supported with MegaBuilder.");
43 for (
const auto& [constraint, opcode_idx] :
zip_view(honk_recursion_data.first, honk_recursion_data.second)) {
46 if (constraint.proof_type ==
HONK_ZK) {
47 honk_recursion_constraint =
48 create_honk_recursion_constraints<UltraZKRecursiveFlavor_<MegaCircuitBuilder>>(
builder, constraint);
49 }
else if (constraint.proof_type ==
HONK) {
50 honk_recursion_constraint =
51 create_honk_recursion_constraints<UltraRecursiveFlavor_<MegaCircuitBuilder>>(
builder, constraint);
58 output.
update(honk_recursion_constraint,
false);
59 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
62 if (has_hn_recursion_constraints) {
73 std::vector<size_t>& gates_per_opcode,
80 bool has_honk_recursion_constraints = !honk_recursion_data.first.empty();
81 bool has_avm_recursion_constraints = !avm_recursion_data.first.empty();
82 bool has_hn_recursion_constraints = !hn_recursion_data.first.empty();
83 bool has_chonk_recursion_constraints = !chonk_recursion_data.first.empty();
86 "Invalid circuit: HN recursion constraints are present with UltraBuilder.");
87 BB_ASSERT(!(has_chonk_recursion_constraints && has_honk_recursion_constraints),
88 "Invalid circuit: both honk and chonk recursion constraints are present.");
89 if (has_chonk_recursion_constraints && has_avm_recursion_constraints) {
90 vinfo(
"WARNING: both chonk and avm recursion constraints are present. While we support this combination, we "
91 "expect to see it only in a mock circuit.");
96 for (
const auto& [constraint, opcode_idx] :
zip_view(honk_recursion_data.first, honk_recursion_data.second)) {
99 if (constraint.proof_type ==
HONK_ZK) {
100 honk_recursion_constraint =
101 create_honk_recursion_constraints<UltraZKRecursiveFlavor_<UltraCircuitBuilder>>(
builder, constraint);
102 }
else if (constraint.proof_type ==
HONK) {
103 honk_recursion_constraint =
104 create_honk_recursion_constraints<UltraRecursiveFlavor_<UltraCircuitBuilder>>(
builder, constraint);
106 honk_recursion_constraint =
107 create_honk_recursion_constraints<UltraRollupRecursiveFlavor_<UltraCircuitBuilder>>(
builder,
114 output.
update(honk_recursion_constraint,
119 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
122 "Root rollup must accumulate two IPA proofs.");
124 for (
const auto& [constraint, opcode_idx] :
zip_view(chonk_recursion_data.first, chonk_recursion_data.second)) {
129 output.
update(honk_output,
true);
131 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
134 for (
const auto& [constraint, opcode_idx] :
zip_view(avm_recursion_data.first, avm_recursion_data.second)) {
139 output.
update(honk_output,
true);
141 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
150 std::vector<size_t>& gates_per_opcode,
162 ivc->verification_queue.size(),
163 "WARNING: Mismatch in number of recursive verifications during kernel creation!");
167 if (
builder.is_write_vk_mode()) {
169 for (
auto [constraint, queue_entry] :
zip_view(hn_recursion_data.first, ivc->verification_queue)) {
171 builder.set_variable(constraint.key_hash, queue_entry.honk_vk->hash());
178 stdlib_vk_and_hashs.reserve(hn_recursion_data.first.size());
179 for (
const auto& constraint : hn_recursion_data.first) {
182 StdlibVerificationKey::from_witness_indices(
builder, constraint.key)),
183 StdlibFF::from_witness_index(&
builder, constraint.key_hash)));
186 ivc->instantiate_stdlib_verification_queue(
builder, stdlib_vk_and_hashs);
194 for (
auto [constraint, queue_entry] :
zip_view(hn_recursion_data.first, ivc->stdlib_verification_queue)) {
196 queue_entry.proof.begin() +
197 static_cast<ptrdiff_t
>(constraint.public_inputs.size()));
199 for (
const auto [proof_public_input, constraint_public_input_idx] :
200 zip_view(public_inputs_from_proof, constraint.public_inputs)) {
201 const StdlibFF constraint_public_input =
202 StdlibFF::from_witness_index(&
builder, constraint_public_input_idx);
203 proof_public_input.assert_equal(constraint_public_input);
208 ivc->complete_kernel_circuit_logic(
builder);
212 gate_counter.
track_diff(gates_per_opcode, hn_recursion_data.second.at(0));
217 if (ivc_base ==
nullptr) {
219 process_with_ivc(mock_ivc);
222 process_with_ivc(sumcheck_ivc);