Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: remove auto verify mode from ClientIVC #10599

Merged
merged 13 commits into from
Dec 12, 2024
Merged
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
10 changes: 2 additions & 8 deletions barretenberg/Earthfile
Original file line number Diff line number Diff line change
@@ -26,12 +26,8 @@ barretenberg-acir-tests-bb:
ENV TEST_SRC /usr/src/acir_artifacts
ENV VERBOSE=1

# Fold and verify an ACIR program stack using ClientIvc
RUN INPUT_TYPE=compiletime_stack FLOW=prove_and_verify_client_ivc ./run_acir_tests.sh fold_basic
# Fold and verify an ACIR program stack using ClientIvc, then natively verify the ClientIVC proof.
RUN INPUT_TYPE=compiletime_stack FLOW=prove_then_verify_client_ivc ./run_acir_tests.sh fold_basic
# Fold and verify an ACIR program stack using ClientIvc, recursively verify as part of the Tube circuit and produce and verify a Honk proof
RUN FLOW=prove_then_verify_tube ./run_acir_tests.sh fold_basic
RUN FLOW=prove_then_verify_tube ./run_acir_tests.sh 6_array
# Run 1_mul through native bb build, all_cmds flow, to test all cli args.
RUN FLOW=all_cmds ./run_acir_tests.sh 1_mul

@@ -95,7 +91,7 @@ barretenberg-acir-tests-bb-client-ivc:
# Construct and verify a ClientIVC proof for a single arbitrary program
RUN FLOW=prove_and_verify_client_ivc ./run_acir_tests.sh 6_array
# Construct and separately verify a ClientIVC proof for all acir programs
RUN FLOW=prove_then_verify_client_ivc CLIENT_IVC_SKIPS=true ./run_acir_tests.sh
RUN FLOW=prove_then_verify_client_ivc ./run_acir_tests.sh 6_array databus databus_two_calldata
Copy link
Contributor

Choose a reason for hiding this comment

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

does it make sense to run civc on 6_array both here and above?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the difference is AND vs THEN. maybe not critical to run both but no real harm


barretenberg-acir-tests-sol:
FROM ../build-images/+from-registry
@@ -174,7 +170,5 @@ barretenberg-acir-tests-bb.js:
RUN BIN=../ts/dest/node/main.js FLOW=prove_then_verify_ultra_honk ./run_acir_tests.sh 6_array assert_statement
# Run a single arbitrary test not involving recursion through bb.js for MegaHonk
RUN BIN=../ts/dest/node/main.js FLOW=prove_and_verify_mega_honk ./run_acir_tests.sh 6_array
# Run fold_basic test through bb.js which runs ClientIVC on fold basic
RUN BIN=../ts/dest/node/main.js FLOW=fold_and_verify_program ./run_acir_tests.sh fold_basic
# Run 1_mul through bb.js build, all_cmds flow, to test all cli args.
RUN BIN=../ts/dest/node/main.js FLOW=all_cmds ./run_acir_tests.sh 1_mul
8 changes: 0 additions & 8 deletions barretenberg/acir_tests/flows/fold_and_verify_program.sh

This file was deleted.

2 changes: 1 addition & 1 deletion barretenberg/acir_tests/flows/prove_then_verify_tube.sh
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ mkdir -p ./proofs

VFLAG=${VERBOSE:+-v}

$BIN prove --scheme client_ivc --input_type compiletime_stack $VFLAG -c $CRS_PATH -b ./target/program.json
$BIN write_arbitrary_valid_proof_and_vk_to_file --scheme client_ivc $VFLAG -c $CRS_PATH
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can no longer generate a full ClientIvc proof from existing noir programs so I just added a flow that produces a valid proof/vk and writes them to file.

$BIN prove_tube -k vk -p proof -c $CRS_PATH $VFLAG
$BIN verify_tube -k vk -p proof -c $CRS_PATH $VFLAG

4 changes: 3 additions & 1 deletion barretenberg/cpp/src/barretenberg/bb/api.hpp
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@ class API {
struct Flags {
std::optional<std::string> output_type; // bytes, fields, bytes_and_fields, fields_msgpack
std::optional<std::string> input_type; // compiletime_stack, runtime_stack
bool no_auto_verify; // TODO(https://github.com/AztecProtocol/barretenberg/issues/1101): remove
};

virtual void prove(const Flags& flags,
@@ -36,5 +35,8 @@ class API {
const std::filesystem::path& proof_path,
const std::filesystem::path& vk_path,
const std::filesystem::path& output_path) = 0;

virtual void write_arbitrary_valid_proof_and_vk_to_file(const API::Flags& flags,
const std::filesystem::path& output_dir) = 0;
};
} // namespace bb
68 changes: 50 additions & 18 deletions barretenberg/cpp/src/barretenberg/bb/api_client_ivc.hpp
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
#include "barretenberg/bb/acir_format_getters.hpp"
#include "barretenberg/bb/api.hpp"
#include "barretenberg/bb/init_srs.hpp"
#include "barretenberg/client_ivc/mock_circuit_producer.hpp"
#include "barretenberg/common/throw_or_abort.hpp"
#include "libdeflate.h"

