Skip to content

Commit a0cb412

Browse files
ledwards2225AztecBot
authored and
AztecBot
committed
feat: remove auto verify mode from ClientIVC (#10599)
Removes auto verify mode from `ClientIVC`. Auto verify mode was a temporary feature designed to append kernel logic (recursive verifications etc.) to kernel circuits generated from noir kernel programs before the `verify_proof()` calls were integrated into those programs. Now that these calls are present in the kernels (mock and genuine), the kernel logic is automatically constructed via ivc_recursion_constraints via the normal `create_circuit()` pathway. If in the future there is need for a backend which automatically appends recursive verification logic, it should be implemented in an entirely separate class. Note: This change means we can no longer generate an IVC proof from the noir `fold_*` programs since they do not contain explicit recursive verifiers. All such tests/flows have been removed. Closes #1116 (remove manual setting of is_kernel) Closes #1101 (remove auto-verify)
1 parent e01ba96 commit a0cb412

14 files changed

+98
-366
lines changed

Earthfile

+2-8
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,8 @@ barretenberg-acir-tests-bb:
2626
ENV TEST_SRC /usr/src/acir_artifacts
2727
ENV VERBOSE=1
2828

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

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

10096
barretenberg-acir-tests-sol:
10197
FROM ../build-images/+from-registry
@@ -174,7 +170,5 @@ barretenberg-acir-tests-bb.js:
174170
RUN BIN=../ts/dest/node/main.js FLOW=prove_then_verify_ultra_honk ./run_acir_tests.sh 6_array assert_statement
175171
# Run a single arbitrary test not involving recursion through bb.js for MegaHonk
176172
RUN BIN=../ts/dest/node/main.js FLOW=prove_and_verify_mega_honk ./run_acir_tests.sh 6_array
177-
# Run fold_basic test through bb.js which runs ClientIVC on fold basic
178-
RUN BIN=../ts/dest/node/main.js FLOW=fold_and_verify_program ./run_acir_tests.sh fold_basic
179173
# Run 1_mul through bb.js build, all_cmds flow, to test all cli args.
180174
RUN BIN=../ts/dest/node/main.js FLOW=all_cmds ./run_acir_tests.sh 1_mul

acir_tests/flows/fold_and_verify_program.sh

-8
This file was deleted.

acir_tests/flows/prove_then_verify_tube.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ mkdir -p ./proofs
55

66
VFLAG=${VERBOSE:+-v}
77

8-
$BIN prove --scheme client_ivc --input_type compiletime_stack $VFLAG -c $CRS_PATH -b ./target/program.json
8+
$BIN write_arbitrary_valid_proof_and_vk_to_file --scheme client_ivc $VFLAG -c $CRS_PATH
99
$BIN prove_tube -k vk -p proof -c $CRS_PATH $VFLAG
1010
$BIN verify_tube -k vk -p proof -c $CRS_PATH $VFLAG
1111

cpp/src/barretenberg/bb/api.hpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ class API {
88
struct Flags {
99
std::optional<std::string> output_type; // bytes, fields, bytes_and_fields, fields_msgpack
1010
std::optional<std::string> input_type; // compiletime_stack, runtime_stack
11-
bool no_auto_verify; // TODO(https://github.com/AztecProtocol/barretenberg/issues/1101): remove
1211
};
1312

1413
virtual void prove(const Flags& flags,
@@ -36,5 +35,8 @@ class API {
3635
const std::filesystem::path& proof_path,
3736
const std::filesystem::path& vk_path,
3837
const std::filesystem::path& output_path) = 0;
38+
39+
virtual void write_arbitrary_valid_proof_and_vk_to_file(const API::Flags& flags,
40+
const std::filesystem::path& output_dir) = 0;
3941
};
4042
} // namespace bb

cpp/src/barretenberg/bb/api_client_ivc.hpp

+50-18
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "barretenberg/bb/acir_format_getters.hpp"
44
#include "barretenberg/bb/api.hpp"
55
#include "barretenberg/bb/init_srs.hpp"
6+
#include "barretenberg/client_ivc/mock_circuit_producer.hpp"
67
#include "barretenberg/common/throw_or_abort.hpp"
78
#include "libdeflate.h"
89

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

128-
static std::shared_ptr<ClientIVC> _accumulate(std::vector<acir_format::AcirProgram>& folding_stack,
129-
bool auto_verify = false)
129+
static std::shared_ptr<ClientIVC> _accumulate(std::vector<acir_format::AcirProgram>& folding_stack)
130130
{
131131
using Builder = MegaCircuitBuilder;
132132
using Program = acir_format::AcirProgram;
133133
using namespace acir_format;
134134

135-
vinfo("performing accumulation with auto-verify = ", auto_verify);
136-
137135
TraceSettings trace_settings{ E2E_FULL_TEST_STRUCTURE };
138-
auto ivc = std::make_shared<ClientIVC>(trace_settings, auto_verify);
136+
auto ivc = std::make_shared<ClientIVC>(trace_settings);
139137

140138
const ProgramMetadata metadata{ ivc };
141139

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

149-
// Set the internal is_kernel flag based on the local mechanism only if it has not already been set to true
150-
if (ivc->auto_verify_mode) {
151-
if (!circuit.databus_propagation_data.is_kernel) {
152-
circuit.databus_propagation_data.is_kernel = is_kernel;
153-
}
154-
is_kernel = !is_kernel;
155-
}
156-
157145
// Do one step of ivc accumulator or, if there is only one circuit in the stack, prove that circuit. In this
158146
// case, no work is added to the Goblin opqueue, but VM proofs for trivials inputs are produced.
159147
ivc->accumulate(circuit, /*one_circuit=*/folding_stack.size() == 1);
@@ -183,8 +171,7 @@ class ClientIVCAPI : public API {
183171
std::vector<acir_format::AcirProgram> folding_stack =
184172
_build_folding_stack(*flags.input_type, bytecode_path, witness_path);
185173

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

190177
// 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 {
246233

247234
std::vector<acir_format::AcirProgram> folding_stack =
248235
_build_folding_stack(*flags.input_type, bytecode_path, witness_path);
249-
std::shared_ptr<ClientIVC> ivc = _accumulate(folding_stack, /*auto_verify=*/true);
236+
std::shared_ptr<ClientIVC> ivc = _accumulate(folding_stack);
250237
const bool verified = ivc->prove_and_verify();
251238
return verified;
252239
};
253240

241+
/**
242+
* @brief Write an arbitrary but valid ClientIVC proof and VK to files
243+
* @details used to test the prove_tube flow
244+
*
245+
* @param flags
246+
* @param output_dir
247+
*/
248+
void write_arbitrary_valid_proof_and_vk_to_file(const API::Flags& flags,
249+
const std::filesystem::path& output_dir) override
250+
{
251+
if (!flags.output_type || *flags.output_type != "fields_msgpack") {
252+
throw_or_abort("No output_type or output_type not supported");
253+
}
254+
255+
if (!flags.input_type || !(*flags.input_type == "compiletime_stack" || *flags.input_type == "runtime_stack")) {
256+
throw_or_abort("No input_type or input_type not supported");
257+
}
258+
259+
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1163) set these dynamically
260+
init_bn254_crs(1 << 20);
261+
init_grumpkin_crs(1 << 15);
262+
263+
ClientIVC ivc{ { CLIENT_IVC_BENCH_STRUCTURE } };
264+
265+
// Construct and accumulate a series of mocked private function execution circuits
266+
PrivateFunctionExecutionMockCircuitProducer circuit_producer;
267+
size_t NUM_CIRCUITS = 2;
268+
for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) {
269+
auto circuit = circuit_producer.create_next_circuit(ivc);
270+
ivc.accumulate(circuit);
271+
}
272+
273+
ClientIVC::Proof proof = ivc.prove();
274+
275+
// Write the proof and verification keys into the working directory in 'binary' format
276+
vinfo("writing ClientIVC proof and vk...");
277+
write_file(output_dir / "client_ivc_proof", to_buffer(proof));
278+
279+
auto eccvm_vk = std::make_shared<ECCVMFlavor::VerificationKey>(ivc.goblin.get_eccvm_proving_key());
280+
auto translator_vk =
281+
std::make_shared<TranslatorFlavor::VerificationKey>(ivc.goblin.get_translator_proving_key());
282+
write_file(output_dir / "client_ivc_vk",
283+
to_buffer(ClientIVC::VerificationKey{ ivc.honk_vk, eccvm_vk, translator_vk }));
284+
};
285+
254286
void gates([[maybe_unused]] const API::Flags& flags,
255287
[[maybe_unused]] const std::filesystem::path& bytecode_path,
256288
[[maybe_unused]] const std::filesystem::path& witness_path) override

