14#include <gtest/gtest.h>
54template <
typename RecursiveFlavor_,
bool IsRootRollup_,
size_t N_, std::array<
size_t, N_> LayerSizes_>
59 static constexpr size_t N = N_;
60 static constexpr std::array<size_t, N>
LayerSizes = LayerSizes_;
63template <
typename RecursiveFlavor,
bool IsRootRollup,
size_t N, std::array<
size_t, N> LayerSizes>
68 for (
size_t idx = 0; idx < N - 1; idx++) {
69 if (LayerSizes[idx + 1] > LayerSizes[idx]) {
79 if constexpr (IsRootRollup) {
81 return N == 1 && LayerSizes[0] == 2;
103 }
else if constexpr (InnerFlavor::HasZK) {
113 using Builder = RecursiveFlavor::CircuitBuilder;
125 if constexpr (IsRootRollup) {
134 if constexpr (IsRootRollup) {
138 return {
"None",
"VKHash",
"VK",
"Proof" };
155 builder.add_public_variable(InnerBuilder::FF::random_element());
177 uint32_t uint32_offset =
static_cast<uint32_t
>(
offset);
178 auto shift_by_offset = [&uint32_offset](std::vector<uint32_t>& indices) {
179 for (
auto&
index : indices) {
180 index += uint32_offset;
184 shift_by_offset(honk_recursion_constraint.
key);
185 shift_by_offset(honk_recursion_constraint.
proof);
187 honk_recursion_constraint.
key_hash += uint32_offset;
188 honk_recursion_constraint.
predicate.index += uint32_offset;
191 for (
auto [constraint, witnesses] :
zip_view(constraints, witness_vectors)) {
192 offset_recursion_constraint(constraint, witness_values.size());
194 constraint.proof_type = IsRootRollup ?
static_cast<uint32_t
>(
ROOT_ROLLUP_HONK) : constraint.proof_type;
195 witness_values.insert(witness_values.end(), witnesses.begin(), witnesses.end());
199 return constraints[0];
214 builder.add_public_variable(InnerBuilder::FF::random_element());
219 InnerProver prover(prover_instance, verification_key);
226 verification_key->to_field_elements(),
227 verification_key->hash(),
229 builder.num_public_inputs() - InnerIO::PUBLIC_INPUTS_SIZE,
232 return { recursion_constraint, witness_values };
250 switch (invalid_witness_target) {
256 witness_values[honk_recursion_constraints.key_hash] +=
fr::one();
258 witness_values[honk_recursion_constraints[0].key_hash] +=
fr::one();
264 std::vector<uint32_t> vk_indices;
266 witness_values[honk_recursion_constraints.key[0]] +=
fr::one();
268 witness_values[honk_recursion_constraints[0].key[0]] +=
fr::one();
275 std::vector<uint32_t> proof_indices;
277 proof_indices = honk_recursion_constraints.proof;
279 proof_indices = honk_recursion_constraints[0].proof;
281 size_t commitment_size = FrCodec::template calc_num_fields<typename InnerFlavor::Commitment>();
283 for (
size_t idx = 0; idx < commitment_size; idx++) {
284 witness_values[proof_indices[InnerIO::PUBLIC_INPUTS_SIZE + idx]] = mock_proof_element[idx];
290 return { honk_recursion_constraints, witness_values };
298 for (
size_t layer_idx = 0; layer_idx < N; layer_idx++) {
299 size_t current_layer_size = LayerSizes[layer_idx];
300 for (
size_t idx = 0; idx < current_layer_size; idx++) {
301 if (layer_idx == 0) {
304 auto [constraint, witnesses] = []() {
308 constraints.emplace_back(
std::move(constraint));
309 witness_vectors.emplace_back(
std::move(witnesses));
320 std::tie(constraints[idx], witness_vectors[idx]) = [&]() {
333template <
typename Params>
335 :
public ::testing::Test,
337 Params::IsRootRollup,
339 Params::LayerSizes>> {
351 testing::Types<HonkRecursionTestParams<UltraRecursiveFlavor_<UltraCircuitBuilder>,
false, 1, { 1 }>,
364 typename TestFixture::RecursiveFlavor::NativeFlavor>;
365 TestFixture::template test_vk_independence<Flavor>();
371 TestFixture::test_constant_true(TestFixture::InvalidWitnessTarget::VKHash);
377 TestFixture::test_witness_true(TestFixture::InvalidWitnessTarget::VKHash);
383 TestFixture::test_witness_false_slow();
388 using RecursiveFlavor = TestFixture::RecursiveFlavor;
389 using Builder = TestFixture::Builder;
390 using InvalidWitnessTarget = TestFixture::InvalidWitnessTarget;
392 typename TestFixture::AcirConstraint constraint;
394 TestFixture::Base::generate_constraints(constraint, witness_values);
398 .invalid_witness = InvalidWitnessTarget::None };
399 auto [updated_constraint, updated_witness_values] =
400 TestFixture::update_witness_based_on_predicate(constraint, witness_values, predicate);
404 AcirProgram program{ constraint_system, updated_witness_values };
407 auto builder = create_circuit<Builder>(program, metadata);
410 EXPECT_EQ(program.constraints.gates_per_opcode.size(), 1);
413 auto [EXPECTED_GATE_COUNT, EXPECTED_ULTRA_OPS] = HONK_RECURSION_CONSTANTS<RecursiveFlavor>(predicate_mode);
416 EXPECT_EQ(program.constraints.gates_per_opcode[0], EXPECTED_GATE_COUNT);
420 size_t actual_ultra_ops =
builder.op_queue->get_current_subtable_size();
421 EXPECT_EQ(actual_ultra_ops, EXPECTED_ULTRA_OPS);
426template <
typename Params>
428 :
public ::testing::Test,
429 public TestClass<HonkRecursionConstraintTestingFunctions<typename Params::RecursiveFlavor,
430 Params::IsRootRollup,
432 Params::LayerSizes>> {
453 if constexpr (TypeParam::IsRootRollup) {
454 TestFixture::template test_vk_independence<UltraZKFlavor>();
460 typename TestFixture::RecursiveFlavor::NativeFlavor>;
462 TestFixture::template test_vk_independence<Flavor>();
469 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_tampering();
474 using Builder = TestFixture::Builder;
476 if constexpr (!TestFixture::IsRootRollup) {
480 typename TestFixture::AcirConstraint constraint;
482 TestFixture::Base::generate_constraints(constraint, witness_values);
486 AcirProgram program{ constraint_system, witness_values };
489 auto builder = create_circuit<Builder>(program, metadata);
492 EXPECT_EQ(program.constraints.gates_per_opcode.size(), 2);
#define BB_DISABLE_ASSERTS()
static void SetUpTestSuite()
static constexpr bool IsRootRollup
Params::RecursiveFlavor RecursiveFlavor
Params::RecursiveFlavor RecursiveFlavor
static void SetUpTestSuite()
static constexpr bool IsRootRollup
InnerFlavor::VerificationKey InnerVerificationKey
static constexpr uint32_t InnerProofType
std::conditional_t< IS_SINGLE_RECURSIVE_VERIFICATION, RecursionConstraint, std::vector< RecursionConstraint > > AcirConstraint
static InnerBuilder create_inner_circuit()
Create a dummy circuit.
static void generate_constraints(AcirConstraint &honk_recursion_constraint, WitnessVector &witness_values)
static constexpr bool UseRollupIO
static constexpr size_t NUM_PUBLIC_INPUTS
static ProgramMetadata generate_metadata()
Generate the metadata for the circuit recursively verifying the top layer circuits.
InnerFlavor::CircuitBuilder InnerBuilder
static constexpr bool IS_SINGLE_RECURSIVE_VERIFICATION
static std::pair< AcirConstraint, WitnessVector > invalidate_witness(AcirConstraint honk_recursion_constraints, WitnessVector witness_values, const InvalidWitness::Target &invalid_witness_target)
std::conditional_t< UseRollupIO, bb::stdlib::recursion::honk::RollupIO, bb::stdlib::recursion::honk::DefaultIO< InnerBuilder > > InnerIO
RecursiveFlavor::NativeFlavor InnerFlavor
RecursiveFlavor::CircuitBuilder Builder
static std::pair< RecursionConstraint, WitnessVector > circuit_to_recursion_constraint(InnerBuilder &builder)
Convert a circuit into a recursion constraint: prove the circuit and add the proof,...
static AcirConstraint merge_recursion_constraints(std::vector< RecursionConstraint > &constraints, std::vector< WitnessVector > &witness_vectors, WitnessVector &witness_values)
Merge a series of recursion constraints by offsetting the relevant indices and concatenating the witn...
static constexpr bool IsRootRollup
static constexpr size_t N
RecursiveFlavor_ RecursiveFlavor
static constexpr std::array< size_t, N > LayerSizes
static std::vector< fr > serialize_to_fields(const T &val)
Conversion from transcript values to bb::frs.
static void add_lookup_gates(Builder &builder, size_t num_iterations=1)
Add lookup gates using the uint32 XOR lookup table (table size 4096)
static void add_arithmetic_gates(Builder &builder, const size_t num_gates=4)
Add a specified number of arithmetic gates to the provided circuit.
Contains all the information required by a Honk prover to create a proof, constructed from a finalize...
A simple wrapper around a vector of stdlib field elements representing a proof.
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.
testing::Types< HonkRecursionTestParams< UltraRecursiveFlavor_< UltraCircuitBuilder >, false, 1, { 1 }>, HonkRecursionTestParams< UltraZKRecursiveFlavor_< UltraCircuitBuilder >, false, 1, { 1 }>, HonkRecursionTestParams< UltraRecursiveFlavor_< MegaCircuitBuilder >, false, 1, { 1 }>, HonkRecursionTestParams< UltraZKRecursiveFlavor_< MegaCircuitBuilder >, false, 1, { 1 }> > HonkRecursionTypesWithPredicate
testing::Types< HonkRecursionTestParams< UltraRecursiveFlavor_< UltraCircuitBuilder >, false, 1, { 2 }>, HonkRecursionTestParams< UltraZKRecursiveFlavor_< UltraCircuitBuilder >, false, 1, { 2 }>, HonkRecursionTestParams< UltraRecursiveFlavor_< UltraCircuitBuilder >, true, 1, { 2 }>, HonkRecursionTestParams< UltraZKRecursiveFlavor_< UltraCircuitBuilder >, false, 2, { 2, 1 }>, HonkRecursionTestParams< UltraZKRecursiveFlavor_< UltraCircuitBuilder >, false, 2, { 2, 2 }>, HonkRecursionTestParams< UltraRecursiveFlavor_< MegaCircuitBuilder >, false, 4, { 4, 3, 1, 1 }> > HonkRecursionTypesWithoutPredicate
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
Entry point for Barretenberg command-line interface.
TYPED_TEST_SUITE(CommitmentKeyTest, Curves)
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
static std::vector< Target > get_all()
static std::vector< std::string > get_labels()
static constexpr field one()