Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions barretenberg/acir_tests/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,6 @@ function test_cmds {
# the prove then verify flow for UltraHonk. This makes sure we have the same circuit for different witness inputs.
echo "$tests_hash $scripts/bbjs_prove.sh a_6_array"

# Fold and verify an ACIR program stack using ClientIVC, recursively verify as part of the Tube circuit and produce and verify a Honk proof
echo "$tests_hash $scripts/bb_tube_prove.sh a_6_array"

for t in $non_recursive_tests; do
echo "$tests_hash $scripts/bb_prove.sh $(basename $t)"
done
Expand Down
16 changes: 0 additions & 16 deletions barretenberg/acir_tests/scripts/bb_tube_prove.sh

This file was deleted.

99 changes: 0 additions & 99 deletions barretenberg/cpp/src/barretenberg/api/prove_tube.cpp

This file was deleted.

14 changes: 0 additions & 14 deletions barretenberg/cpp/src/barretenberg/api/prove_tube.hpp

This file was deleted.

38 changes: 0 additions & 38 deletions barretenberg/cpp/src/barretenberg/bb/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "barretenberg/api/api_msgpack.hpp"
#include "barretenberg/api/api_ultra_honk.hpp"
#include "barretenberg/api/file_io.hpp"
#include "barretenberg/api/prove_tube.hpp"
#include "barretenberg/bb/cli11_formatter.hpp"
#include "barretenberg/bbapi/bbapi.hpp"
#include "barretenberg/bbapi/bbapi_ultra_honk.hpp"
Expand Down Expand Up @@ -521,30 +520,6 @@ int parse_and_run_cli_command(int argc, char* argv[])
msgpack_run_command->add_option(
"-i,--input", msgpack_input_file, "Input file containing msgpack buffers (defaults to stdin)");

/***************************************************************************************************************
* Subcommand: prove_tube
***************************************************************************************************************/
CLI ::App* prove_tube_command = app.add_subcommand("prove_tube", "");
prove_tube_command->group(""); // hide from list of subcommands
add_verbose_flag(prove_tube_command);
add_debug_flag(prove_tube_command);
add_crs_path_option(prove_tube_command);
add_vk_path_option(prove_tube_command);
std::string prove_tube_output_path{ "./target" };
add_output_path_option(prove_tube_command, prove_tube_output_path);

/***************************************************************************************************************
* Subcommand: verify_tube
***************************************************************************************************************/
CLI::App* verify_tube_command = app.add_subcommand("verify_tube", "");
verify_tube_command->group(""); // hide from list of subcommands
add_verbose_flag(verify_tube_command);
add_debug_flag(verify_tube_command);
add_crs_path_option(verify_tube_command);
// doesn't make sense that this is set by -o but that's how it was
std::string tube_proof_and_vk_path{ "./target" };
add_output_path_option(verify_tube_command, tube_proof_and_vk_path);

/***************************************************************************************************************
* Build the CLI11 App
***************************************************************************************************************/
Expand Down Expand Up @@ -614,19 +589,6 @@ int parse_and_run_cli_command(int argc, char* argv[])
if (msgpack_run_command->parsed()) {
return execute_msgpack_run(msgpack_input_file);
}
// TUBE
if (prove_tube_command->parsed()) {
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1201): Potentially remove this extra logic.
prove_tube(prove_tube_output_path, vk_path);
} else if (verify_tube_command->parsed()) {
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1322): Remove verify_tube logic.
auto tube_public_inputs_path = tube_proof_and_vk_path + "/public_inputs";
auto tube_proof_path = tube_proof_and_vk_path + "/proof";
auto tube_vk_path = tube_proof_and_vk_path + "/vk";
UltraHonkAPI api;
return api.verify({ .ipa_accumulation = true }, tube_public_inputs_path, tube_proof_path, tube_vk_path) ? 0
: 1;
}
// AVM
#ifndef DISABLE_AZTEC_VM
else if (avm_prove_command->parsed()) {
Expand Down
3 changes: 1 addition & 2 deletions barretenberg/cpp/src/barretenberg/bbapi/bbapi_ultra_honk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,7 @@ bool _verify(const bool ipa_accumulation,
const std::ptrdiff_t honk_proof_with_pub_inputs_length =
static_cast<std::ptrdiff_t>(HONK_PROOF_LENGTH + num_public_inputs);
auto ipa_proof = Proof(complete_proof.begin() + honk_proof_with_pub_inputs_length, complete_proof.end());
auto tube_honk_proof =
Proof(complete_proof.begin(), complete_proof.begin() + honk_proof_with_pub_inputs_length);
auto honk_proof = Proof(complete_proof.begin(), complete_proof.begin() + honk_proof_with_pub_inputs_length);
verified = verifier.template verify_proof<RollupIO>(complete_proof, ipa_proof).result;
} else {
verified = verifier.template verify_proof<DefaultIO>(complete_proof).result;
Expand Down
16 changes: 13 additions & 3 deletions barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,19 +303,29 @@ void build_constraints(Builder& builder, AcirProgram& program, const ProgramMeta
bool has_pairing_points =
has_honk_recursion_constraints || has_civc_recursion_constraints || has_avm_recursion_constraints;

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1523): Only handle either HONK or CIVC + AVM and
// fail fast otherwise
// We only handle:
// - CIVC recursion constraints (Private Base Rollup)
// - HONK + AVM recursion constraints (Public Base Rollup)
// - HONK recursion constraints
// - AVM recursion constraints
// However, as mock protocol circuits use CIVC + AVM (mock Public Base Rollup), instead of throwing an assert we
// return a vinfo for the case of CIVC + AVM
BB_ASSERT_EQ(has_pg_recursion_constraints,
false,
"Invalid circuit: pg recursion constraints are present with UltraBuilder.");
BB_ASSERT_EQ(!(has_honk_recursion_constraints && has_civc_recursion_constraints),
BB_ASSERT_EQ(!(has_civc_recursion_constraints && has_honk_recursion_constraints),
true,
"Invalid circuit: both honk and civc recursion constraints are present.");
BB_ASSERT_EQ(
!(has_honk_recursion_constraints || has_civc_recursion_constraints || has_avm_recursion_constraints) ||
is_recursive_circuit,
true,
"Invalid circuit: honk, civc, or avm recursion constraints present but the circuit is not recursive.");
if (has_civc_recursion_constraints && has_avm_recursion_constraints) {
vinfo("WARNING: both civc and avm recursion constraints are present. While we support this combination, we "
"expect to see it only in a mock "
"circuit.");
}

// Container for data to be propagated
HonkRecursionConstraintsOutput<Builder> honk_output;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,122 +85,4 @@ TEST_F(ClientIVCRecursionTests, Basic)
// Print the number of gates post finalization
info("Recursive Verifier: finalized num gates = ", builder.num_gates);
}

TEST_F(ClientIVCRecursionTests, ClientTubeBase)
Copy link
Contributor Author

@federicobarbacovi federicobarbacovi Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is subsided by this test in civc_recursion_constraints (in that test we prove and verify a circuit containing a CIVC recursive verifier, i.e., a tube circuit) and by ultra recursive verifier tests, which test that an ultra recursive verifier can be proven and verified.

Together, these tests ensure that a CIVC recursive verifier can be proven and that its proof can be recursively verified, which are the two cases of interest:

  • CIVC recursive verifier proven = Private Base Rollup
  • CIVC recursive verifier proven and recursively verified = Public Base Rollup

{
using CIVCRecVerifierOutput = ClientIVCRecursiveVerifier::Output;

// Generate a genuine ClientIVC prover output
auto [proof, vk] = construct_client_ivc_prover_output();

// Construct the ClientIVC recursive verifier
Builder tube_builder;
ClientIVCVerifier verifier{ &tube_builder, vk.mega };

// Generate the recursive verification circuit
StdlibProof stdlib_proof(tube_builder, proof);
CIVCRecVerifierOutput client_ivc_rec_verifier_output = verifier.verify(stdlib_proof);

{
// IO
RollupIO inputs;
inputs.pairing_inputs = client_ivc_rec_verifier_output.points_accumulator;
inputs.ipa_claim = client_ivc_rec_verifier_output.opening_claim;
inputs.set_public();
}

// The tube only calls an IPA recursive verifier once, so we can just add this IPA proof
tube_builder.ipa_proof = client_ivc_rec_verifier_output.ipa_proof.get_value();

info("ClientIVC Recursive Verifier: num prefinalized gates = ", tube_builder.num_gates);

EXPECT_EQ(tube_builder.failed(), false) << tube_builder.err();

// EXPECT_TRUE(CircuitChecker::check(tube_builder));

// Construct and verify a proof for the ClientIVC Recursive Verifier circuit
auto prover_instance = std::make_shared<ProverInstance_<NativeFlavor>>(tube_builder);
auto native_vk_with_ipa = std::make_shared<NativeFlavor::VerificationKey>(prover_instance->get_precomputed());
UltraProver_<NativeFlavor> tube_prover{ prover_instance, native_vk_with_ipa };
// Prove the CIVCRecursiveVerifier circuit
auto native_tube_proof = tube_prover.construct_proof();

// Natively verify the tube proof
VerifierCommitmentKey<curve::Grumpkin> ipa_verification_key(1 << CONST_ECCVM_LOG_N);
UltraVerifier_<NativeFlavor> native_verifier(native_vk_with_ipa, ipa_verification_key);
bool native_result =
native_verifier.template verify_proof<bb::RollupIO>(native_tube_proof, tube_prover.prover_instance->ipa_proof)
.result;
EXPECT_TRUE(native_result);

// Construct a base rollup circuit that recursively verifies the tube proof and forwards the IPA proof.
Builder base_builder;
auto tube_vk = std::make_shared<NativeFlavor::VerificationKey>(prover_instance->get_precomputed());
auto stdlib_tube_vk_and_hash = std::make_shared<RollupFlavor::VKAndHash>(base_builder, tube_vk);
stdlib::Proof<Builder> base_tube_proof(base_builder, native_tube_proof);
UltraRecursiveVerifier base_verifier{ &base_builder, stdlib_tube_vk_and_hash };
UltraRecursiveVerifierOutput<Builder> output = base_verifier.template verify_proof<RollupIO>(base_tube_proof);
info("Tube UH Recursive Verifier: num prefinalized gates = ", base_builder.num_gates);

{
// IO
RollupIO inputs;
inputs.pairing_inputs = output.points_accumulator;
inputs.ipa_claim = output.ipa_claim;
inputs.set_public();
}

base_builder.ipa_proof = tube_prover.prover_instance->ipa_proof;
EXPECT_EQ(base_builder.failed(), false) << base_builder.err();
EXPECT_TRUE(CircuitChecker::check(base_builder));

// Natively verify the IPA proof for the base rollup circuit
auto base_prover_instance = std::make_shared<ProverInstance_<NativeFlavor>>(base_builder);
auto ipa_transcript = std::make_shared<NativeTranscript>();
ipa_transcript->load_proof(base_prover_instance->ipa_proof);
IPA<curve::Grumpkin>::reduce_verify(
ipa_verification_key, output.ipa_claim.get_native_opening_claim(), ipa_transcript);
}

// Ensure that the Client IVC Recursive Verifier Circuit does not depend on the Client IVC input
TEST_F(ClientIVCRecursionTests, TubeVKIndependentOfInputCircuits)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is a duplicate of this test in civc_recursion_constraints

{
// Retrieves the trace blocks (each consisting of a specific gate) from the recursive verifier circuit
auto get_blocks = [](size_t num_app_circuits)
-> std::tuple<typename Builder::ExecutionTrace, std::shared_ptr<NativeFlavor::VerificationKey>> {
auto [proof, ivc_vk] = construct_client_ivc_prover_output(num_app_circuits);

Builder tube_builder;
ClientIVCVerifier verifier{ &tube_builder, ivc_vk.mega };

StdlibProof stdlib_proof(tube_builder, proof);
auto client_ivc_rec_verifier_output = verifier.verify(stdlib_proof);

// IO
RollupIO inputs;
inputs.pairing_inputs = client_ivc_rec_verifier_output.points_accumulator;
inputs.ipa_claim = client_ivc_rec_verifier_output.opening_claim;
inputs.set_public();

// The tube only calls an IPA recursive verifier once, so we can just add this IPA proof
tube_builder.ipa_proof = client_ivc_rec_verifier_output.ipa_proof.get_value();

info("ClientIVC Recursive Verifier: num prefinalized gates = ", tube_builder.num_gates);

EXPECT_EQ(tube_builder.failed(), false) << tube_builder.err();

// Construct and verify a proof for the ClientIVC Recursive Verifier circuit
auto prover_instance = std::make_shared<ProverInstance_<NativeFlavor>>(tube_builder);

auto tube_vk = std::make_shared<NativeFlavor::VerificationKey>(prover_instance->get_precomputed());

return { tube_builder.blocks, tube_vk };
};

auto [blocks_4, verification_key_4] = get_blocks(/*num_app_circuits=*/1);
auto [blocks_5, verification_key_5] = get_blocks(/*num_app_circuits=*/2);

compare_ultra_blocks_and_verification_keys<NativeFlavor>({ blocks_4, blocks_5 },
{ verification_key_4, verification_key_5 });
}
} // namespace bb::stdlib::recursion::honk
Loading