cpp/src/barretenberg/bb/main.cpp

+8-7
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,6 @@ void prove_tube(const std::string& output_path)
190190
{
191191
using namespace stdlib::recursion::honk;
192192

193-
using GoblinVerifierInput = ClientIVCRecursiveVerifier::GoblinVerifierInput;
194-
using VerifierInput = ClientIVCRecursiveVerifier::VerifierInput;
195193
using Builder = UltraCircuitBuilder;
196194
using GrumpkinVk = bb::VerifierCommitmentKey<curve::Grumpkin>;
197195

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

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

218214
// 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)
226222
auto offset = bb::HONK_PROOF_PUBLIC_INPUT_OFFSET;
227223
builder->add_public_variable(proof.mega_proof[i + offset]);
228224
}
229-
ClientIVCRecursiveVerifier verifier{ builder, input };
225+
ClientIVCRecursiveVerifier verifier{ builder, vk };
230226

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

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

11201116
const API::Flags flags = [&args]() {
11211117
return API::Flags{ .output_type = get_option(args, "--output_type", "fields_msgpack"),
1122-
.input_type = get_option(args, "--input_type", "compiletime_stack"),
1123-
.no_auto_verify = flag_present(args, "--no_auto_verify") };
1118+
.input_type = get_option(args, "--input_type", "compiletime_stack") };
11241119
}();
11251120

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

