-
Notifications
You must be signed in to change notification settings - Fork 615
feat: Acir formal proofs #10973
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
Merged
Merged
feat: Acir formal proofs #10973
Changes from 28 commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
a837887
IT FINALLY WORKS :D
defkit 5750f4c
i forgot cmakelists
defkit cc71c30
save artifacts
defkit a791e76
stable version for verifying
defkit 56559cf
dummy
defkit c364e63
IT FINALLY WORKS :D
defkit 579c5ff
i forgot cmakelists
defkit be6ef36
save artifacts
defkit 6b27d0e
stable version for verifying
defkit 84319b2
dummy
defkit 28cd1f9
smol refactor
defkit 8ea00fc
smol refactor
defkit 2ff5084
smol refactor
defkit 58c1268
forgot to resolve merge conflicts
defkit e1a6541
i forgor to resolve conflicts in cargolock...
7dd7e98
hmm
defkit d58a19a
smol refactor
defkit 4f07105
ples have a patient i have problems
defkit e33a29f
verif changes
defkit 802b0cd
smol shifts
defkit d7dd95d
deleted codegen + shl + shr
defkit 2cf19f0
bug in acir builder
defkit 10b361f
recaftor
defkit 3cc7f44
docs + small refactor
defkit 884b2aa
readme mistake, artifacts dirs
defkit ef9c730
restore cmake list
defkit 208f9ce
bug in verify_mod
defkit 97bfad1
still bug in verify_mod
defkit 1c90845
deleted gitignores + table + shl64 bug + directory flag for binary
defkit 442e387
readme mistake, deleted all noir stuff
defkit 29ed080
broken table
defkit f32a27e
last readme fix
defkit d9d77f5
Merge branch 'master' into sa/acir_formal_proofs
defkit d800214
Merge branch 'master' of https://github.com/AztecProtocol/aztec-packa…
defkit 9dd4709
ACIR_FORMAL_PROOFS flag for cmake
defkit File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
1 change: 1 addition & 0 deletions
1
barretenberg/cpp/src/barretenberg/acir_formal_proofs/CMakeLists.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| barretenberg_module(acir_formal_proofs dsl circuit_checker smt_verification common) |
50 changes: 50 additions & 0 deletions
50
barretenberg/cpp/src/barretenberg/acir_formal_proofs/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| # Formal Verification of ACIR Instructions | ||
|
|
||
| This module provides formal verification capabilities for ACIR (Arithmetic Circuit Intermediate Representation) instructions generated from Noir SSA code. | ||
|
|
||
| ## Overview | ||
|
|
||
| The verifier uses SMT (Satisfiability Modulo Theories) solving to formally verify the correctness of ACIR instructions. It supports verification of: | ||
|
|
||
| - Arithmetic operations (add, subtract, multiply, divide) | ||
| - Bitwise operations (AND, OR, XOR, NOT) | ||
| - Shifts (left shift, right shift) | ||
| - Comparisons (equality, less than, greater than) | ||
| - Field arithmetic | ||
|
|
||
| ## Tests | ||
|
|
||
| ⚠️ **WARNING**: Do not run these tests on a local machine without sufficient memory (>32GB RAM). The tests can consume large amounts of memory and CPU resources. Some tests like integer division can run for multiple days. It is recommended to run these tests in a controlled environment with adequate resources. | ||
| The test suite verifies correctness of ACIR operations through SMT solving: | ||
|
|
||
| ### Arithmetic Tests | ||
|
|
||
| - `uint_terms_add`: Tests 127-bit unsigned addition. Execution time: ~2.8s | ||
| - `uint_terms_sub`: Tests 127-bit unsigned subtraction. Execution time: ~2.6s | ||
| - `uint_terms_mul`: Tests 127-bit unsigned multiplication. Execution time: ~10.0s | ||
| - `uint_terms_div`: Tests 126-bit unsigned division | ||
| - `integer_terms_div`: Tests 126-bit signed division. Execution time: >10 days | ||
| - `field_terms_div`: Tests field division. Execution time: ~0.22s | ||
| - `uint_terms_mod`: Tests 126-bit unsigned modulo. Execution time: ???. Unknown time due to bug found during reviewing. | ||
|
|
||
| ### Bitwise Tests | ||
|
|
||
| - `uint_terms_and`: Tests 127-bit unsigned bitwise AND DOESNT WORK\* | ||
| - `uint_terms_or`: Tests 127-bit unsigned bitwise OR DOESNT WORK\* | ||
| - `uint_terms_xor`: Tests 127-bit unsigned bitwise XOR DOESNT WORK\* | ||
| - `uint_terms_not`: Tests 127-bit unsigned bitwise NOT | ||
|
|
||
| ### Shift Tests | ||
|
|
||
| - `uint_terms_shl32`: Tests 32-bit left shift. Execution time: ~4574s, Memory: ~30GB | ||
| - `uint_terms_shl64`: Tests 64-bit left shift. Execution time: ~4588s, Memory: ~30GB | ||
| - `uint_terms_shr`: Tests right shift. Execution time: ~3927.88s, Memory: ~10GB | ||
|
|
||
| ### Comparison Tests | ||
|
|
||
| - `uint_terms_eq`: Tests 127-bit unsigned equality comparison. Verifies both equal and unequal cases. Execution time: ~22.8s | ||
| - `uint_terms_lt`: Tests 127-bit unsigned less than comparison. Verifies both a < b and a >= b cases. Execution time: ~56.7s | ||
|
|
||
| Each test attempts to find counterexamples that violate the expected behavior. A passing test indicates the operation is correctly implemented, while a failing test reveals potential issues. | ||
|
|
||
| \*Note: The bitwise tests are not working yet. (probably because of bug in the SMT solver). It works only for variables with 32 bits. |
69 changes: 69 additions & 0 deletions
69
barretenberg/cpp/src/barretenberg/acir_formal_proofs/acir_loader.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| #include "acir_loader.hpp" | ||
| #include "barretenberg/dsl/acir_format/acir_format.hpp" | ||
| #include "barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp" | ||
| #include "barretenberg/smt_verification/circuit/ultra_circuit.hpp" | ||
| #include "barretenberg/smt_verification/terms/term.hpp" | ||
| #include "msgpack/v3/sbuffer_decl.hpp" | ||
| #include <fstream> | ||
| #include <string> | ||
| #include <vector> | ||
|
|
||
| std::vector<uint8_t> readFile(std::string filename) | ||
| { | ||
| std::ifstream file(filename, std::ios::binary); | ||
| file.unsetf(std::ios::skipws); | ||
|
|
||
| std::streampos fileSize; | ||
|
|
||
| file.seekg(0, std::ios::end); | ||
| fileSize = file.tellg(); | ||
| file.seekg(0, std::ios::beg); | ||
|
|
||
| std::vector<uint8_t> vec; | ||
|
|
||
| vec.insert(vec.begin(), std::istream_iterator<uint8_t>(file), std::istream_iterator<uint8_t>()); | ||
| file.close(); | ||
| return vec; | ||
| } | ||
|
|
||
| AcirToSmtLoader::AcirToSmtLoader(std::string filename) | ||
| { | ||
| this->acir_program_buf = readFile(filename); | ||
| this->instruction_name = filename; | ||
| this->constraint_system = acir_format::program_buf_to_acir_format(this->acir_program_buf, false).at(0); | ||
| this->circuit_buf = this->get_circuit_builder().export_circuit(); | ||
| } | ||
|
|
||
| bb::UltraCircuitBuilder AcirToSmtLoader::get_circuit_builder() | ||
| { | ||
| bb::UltraCircuitBuilder builder = acir_format::create_circuit(this->constraint_system, false); | ||
| builder.set_variable_name(0, "a"); | ||
| builder.set_variable_name(1, "b"); | ||
| builder.set_variable_name(2, "c"); | ||
| return builder; | ||
| } | ||
|
|
||
| smt_solver::Solver AcirToSmtLoader::get_smt_solver() | ||
| { | ||
| smt_circuit::CircuitSchema circuit_info = smt_circuit_schema::unpack_from_buffer(this->circuit_buf); | ||
| // for shl i have variable with bit length 197... for some reason | ||
| return smt_solver::Solver(circuit_info.modulus, smt_circuit::default_solver_config, 16, 240); | ||
| } | ||
|
|
||
| smt_circuit::UltraCircuit AcirToSmtLoader::get_bitvec_smt_circuit(smt_solver::Solver* solver) | ||
| { | ||
| smt_circuit::CircuitSchema circuit_info = smt_circuit_schema::unpack_from_buffer(this->circuit_buf); | ||
| return smt_circuit::UltraCircuit(circuit_info, solver, smt_terms::TermType::BVTerm); | ||
| } | ||
|
|
||
| smt_circuit::UltraCircuit AcirToSmtLoader::get_field_smt_circuit(smt_solver::Solver* solver) | ||
| { | ||
| smt_circuit::CircuitSchema circuit_info = smt_circuit_schema::unpack_from_buffer(this->circuit_buf); | ||
| return smt_circuit::UltraCircuit(circuit_info, solver, smt_terms::TermType::FFTerm); | ||
| } | ||
|
|
||
| smt_circuit::UltraCircuit AcirToSmtLoader::get_integer_smt_circuit(smt_solver::Solver* solver) | ||
| { | ||
| smt_circuit::CircuitSchema circuit_info = smt_circuit_schema::unpack_from_buffer(this->circuit_buf); | ||
| return smt_circuit::UltraCircuit(circuit_info, solver, smt_terms::TermType::ITerm); | ||
| } | ||
96 changes: 96 additions & 0 deletions
96
barretenberg/cpp/src/barretenberg/acir_formal_proofs/acir_loader.hpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| #pragma once | ||
| #include "barretenberg/dsl/acir_format/acir_format.hpp" | ||
| #include "barretenberg/smt_verification/circuit/ultra_circuit.hpp" | ||
| #include "msgpack/v3/sbuffer_decl.hpp" | ||
| #include <cstdint> | ||
| #include <string> | ||
| #include <vector> | ||
|
|
||
| /** | ||
| * @brief Class for loading ACIR (Arithmetic Circuit Intermediate Representation) programs and converting them to SMT | ||
| * format | ||
| * | ||
| * This class handles loading ACIR programs from files and provides functionality to: | ||
| * - Convert the ACIR program to various SMT circuit representations | ||
| * - Access the underlying constraint systems | ||
| * - Build circuits for verification | ||
| * | ||
| * The loader reads an ACIR program file, creates constraint systems, and allows conversion | ||
| * to different SMT circuit types (bitvector, field, integer) for formal verification. | ||
| */ | ||
| class AcirToSmtLoader { | ||
| public: | ||
| // Deleted constructors/operators to prevent copying/moving | ||
| AcirToSmtLoader() = delete; | ||
| AcirToSmtLoader(const AcirToSmtLoader& other) = delete; | ||
| AcirToSmtLoader(AcirToSmtLoader&& other) = delete; | ||
| AcirToSmtLoader& operator=(const AcirToSmtLoader other) = delete; | ||
| AcirToSmtLoader&& operator=(AcirToSmtLoader&& other) = delete; | ||
|
|
||
| ~AcirToSmtLoader() = default; | ||
|
|
||
| /** | ||
| * @brief Constructs loader from an ACIR program file | ||
| * @param filename Path to the ACIR program file to load | ||
| * | ||
| * Reads the ACIR program from file, initializes the constraint system, | ||
| * and prepares the circuit buffer for later use. | ||
| */ | ||
| AcirToSmtLoader(std::string filename); | ||
|
|
||
| /** | ||
| * @brief Gets the constraint systems from the loaded ACIR program | ||
| * @return Reference to the ACIR format constraint systems | ||
| */ | ||
| acir_format::AcirFormat& get_constraint_systems() { return this->constraint_system; } | ||
|
|
||
| /** | ||
| * @brief Creates a circuit builder for the loaded program | ||
| * @return UltraCircuitBuilder instance | ||
| * | ||
| * Creates and returns a circuit builder with predefined variable names: | ||
| * - Variable 0 named "a" | ||
| * - Variable 1 named "b" | ||
| * - Variable 2 named "c" | ||
| */ | ||
| bb::UltraCircuitBuilder get_circuit_builder(); | ||
|
|
||
| /** | ||
| * @brief Gets an SMT solver instance | ||
| * @return Solver instance for SMT solving | ||
| * | ||
| * Creates a solver configured with: | ||
| * - Circuit modulus from schema | ||
| * - Default solver configuration | ||
| * - Minimum bit width of 16 | ||
| * - Maximum bit width of 240 | ||
| */ | ||
| smt_solver::Solver get_smt_solver(); | ||
|
|
||
| /** | ||
| * @brief Creates an SMT circuit for bitvector operations | ||
| * @param solver Pointer to SMT solver to use | ||
| * @return UltraCircuit configured for bitvector operations | ||
| */ | ||
| smt_circuit::UltraCircuit get_bitvec_smt_circuit(smt_solver::Solver* solver); | ||
|
|
||
| /** | ||
| * @brief Creates an SMT circuit for field operations | ||
| * @param solver Pointer to SMT solver to use | ||
| * @return UltraCircuit configured for field operations | ||
| */ | ||
| smt_circuit::UltraCircuit get_field_smt_circuit(smt_solver::Solver* solver); | ||
|
|
||
| /** | ||
| * @brief Creates an SMT circuit for integer operations | ||
| * @param solver Pointer to SMT solver to use | ||
| * @return UltraCircuit configured for integer operations | ||
| */ | ||
| smt_circuit::UltraCircuit get_integer_smt_circuit(smt_solver::Solver* solver); | ||
|
|
||
| private: | ||
| std::string instruction_name; ///< Name of the instruction/filename being processed | ||
| std::vector<uint8_t> acir_program_buf; ///< Buffer containing the raw ACIR program data read from file | ||
| acir_format::AcirFormat constraint_system; ///< The parsed constraint system from the ACIR program | ||
| msgpack::sbuffer circuit_buf; ///< Buffer for circuit serialization using MessagePack | ||
| }; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.