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>>(
builder, constraint);
50 }
else if (constraint.proof_type ==
HONK) {
51 honk_recursion_constraint =
52 create_honk_recursion_constraints<UltraRecursiveFlavor_<MegaCircuitBuilder>>(
builder, constraint);
59 output.
update(honk_recursion_constraint,
false);
60 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
63 if (has_hn_recursion_constraints) {
74 std::vector<size_t>& gates_per_opcode,
81 bool has_honk_recursion_constraints = !honk_recursion_data.first.empty();
82 bool has_avm_recursion_constraints = !avm_recursion_data.first.empty();
83 bool has_hn_recursion_constraints = !hn_recursion_data.first.empty();
84 bool has_chonk_recursion_constraints = !chonk_recursion_data.first.empty();
88 !has_hn_recursion_constraints,
89 "create_recursion_constraints: invalid circuit - HN recursion constraints not supported with UltraBuilder");
90 BB_ASSERT(!(has_chonk_recursion_constraints && has_honk_recursion_constraints),
91 "create_recursion_constraints: invalid circuit - both honk and chonk recursion constraints present");
92 if (has_chonk_recursion_constraints && has_avm_recursion_constraints) {
93 vinfo(
"WARNING: both chonk and avm recursion constraints are present. While we support this combination, we "
94 "expect to see it only in a mock circuit.");
99 for (
const auto& [constraint, opcode_idx] :
zip_view(honk_recursion_data.first, honk_recursion_data.second)) {
102 if (constraint.proof_type ==
HONK_ZK) {
103 honk_recursion_constraint =
104 create_honk_recursion_constraints<UltraZKRecursiveFlavor_<UltraCircuitBuilder>>(
builder, constraint);
105 }
else if (constraint.proof_type ==
HONK) {
106 honk_recursion_constraint =
107 create_honk_recursion_constraints<UltraRecursiveFlavor_<UltraCircuitBuilder>>(
builder, constraint);
109 honk_recursion_constraint =
110 create_honk_recursion_constraints<UltraRollupRecursiveFlavor_<UltraCircuitBuilder>>(
builder,
117 output.
update(honk_recursion_constraint,
122 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
125 "Root rollup must accumulate two IPA proofs.");
127 for (
const auto& [constraint, opcode_idx] :
zip_view(chonk_recursion_data.first, chonk_recursion_data.second)) {
132 output.
update(honk_output,
true);
134 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
137 for (
const auto& [constraint, opcode_idx] :
zip_view(avm_recursion_data.first, avm_recursion_data.second)) {
142 output.
update(honk_output,
true);
144 gate_counter.
track_diff(gates_per_opcode, opcode_idx);
153 std::vector<size_t>& gates_per_opcode,
163 hn_recursion_data.second.size(),
164 "process_hn_recursion_constraints: hn_recursion_data constraints/indices size mismatch");
170 ivc->verification_queue.size(),
171 "process_hn_recursion_constraints: mismatch in number of recursive verifications during kernel "
176 if (
builder.is_write_vk_mode()) {
178 for (
auto [constraint, queue_entry] :
zip_view(hn_recursion_data.first, ivc->verification_queue)) {
181 builder.set_variable(constraint.key_hash, queue_entry.honk_vk->hash());
188 stdlib_vk_and_hashs.reserve(hn_recursion_data.first.size());
189 for (
const auto& constraint : hn_recursion_data.first) {
192 StdlibVerificationKey::from_witness_indices(
builder, constraint.key)),
193 StdlibFF::from_witness_index(&
builder, constraint.key_hash)));
196 ivc->instantiate_stdlib_verification_queue(
builder, stdlib_vk_and_hashs);
200 hn_recursion_data.first.size(),
201 "process_hn_recursion_constraints: stdlib_verification_queue size mismatch after instantiation");
204 for (
auto [constraint, queue_entry] :
zip_view(hn_recursion_data.first, ivc->stdlib_verification_queue)) {
207 "process_hn_recursion_constraints: ACIR constraint proof_type does not match IVC queue type");
212 BB_ASSERT(constraint.public_inputs.empty(),
213 "process_hn_recursion_constraints: unexpected non-empty public_inputs in HN constraint - "
214 "Noir HN constraints should have empty public_inputs (public inputs are handled by IVC IO)");
217 size_t expected_io_size =
218 queue_entry.is_kernel ? IVCType::KernelIO::PUBLIC_INPUTS_SIZE : IVCType::AppIO::PUBLIC_INPUTS_SIZE;
219 size_t vk_num_public_inputs =
220 static_cast<size_t>(uint64_t(queue_entry.honk_vk_and_hash->vk->num_public_inputs.get_value()));
222 vk_num_public_inputs,
223 "process_hn_recursion_constraints: IO size mismatch with VK num_public_inputs");
228 vk_num_public_inputs,
229 "process_hn_recursion_constraints: proof vector smaller than num_public_inputs - malformed "
234 ivc->complete_kernel_circuit_logic(
builder);
238 gate_counter.
track_diff(gates_per_opcode, hn_recursion_data.second.at(0));
243 if (ivc_base ==
nullptr) {
245 process_with_ivc(mock_ivc);
249 throw_or_abort(
"process_hn_recursion_constraints: ivc_base is not a Chonk instance");
251 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
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)