@@ -125,35 +126,22 @@ class ClientIVCAPI : public API {
return folding_stack;
};

static std::shared_ptr<ClientIVC> _accumulate(std::vector<acir_format::AcirProgram>& folding_stack,
bool auto_verify = false)
static std::shared_ptr<ClientIVC> _accumulate(std::vector<acir_format::AcirProgram>& folding_stack)
{
using Builder = MegaCircuitBuilder;
using Program = acir_format::AcirProgram;
using namespace acir_format;

vinfo("performing accumulation with auto-verify = ", auto_verify);

TraceSettings trace_settings{ E2E_FULL_TEST_STRUCTURE };
auto ivc = std::make_shared<ClientIVC>(trace_settings, auto_verify);
auto ivc = std::make_shared<ClientIVC>(trace_settings);

const ProgramMetadata metadata{ ivc };

// Accumulate the entire program stack into the IVC
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1116): remove manual setting of is_kernel
bool is_kernel = false;
for (Program& program : folding_stack) {
// Construct a bberg circuit from the acir representation then accumulate it into the IVC
Builder circuit = acir_format::create_circuit<Builder>(program, metadata);

// Set the internal is_kernel flag based on the local mechanism only if it has not already been set to true
if (ivc->auto_verify_mode) {
if (!circuit.databus_propagation_data.is_kernel) {
circuit.databus_propagation_data.is_kernel = is_kernel;
}
is_kernel = !is_kernel;
}

// Do one step of ivc accumulator or, if there is only one circuit in the stack, prove that circuit. In this
// case, no work is added to the Goblin opqueue, but VM proofs for trivials inputs are produced.
ivc->accumulate(circuit, /*one_circuit=*/folding_stack.size() == 1);
@@ -183,8 +171,7 @@ class ClientIVCAPI : public API {
std::vector<acir_format::AcirProgram> folding_stack =
_build_folding_stack(*flags.input_type, bytecode_path, witness_path);

bool auto_verify = !flags.no_auto_verify;
std::shared_ptr<ClientIVC> ivc = _accumulate(folding_stack, auto_verify);
std::shared_ptr<ClientIVC> ivc = _accumulate(folding_stack);
ClientIVC::Proof proof = ivc->prove();

// Write the proof and verification keys into the working directory in 'binary' format (in practice it seems
@@ -246,11 +233,56 @@ class ClientIVCAPI : public API {

std::vector<acir_format::AcirProgram> folding_stack =
_build_folding_stack(*flags.input_type, bytecode_path, witness_path);
std::shared_ptr<ClientIVC> ivc = _accumulate(folding_stack, /*auto_verify=*/true);
std::shared_ptr<ClientIVC> ivc = _accumulate(folding_stack);
const bool verified = ivc->prove_and_verify();
return verified;
};

/**
* @brief Write an arbitrary but valid ClientIVC proof and VK to files
* @details used to test the prove_tube flow
*
* @param flags
* @param output_dir
*/
void write_arbitrary_valid_proof_and_vk_to_file(const API::Flags& flags,
const std::filesystem::path& output_dir) override
{
if (!flags.output_type || *flags.output_type != "fields_msgpack") {
throw_or_abort("No output_type or output_type not supported");
}

if (!flags.input_type || !(*flags.input_type == "compiletime_stack" || *flags.input_type == "runtime_stack")) {
throw_or_abort("No input_type or input_type not supported");
}

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1163) set these dynamically
init_bn254_crs(1 << 20);
init_grumpkin_crs(1 << 15);

ClientIVC ivc{ { CLIENT_IVC_BENCH_STRUCTURE } };

// Construct and accumulate a series of mocked private function execution circuits
PrivateFunctionExecutionMockCircuitProducer circuit_producer;
size_t NUM_CIRCUITS = 2;
for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
auto circuit = circuit_producer.create_next_circuit(ivc);
ivc.accumulate(circuit);
}

ClientIVC::Proof proof = ivc.prove();

// Write the proof and verification keys into the working directory in 'binary' format
vinfo("writing ClientIVC proof and vk...");
write_file(output_dir / "client_ivc_proof", to_buffer(proof));

auto eccvm_vk = std::make_shared<ECCVMFlavor::VerificationKey>(ivc.goblin.get_eccvm_proving_key());
auto translator_vk =
std::make_shared<TranslatorFlavor::VerificationKey>(ivc.goblin.get_translator_proving_key());
write_file(output_dir / "client_ivc_vk",
to_buffer(ClientIVC::VerificationKey{ ivc.honk_vk, eccvm_vk, translator_vk }));
};

