Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
acir_integration.test.cpp
Go to the documentation of this file.
2#ifndef __wasm__
9
10#include <filesystem>
11#include <gtest/gtest.h>
12
13// #define LOG_SIZES
14
15using namespace bb;
16class AcirIntegrationTest : public ::testing::Test {
17 public:
18 // Function to check if a file exists
19 static bool file_exists(const std::string& path)
20 {
21 std::ifstream file(path);
22 return file.good();
23 }
24
25 static acir_format::AcirProgramStack get_program_stack_data_from_test_file(const std::string& test_program_name)
26 {
27 std::string base_path = "../../acir_tests/acir_tests/" + test_program_name + "/target";
28 std::string bytecode_path = base_path + "/program.json";
29 std::string witness_path = base_path + "/witness.gz";
30
31 return acir_format::get_acir_program_stack(bytecode_path, witness_path);
32 }
33
34 static acir_format::AcirProgram get_program_data_from_test_file(const std::string& test_program_name)
35 {
36 auto program_stack = get_program_stack_data_from_test_file(test_program_name);
37 BB_ASSERT_EQ(program_stack.size(),
38 static_cast<size_t>(1)); // Otherwise this method will not return full stack data
39
40 return program_stack.back();
41 }
42
44 {
45 using Prover = UltraProver_<Flavor>;
46 using Verifier = UltraVerifier_<Flavor>;
48
50 auto verification_key = std::make_shared<VerificationKey>(prover_instance->get_precomputed());
51 Prover prover{ prover_instance, verification_key };
52#ifdef LOG_SIZES
53 builder.blocks.summarize();
54 info("num gates = ", builder.get_estimated_num_finalized_gates());
55 info("total circuit size = ", builder.get_estimated_total_circuit_size());
56 info("circuit size = ", prover.prover_instance->dyadic_size());
57 info("log circuit size = ", prover.prover_instance->log_dyadic_size());
58#endif
59 auto proof = prover.construct_proof();
60
61 // Verify Honk proof
62 Verifier verifier{ verification_key };
63 bool result = verifier.template verify_proof<DefaultIO>(proof).result;
64
65 return result;
66 }
67
68 void add_some_simple_RAM_gates(auto& circuit)
69 {
70 std::array<uint32_t, 3> ram_values{ circuit.add_variable(5),
71 circuit.add_variable(10),
72 circuit.add_variable(20) };
73
74 size_t ram_id = circuit.create_RAM_array(3);
75
76 for (size_t i = 0; i < 3; ++i) {
77 circuit.init_RAM_element(ram_id, i, ram_values[i]);
78 }
79
80 auto val_idx_1 = circuit.read_RAM_array(ram_id, circuit.add_variable(1));
81 auto val_idx_2 = circuit.read_RAM_array(ram_id, circuit.add_variable(2));
82 auto val_idx_3 = circuit.read_RAM_array(ram_id, circuit.add_variable(0));
83
84 circuit.create_big_add_gate({
85 val_idx_1,
86 val_idx_2,
87 val_idx_3,
88 circuit.zero_idx(),
89 1,
90 1,
91 1,
92 0,
93 -35,
94 });
95 }
96
97 protected:
99};
100
101class AcirIntegrationSingleTest : public AcirIntegrationTest, public testing::WithParamInterface<std::string> {};
102
103class AcirIntegrationFoldingTest : public AcirIntegrationTest, public testing::WithParamInterface<std::string> {
104 protected:
106};
107
108TEST_P(AcirIntegrationSingleTest, DISABLED_ProveAndVerifyProgram)
109{
110 using Flavor = UltraFlavor;
112
113 std::string test_name = GetParam();
114 info("Test: ", test_name);
115 acir_format::AcirProgram acir_program = get_program_data_from_test_file(test_name);
116
117 // Construct a bberg circuit from the acir representation
118 Builder builder = acir_format::create_circuit<Builder>(acir_program);
119
120 // Construct and verify Honk proof
121 EXPECT_TRUE(prove_and_verify_honk<Flavor>(builder));
122}
123
124// TODO(https://github.com/AztecProtocol/barretenberg/issues/994): Run all tests
127 testing::Values("a_1327_concrete_in_generic",
128 "a_1_mul",
129 "a_2_div",
130 "a_3_add",
131 "a_4_sub",
132 "a_5_over",
133 "a_6",
134 "a_6_array",
135 "a_7",
136 "a_7_function",
137 "aes128_encrypt",
138 "arithmetic_binary_operations",
139 "array_dynamic",
140 "array_dynamic_blackbox_input",
141 "array_dynamic_main_output",
142 "array_dynamic_nested_blackbox_input",
143 "array_eq",
144 "array_if_cond_simple",
145 "array_len",
146 "array_neq",
147 "array_sort",
148 "array_to_slice",
149 "array_to_slice_constant_length",
150 "assert",
151 "assert_statement",
152 "assign_ex",
153 "bigint",
154 "bit_and",
155 "bit_not",
156 "bit_shifts_comptime",
157 "bit_shifts_runtime",
158 "blake3",
159 "bool_not",
160 "bool_or",
161 "break_and_continue",
162 "brillig_acir_as_brillig",
163 "brillig_array_eq",
164 "brillig_array_to_slice",
165 "brillig_arrays",
166 "brillig_assert",
167 "brillig_bit_shifts_runtime",
168 "brillig_blake2s",
169 "brillig_blake3",
170 "brillig_calls",
171 "brillig_calls_array",
172 "brillig_calls_conditionals",
173 "brillig_conditional",
174 "brillig_cow",
175 "brillig_cow_assign",
176 "brillig_cow_regression",
177 "brillig_ecdsa_secp256k1",
178 "brillig_ecdsa_secp256r1",
179 "brillig_embedded_curve",
180 "brillig_fns_as_values",
181 "brillig_hash_to_field",
182 "brillig_identity_function",
183 "brillig_keccak",
184 "brillig_loop",
185 "brillig_nested_arrays",
186 "brillig_not",
187 "brillig_oracle",
188 "brillig_pedersen",
189 "brillig_recursion",
190 "brillig_references",
191 "brillig_schnorr",
192 "brillig_sha256",
193 "brillig_signed_cmp",
194 "brillig_signed_div",
195 "brillig_slices",
196 "brillig_to_be_bytes",
197 "brillig_to_bits",
198 "brillig_to_bytes_integration",
199 "brillig_to_le_bytes",
200 "brillig_top_level",
201 "brillig_uninitialized_arrays",
202 "brillig_wrapping",
203 "cast_bool",
204 "closures_mut_ref",
205 "conditional_1",
206 "conditional_2",
207 "conditional_regression_421",
208 "conditional_regression_547",
209 "conditional_regression_661",
210 "conditional_regression_short_circuit",
211 "conditional_regression_underflow",
212 "custom_entry",
213 "databus",
214 "debug_logs",
215 "diamond_deps_0",
216 "double_verify_nested_proof",
217 "double_verify_proof",
218 "ecdsa_secp256k1",
219 "ecdsa_secp256r1",
220 "ecdsa_secp256r1_3x",
221 "eddsa",
222 "embedded_curve_ops",
223 "field_attribute",
224 "generics",
225 "global_consts",
226 "hash_to_field",
227 "hashmap",
228 "higher_order_functions",
229 "if_else_chain",
230 "import",
231 "inline_never_basic",
232 "integer_array_indexing",
233 "keccak256",
234 "main_bool_arg",
235 "main_return",
236 "merkle_insert",
237 "missing_closure_env",
238 "modules",
239 "modules_more",
240 "modulus",
241 "nested_array_dynamic",
242 "nested_array_dynamic_simple",
243 "nested_array_in_slice",
244 "nested_arrays_from_brillig",
245 "no_predicates_basic",
246 "no_predicates_brillig",
247 "no_predicates_numeric_generic_poseidon",
248 "operator_overloading",
249 "pedersen_check",
250 "pedersen_commitment",
251 "pedersen_hash",
252 "poseidon_bn254_hash",
253 "poseidonsponge_x5_254",
254 "pred_eq",
255 "prelude",
256 "references",
257 "regression",
258 "regression_2660",
259 "regression_3051",
260 "regression_3394",
261 "regression_3607",
262 "regression_3889",
263 "regression_4088",
264 "regression_4124",
265 "regression_4202",
266 "regression_4449",
267 "regression_4709",
268 "regression_5045",
269 "regression_capacity_tracker",
270 "regression_mem_op_predicate",
271 "regression_method_cannot_be_found",
272 "regression_struct_array_conditional",
273 "schnorr",
274 "sha256",
275 "sha2_byte",
276 "side_effects_constrain_array",
277 "signed_arithmetic",
278 "signed_comparison",
279 "signed_division",
280 "simple_2d_array",
281 "simple_add_and_ret_arr",
282 "simple_array_param",
283 "simple_bitwise",
284 "simple_comparison",
285 "simple_mut",
286 "simple_not",
287 "simple_print",
288 "simple_program_addition",
289 "simple_radix",
290 "simple_shield",
291 "simple_shift_left_right",
292 "slice_coercion",
293 "slice_dynamic_index",
294 "slice_loop",
295 "slices",
296 "strings",
297 "struct",
298 "struct_array_inputs",
299 "struct_fields_ordering",
300 "struct_inputs",
301 "submodules",
302 "to_be_bytes",
303 "to_bytes_consistent",
304 "to_bytes_integration",
305 "to_le_bytes",
306 "trait_as_return_type",
307 "trait_impl_base_type",
308 "traits_in_crates_1",
309 "traits_in_crates_2",
310 "tuple_inputs",
311 "tuples",
312 "type_aliases",
313 "u128",
314 "u16_support",
315 "unconstrained_empty",
316 "unit_value",
317 "unsafe_range_constraint",
318 "witness_compression",
319 // "workspace",
320 // "workspace_default_member",
321 "xor"));
322
323TEST_P(AcirIntegrationFoldingTest, DISABLED_ProveAndVerifyProgramStack)
324{
325 using Flavor = MegaFlavor;
327
328 std::string test_name = GetParam();
329 info("Test: ", test_name);
330
331 auto program_stack = get_program_stack_data_from_test_file(test_name);
332
333 while (!program_stack.empty()) {
334 auto program = program_stack.back();
335
336 // Construct a bberg circuit from the acir representation
337 auto builder = acir_format::create_circuit<Builder>(program);
338
339 // Construct and verify Honk proof for the individidual circuit
340 EXPECT_TRUE(prove_and_verify_honk<Flavor>(builder));
341
342 program_stack.pop_back();
343 }
344}
345
348 testing::Values("fold_basic", "fold_basic_nested_call"));
349
354TEST_F(AcirIntegrationTest, DISABLED_Databus)
355{
356 using Flavor = MegaFlavor;
358
359 std::string test_name = "databus";
360 info("Test: ", test_name);
361 acir_format::AcirProgram acir_program = get_program_data_from_test_file(test_name);
362
363 // Construct a bberg circuit from the acir representation
364 Builder builder = acir_format::create_circuit<Builder>(acir_program);
365
366 // This prints a summary of the types of gates in the circuit
367 builder.blocks.summarize();
368
369 // Construct and verify Honk proof
370 EXPECT_TRUE(prove_and_verify_honk<Flavor>(builder));
371}
372
378TEST_F(AcirIntegrationTest, DISABLED_DatabusTwoCalldata)
379{
380 using Flavor = MegaFlavor;
382
383 std::string test_name = "databus_two_calldata";
384 info("Test: ", test_name);
385 acir_format::AcirProgram acir_program = get_program_data_from_test_file(test_name);
386
387 // Construct a bberg circuit from the acir representation
388 Builder builder = acir_format::create_circuit<Builder>(acir_program);
389
390 // Check that the databus columns in the builder have been populated as expected
391 const auto& calldata = builder.get_calldata();
392 const auto& secondary_calldata = builder.get_secondary_calldata();
393 const auto& return_data = builder.get_return_data();
394
395 ASSERT_EQ(calldata.size(), static_cast<size_t>(4));
396 ASSERT_EQ(secondary_calldata.size(), static_cast<size_t>(3));
397 ASSERT_EQ(return_data.size(), static_cast<size_t>(4));
398
399 // Check that return data was computed from the two calldata inputs as expected
400 ASSERT_EQ(builder.get_variable(calldata[0]) + builder.get_variable(secondary_calldata[0]),
401 builder.get_variable(return_data[0]));
402 ASSERT_EQ(builder.get_variable(calldata[1]) + builder.get_variable(secondary_calldata[1]),
403 builder.get_variable(return_data[1]));
404 ASSERT_EQ(builder.get_variable(calldata[2]) + builder.get_variable(secondary_calldata[2]),
405 builder.get_variable(return_data[2]));
406 ASSERT_EQ(builder.get_variable(calldata[3]), builder.get_variable(return_data[3]));
407
408 // Ensure that every index of each bus column was read once as expected
409 for (size_t idx = 0; idx < calldata.size(); ++idx) {
410 ASSERT_EQ(calldata.get_read_count(idx), 1);
411 }
412 for (size_t idx = 0; idx < secondary_calldata.size(); ++idx) {
413 ASSERT_EQ(secondary_calldata.get_read_count(idx), 1);
414 }
415 for (size_t idx = 0; idx < return_data.size(); ++idx) {
416 ASSERT_EQ(return_data.get_read_count(idx), 1);
417 }
418
419 // This prints a summary of the types of gates in the circuit
420 builder.blocks.summarize();
421
422 // Construct and verify Honk proof
423 EXPECT_TRUE(prove_and_verify_honk<Flavor>(builder));
424}
425
431TEST_F(AcirIntegrationTest, DISABLED_UpdateAcirCircuit)
432{
433 using Flavor = MegaFlavor;
435
436 std::string test_name = "6_array"; // arbitrary program with RAM gates
437 auto acir_program = get_program_data_from_test_file(test_name);
438
439 // Construct a bberg circuit from the acir representation
440 Builder circuit = acir_format::create_circuit<Builder>(acir_program);
441
442 EXPECT_TRUE(CircuitChecker::check(circuit));
443
444 // Now append some RAM gates onto the circuit generated from acir and confirm that its still valid. (First, check
445 // that the RAM operations constitute a valid independent circuit).
446 {
447 Builder circuit;
448 add_some_simple_RAM_gates(circuit);
449 EXPECT_TRUE(CircuitChecker::check(circuit));
450 EXPECT_TRUE(prove_and_verify_honk<Flavor>(circuit));
451 }
452
453 // Now manually append the simple RAM circuit to the circuit generated from acir
454 add_some_simple_RAM_gates(circuit);
455
456 // Confirm that the result is still valid
457 EXPECT_TRUE(CircuitChecker::check(circuit));
458 EXPECT_TRUE(prove_and_verify_honk<Flavor>(circuit));
459}
460
465TEST_F(AcirIntegrationTest, DISABLED_HonkRecursion)
466{
467 using Flavor = UltraFlavor;
469
470 std::string test_name = "verify_honk_proof"; // program that recursively verifies a honk proof
471 auto acir_program = get_program_data_from_test_file(test_name);
472
473 // Construct a bberg circuit from the acir representation
474 Builder circuit = acir_format::create_circuit<Builder>(acir_program);
475
476 EXPECT_TRUE(CircuitChecker::check(circuit));
477 EXPECT_TRUE(prove_and_verify_honk<Flavor>(circuit));
478}
479
484TEST_F(AcirIntegrationTest, DISABLED_ClientIVCMsgpackInputs)
485{
486 // NOTE: to populate the test inputs at this location, run the following commands:
487 // export AZTEC_CACHE_COMMIT=origin/master~3
488 // export FORCE_CACHE_DOWNLOAD=1
489 // yarn-project/end-to-end/bootstrap.sh build_bench
490 std::string input_path = "../../../yarn-project/end-to-end/example-app-ivc-inputs-out/"
491 "ecdsar1+transfer_0_recursions+sponsored_fpc/ivc-inputs.msgpack";
492
495
497 ClientIVC::Proof proof = ivc->prove();
498
499 EXPECT_TRUE(ivc->verify(proof, ivc->get_vk()));
500}
501
506TEST_F(AcirIntegrationTest, DISABLED_DummyWitnessVkConsistency)
507{
508 std::string input_path = "../../../yarn-project/end-to-end/example-app-ivc-inputs-out/"
509 "ecdsar1+transfer_0_recursions+sponsored_fpc/ivc-inputs.msgpack";
510
513
514 uint256_t recomputed_vk_hash{ 0 };
515 uint256_t computed_vk_hash{ 0 };
516
517 TraceSettings trace_settings{ AZTEC_TRACE_STRUCTURE };
518
519 for (auto [program_in, precomputed_vk, function_name] :
521
522 // Compute the VK using the program constraints but no witness (i.e. mimic the "dummy witness" case)
523 {
524 auto program = program_in;
525 program.witness = {}; // erase the witness to mimmic the "dummy witness" case
526 auto& ivc_constraints = program.constraints.pg_recursion_constraints;
527 const acir_format::ProgramMetadata metadata{
528 .ivc = ivc_constraints.empty() ? nullptr
529 : create_mock_ivc_from_constraints(ivc_constraints, trace_settings)
530 };
531
532 auto circuit = acir_format::create_circuit<MegaCircuitBuilder>(program, metadata);
533 recomputed_vk_hash = prover_instance_inspector::compute_vk_hash<MegaFlavor>(circuit);
534 }
535
536 // Compute the verification key using the genuine witness
537 {
538 auto program = program_in;
539 auto& ivc_constraints = program.constraints.pg_recursion_constraints;
540 const acir_format::ProgramMetadata metadata{
541 .ivc = ivc_constraints.empty() ? nullptr
542 : create_mock_ivc_from_constraints(ivc_constraints, trace_settings)
543 };
544
545 auto circuit = acir_format::create_circuit<MegaCircuitBuilder>(program, metadata);
546 computed_vk_hash = prover_instance_inspector::compute_vk_hash<MegaFlavor>(circuit);
547 }
548
549 // Check that the hashes computed from the dummy witness VK and the genuine witness VK are equal
550 EXPECT_EQ(recomputed_vk_hash, computed_vk_hash);
551 // Check that the VK hashes match the hash of the precomputed VK contained in the msgpack inputs
552 EXPECT_EQ(computed_vk_hash, precomputed_vk->hash());
553 }
554}
555#endif
INSTANTIATE_TEST_SUITE_P(AcirTests, AcirIntegrationSingleTest, testing::Values("a_1327_concrete_in_generic", "a_1_mul", "a_2_div", "a_3_add", "a_4_sub", "a_5_over", "a_6", "a_6_array", "a_7", "a_7_function", "aes128_encrypt", "arithmetic_binary_operations", "array_dynamic", "array_dynamic_blackbox_input", "array_dynamic_main_output", "array_dynamic_nested_blackbox_input", "array_eq", "array_if_cond_simple", "array_len", "array_neq", "array_sort", "array_to_slice", "array_to_slice_constant_length", "assert", "assert_statement", "assign_ex", "bigint", "bit_and", "bit_not", "bit_shifts_comptime", "bit_shifts_runtime", "blake3", "bool_not", "bool_or", "break_and_continue", "brillig_acir_as_brillig", "brillig_array_eq", "brillig_array_to_slice", "brillig_arrays", "brillig_assert", "brillig_bit_shifts_runtime", "brillig_blake2s", "brillig_blake3", "brillig_calls", "brillig_calls_array", "brillig_calls_conditionals", "brillig_conditional", "brillig_cow", "brillig_cow_assign", "brillig_cow_regression", "brillig_ecdsa_secp256k1", "brillig_ecdsa_secp256r1", "brillig_embedded_curve", "brillig_fns_as_values", "brillig_hash_to_field", "brillig_identity_function", "brillig_keccak", "brillig_loop", "brillig_nested_arrays", "brillig_not", "brillig_oracle", "brillig_pedersen", "brillig_recursion", "brillig_references", "brillig_schnorr", "brillig_sha256", "brillig_signed_cmp", "brillig_signed_div", "brillig_slices", "brillig_to_be_bytes", "brillig_to_bits", "brillig_to_bytes_integration", "brillig_to_le_bytes", "brillig_top_level", "brillig_uninitialized_arrays", "brillig_wrapping", "cast_bool", "closures_mut_ref", "conditional_1", "conditional_2", "conditional_regression_421", "conditional_regression_547", "conditional_regression_661", "conditional_regression_short_circuit", "conditional_regression_underflow", "custom_entry", "databus", "debug_logs", "diamond_deps_0", "double_verify_nested_proof", "double_verify_proof", "ecdsa_secp256k1", "ecdsa_secp256r1", "ecdsa_secp256r1_3x", "eddsa", "embedded_curve_ops", "field_attribute", "generics", "global_consts", "hash_to_field", "hashmap", "higher_order_functions", "if_else_chain", "import", "inline_never_basic", "integer_array_indexing", "keccak256", "main_bool_arg", "main_return", "merkle_insert", "missing_closure_env", "modules", "modules_more", "modulus", "nested_array_dynamic", "nested_array_dynamic_simple", "nested_array_in_slice", "nested_arrays_from_brillig", "no_predicates_basic", "no_predicates_brillig", "no_predicates_numeric_generic_poseidon", "operator_overloading", "pedersen_check", "pedersen_commitment", "pedersen_hash", "poseidon_bn254_hash", "poseidonsponge_x5_254", "pred_eq", "prelude", "references", "regression", "regression_2660", "regression_3051", "regression_3394", "regression_3607", "regression_3889", "regression_4088", "regression_4124", "regression_4202", "regression_4449", "regression_4709", "regression_5045", "regression_capacity_tracker", "regression_mem_op_predicate", "regression_method_cannot_be_found", "regression_struct_array_conditional", "schnorr", "sha256", "sha2_byte", "side_effects_constrain_array", "signed_arithmetic", "signed_comparison", "signed_division", "simple_2d_array", "simple_add_and_ret_arr", "simple_array_param", "simple_bitwise", "simple_comparison", "simple_mut", "simple_not", "simple_print", "simple_program_addition", "simple_radix", "simple_shield", "simple_shift_left_right", "slice_coercion", "slice_dynamic_index", "slice_loop", "slices", "strings", "struct", "struct_array_inputs", "struct_fields_ordering", "struct_inputs", "submodules", "to_be_bytes", "to_bytes_consistent", "to_bytes_integration", "to_le_bytes", "trait_as_return_type", "trait_impl_base_type", "traits_in_crates_1", "traits_in_crates_2", "tuple_inputs", "tuples", "type_aliases", "u128", "u16_support", "unconstrained_empty", "unit_value", "unsafe_range_constraint", "witness_compression", "xor"))
TEST_P(AcirIntegrationSingleTest, DISABLED_ProveAndVerifyProgram)
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:88
static acir_format::AcirProgramStack get_program_stack_data_from_test_file(const std::string &test_program_name)
static bool file_exists(const std::string &path)
bool prove_and_verify_honk(Flavor::CircuitBuilder &builder)
void add_some_simple_RAM_gates(auto &circuit)
static acir_format::AcirProgram get_program_data_from_test_file(const std::string &test_program_name)
The verification key is responsible for storing the commitments to the precomputed (non-witness) poly...
MegaCircuitBuilder CircuitBuilder
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
void info(Args... args)
Definition log.hpp:74
AluTraceBuilder builder
Definition alu.test.cpp:123
UltraKeccakFlavor::VerificationKey VerificationKey
AcirProgramStack get_acir_program_stack(std::string const &bytecode_path, std::string const &witness_path)
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
Entry point for Barretenberg command-line interface.
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:188
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::vector< FF > calldata
Storage for constaint_systems/witnesses for a stack of acir programs.
std::shared_ptr< bb::IVCBase > ivc
A full proof for the IVC scheme containing a Mega proof showing correctness of the hiding circuit (wh...
static std::vector< PrivateExecutionStepRaw > load_and_decompress(const std::filesystem::path &input_path)
std::vector< std::shared_ptr< ClientIVC::MegaVerificationKey > > precomputed_vks
std::shared_ptr< ClientIVC > accumulate()
void parse(std::vector< PrivateExecutionStepRaw > &&steps)
std::vector< acir_format::AcirProgram > folding_stack
std::vector< std::string > function_names