1156+
if (command == "write_arbitrary_valid_proof_and_vk_to_file") {
1157+
const std::filesystem::path output_dir = get_option(args, "-o", "./target");
1158+
api.write_arbitrary_valid_proof_and_vk_to_file(flags, output_dir);
1159+
return 1;
1160+
}
1161+
11611162
throw_or_abort("Invalid command passed to execute_command in bb");
11621163
return 1;
11631164
};

cpp/src/barretenberg/client_ivc/client_ivc.cpp

-6
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,6 @@ void ClientIVC::accumulate(ClientCircuit& circuit,
161161
const std::shared_ptr<MegaVerificationKey>& precomputed_vk,
162162
const bool mock_vk)
163163
{
164-
if (auto_verify_mode && circuit.databus_propagation_data.is_kernel) {
165-
complete_kernel_circuit_logic(circuit);
166-
}
167-
168164
// Construct merge proof for the present circuit and add to merge verification queue
169165
MergeProof merge_proof = goblin.prove_merge(circuit);
170166
merge_verification_queue.emplace_back(merge_proof);
@@ -407,10 +403,8 @@ std::vector<std::shared_ptr<MegaFlavor::VerificationKey>> ClientIVC::precompute_
407403

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

415409
return vkeys;
416410
}

cpp/src/barretenberg/client_ivc/client_ivc.hpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,6 @@ class ClientIVC {
126126
// Settings related to the use of fixed block sizes for each gate in the execution trace
127127
TraceSettings trace_settings;
128128

129-
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1101): eventually do away with this.
130-
// Setting auto_verify_mode = true will cause kernel completion logic to be added to kernels automatically
131-
bool auto_verify_mode;
132-
133129
std::shared_ptr<typename MegaFlavor::CommitmentKey> bn254_commitment_key;
134130

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

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

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

192187
std::vector<std::shared_ptr<MegaVerificationKey>> precompute_folding_verification_keys(
193188
std::vector<ClientCircuit> circuits);
189+
190+
VerificationKey get_vk() const
191+
{
192+
return { honk_vk,
193+
std::make_shared<ECCVMVerificationKey>(goblin.get_eccvm_proving_key()),
194+
std::make_shared<TranslatorVerificationKey>(goblin.get_translator_proving_key()) };
195+
}
194196
};
195197
} // namespace bb

0 commit comments

Comments
 (0)