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