void gates([[maybe_unused]] const API::Flags& flags,
[[maybe_unused]] const std::filesystem::path& bytecode_path,
[[maybe_unused]] const std::filesystem::path& witness_path) override
15 changes: 8 additions & 7 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
@@ -190,8 +190,6 @@ void prove_tube(const std::string& output_path)
{
using namespace stdlib::recursion::honk;

using GoblinVerifierInput = ClientIVCRecursiveVerifier::GoblinVerifierInput;
using VerifierInput = ClientIVCRecursiveVerifier::VerifierInput;
using Builder = UltraCircuitBuilder;
using GrumpkinVk = bb::VerifierCommitmentKey<curve::Grumpkin>;

@@ -211,8 +209,6 @@ void prove_tube(const std::string& output_path)
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1025)
vk.eccvm->pcs_verification_key = std::make_shared<GrumpkinVk>(vk.eccvm->circuit_size + 1);

GoblinVerifierInput goblin_verifier_input{ vk.eccvm, vk.translator };
VerifierInput input{ vk.mega, goblin_verifier_input };
auto builder = std::make_shared<Builder>();

// Preserve the public inputs that should be passed to the base rollup by making them public inputs to the tube
@@ -226,7 +222,7 @@ void prove_tube(const std::string& output_path)
auto offset = bb::HONK_PROOF_PUBLIC_INPUT_OFFSET;
builder->add_public_variable(proof.mega_proof[i + offset]);
}
ClientIVCRecursiveVerifier verifier{ builder, input };
ClientIVCRecursiveVerifier verifier{ builder, vk };

ClientIVCRecursiveVerifier::Output client_ivc_rec_verifier_output = verifier.verify(proof);

@@ -1119,8 +1115,7 @@ int main(int argc, char* argv[])

const API::Flags flags = [&args]() {
return API::Flags{ .output_type = get_option(args, "--output_type", "fields_msgpack"),
.input_type = get_option(args, "--input_type", "compiletime_stack"),
.no_auto_verify = flag_present(args, "--no_auto_verify") };
.input_type = get_option(args, "--input_type", "compiletime_stack") };
}();

const std::string command = args[0];
@@ -1158,6 +1153,12 @@ int main(int argc, char* argv[])
return api.prove_and_verify(flags, bytecode_path, witness_path) ? 0 : 1;
}

if (command == "write_arbitrary_valid_proof_and_vk_to_file") {
const std::filesystem::path output_dir = get_option(args, "-o", "./target");
api.write_arbitrary_valid_proof_and_vk_to_file(flags, output_dir);
return 1;
}

throw_or_abort("Invalid command passed to execute_command in bb");
return 1;
};
6 changes: 0 additions & 6 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp
Original file line number Diff line number Diff line change
@@ -161,10 +161,6 @@ void ClientIVC::accumulate(ClientCircuit& circuit,
const std::shared_ptr<MegaVerificationKey>& precomputed_vk,
const bool mock_vk)
{
if (auto_verify_mode && circuit.databus_propagation_data.is_kernel) {
complete_kernel_circuit_logic(circuit);
}

// Construct merge proof for the present circuit and add to merge verification queue
MergeProof merge_proof = goblin.prove_merge(circuit);
merge_verification_queue.emplace_back(merge_proof);
@@ -407,10 +403,8 @@ std::vector<std::shared_ptr<MegaFlavor::VerificationKey>> ClientIVC::precompute_

// Reset the scheme so it can be reused for actual accumulation, maintaining the trace structure setting as is
TraceSettings settings = trace_settings;
bool auto_verify = auto_verify_mode;
*this = ClientIVC();
this->trace_settings = settings;
this->auto_verify_mode = auto_verify;

return vkeys;
}
14 changes: 8 additions & 6 deletions barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp
Original file line number Diff line number Diff line change
@@ -126,10 +126,6 @@ class ClientIVC {
// Settings related to the use of fixed block sizes for each gate in the execution trace
TraceSettings trace_settings;

// TODO(https://github.com/AztecProtocol/barretenberg/issues/1101): eventually do away with this.
// Setting auto_verify_mode = true will cause kernel completion logic to be added to kernels automatically
bool auto_verify_mode;

std::shared_ptr<typename MegaFlavor::CommitmentKey> bn254_commitment_key;

GoblinProver goblin;
@@ -140,10 +136,9 @@ class ClientIVC {

bool initialized = false; // Is the IVC accumulator initialized

ClientIVC(TraceSettings trace_settings = {}, bool auto_verify_mode = false)
ClientIVC(TraceSettings trace_settings = {})
: trace_usage_tracker(trace_settings)
, trace_settings(trace_settings)
, auto_verify_mode(auto_verify_mode)
, bn254_commitment_key(trace_settings.structure.has_value()
? std::make_shared<CommitmentKey<curve::BN254>>(trace_settings.dyadic_size())
: nullptr)
@@ -191,5 +186,12 @@ class ClientIVC {

std::vector<std::shared_ptr<MegaVerificationKey>> precompute_folding_verification_keys(
std::vector<ClientCircuit> circuits);

VerificationKey get_vk() const
{
return { honk_vk,
std::make_shared<ECCVMVerificationKey>(goblin.get_eccvm_proving_key()),
std::make_shared<TranslatorVerificationKey>(goblin.get_translator_proving_key()) };
}
};
} // namespace bb
Loading