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
Show file tree
Hide file tree
Changes from 12 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
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Up @@ -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
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Up @@ -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"

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
15 changes: 8 additions & 7 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>;

Expand All @@ -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
Expand All @@ -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);

Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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;
};
Expand Down
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
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
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
Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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
Loading