-
Notifications
You must be signed in to change notification settings - Fork 614
fix: smt_verification: negative bitvecs, changed gates indicies. acir_formal_proofs: noir-style signed division #11649
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
Changes from 10 commits
711e138
55b1bfe
f2ed1bb
691f4a6
a33a3de
6be0d4c
b7076d5
e9646d8
53387ac
fc4163f
cfabdea
536af25
ee568cb
3f0a4b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -89,4 +89,87 @@ TEST(helpers, pow2) | |
| info("z = ", vals["z"]); | ||
| // z == 2048 in binary | ||
| EXPECT_TRUE(vals["z"] == "00000000000000000000100000000000"); | ||
| } | ||
|
|
||
|
Sarkoxed marked this conversation as resolved.
|
||
| TEST(helpers, signed_div) | ||
| { | ||
| Solver s("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", default_solver_config, 16, 32); | ||
|
|
||
| STerm x = BVVar("x", &s); | ||
| STerm y = BVVar("y", &s); | ||
| STerm z = idiv(x, y, 2, &s); | ||
| // 00 == 0 | ||
| x == 0; | ||
| // 11 == -1 | ||
| y == 3; | ||
| s.check(); | ||
| std::unordered_map<std::string, cvc5::Term> terms({ { "x", x }, { "y", y }, { "z", z } }); | ||
| std::unordered_map<std::string, std::string> vals = s.model(terms); | ||
| info("x = ", vals["x"]); | ||
| info("y = ", vals["y"]); | ||
| info("z = ", vals["z"]); | ||
| EXPECT_TRUE(vals["z"] == "00000000000000000000000000000000"); | ||
| } | ||
|
|
||
| TEST(helpers, signed_div_1) | ||
| { | ||
| // using smt solver i found that 1879048194 >> 16 == 0 | ||
| // its strange... | ||
| Solver s("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", default_solver_config, 16, 32); | ||
|
|
||
| STerm x = BVVar("x", &s); | ||
| STerm y = BVVar("y", &s); | ||
| STerm z = idiv(x, y, 2, &s); | ||
| // 01 == 1 | ||
| x == 1; | ||
| // 11 == -1 | ||
| y == 3; | ||
| s.check(); | ||
| std::unordered_map<std::string, cvc5::Term> terms({ { "x", x }, { "y", y }, { "z", z } }); | ||
| std::unordered_map<std::string, std::string> vals = s.model(terms); | ||
| info("x = ", vals["x"]); | ||
| info("y = ", vals["y"]); | ||
| info("z = ", vals["z"]); | ||
| EXPECT_TRUE(vals["z"] == "00000000000000000000000000000011"); | ||
| } | ||
|
|
||
| TEST(helpers, signed_div_2) | ||
| { | ||
| // using smt solver i found that 1879048194 >> 16 == 0 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you find out why?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it was bug in my implementation |
||
| // its strange... | ||
| Solver s("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", default_solver_config, 16, 32); | ||
|
|
||
| STerm x = BVVar("x", &s); | ||
| STerm y = BVVar("y", &s); | ||
| STerm z = idiv(x, y, 4, &s); | ||
| // 0111 == 7 | ||
| x == 7; | ||
| // 0010 == 2 | ||
| y == 2; | ||
| s.check(); | ||
| std::unordered_map<std::string, cvc5::Term> terms({ { "x", x }, { "y", y }, { "z", z } }); | ||
| std::unordered_map<std::string, std::string> vals = s.model(terms); | ||
| info("x = ", vals["x"]); | ||
| info("y = ", vals["y"]); | ||
| info("z = ", vals["z"]); | ||
| EXPECT_TRUE(vals["z"] == "00000000000000000000000000000011"); | ||
| } | ||
|
|
||
| TEST(helpers, shl_overflow) | ||
| { | ||
| Solver s("30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", default_solver_config, 16, 32); | ||
|
|
||
| STerm x = BVVar("x", &s); | ||
| STerm y = BVVar("y", &s); | ||
| STerm z = shl32(x, y, &s); | ||
| x == 1; | ||
| y == 50; | ||
| s.check(); | ||
| std::unordered_map<std::string, cvc5::Term> terms({ { "x", x }, { "y", y }, { "z", z } }); | ||
| std::unordered_map<std::string, std::string> vals = s.model(terms); | ||
| info("x = ", vals["x"]); | ||
| info("y = ", vals["y"]); | ||
| info("z = ", vals["z"]); | ||
| // z == 1010 in binary | ||
| EXPECT_TRUE(vals["z"] == "00000000000000000000000000000000"); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,18 +30,18 @@ UltraCircuit::UltraCircuit( | |
| // add gate in its normal state to solver | ||
|
|
||
| size_t arith_cursor = 0; | ||
| while (arith_cursor < this->selectors[1].size()) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add an entry to |
||
| arith_cursor = this->handle_arithmetic_relation(arith_cursor, 1); | ||
| while (arith_cursor < this->selectors[2].size()) { | ||
| arith_cursor = this->handle_arithmetic_relation(arith_cursor, 2); | ||
| } | ||
|
|
||
| size_t lookup_cursor = 0; | ||
| while (lookup_cursor < this->selectors[5].size()) { | ||
| lookup_cursor = this->handle_lookup_relation(lookup_cursor, 5); | ||
| while (lookup_cursor < this->selectors[1].size()) { | ||
| lookup_cursor = this->handle_lookup_relation(lookup_cursor, 1); | ||
| } | ||
|
|
||
| size_t elliptic_cursor = 0; | ||
| while (elliptic_cursor < this->selectors[3].size()) { | ||
| elliptic_cursor = this->handle_elliptic_relation(elliptic_cursor, 3); | ||
| while (elliptic_cursor < this->selectors[4].size()) { | ||
| elliptic_cursor = this->handle_elliptic_relation(elliptic_cursor, 4); | ||
| } | ||
|
|
||
| // size_t delta_range_cursor = 0; | ||
|
|
@@ -88,7 +88,7 @@ size_t UltraCircuit::handle_arithmetic_relation(size_t cursor, size_t idx) | |
|
|
||
| std::vector<bb::fr> boolean_gate = { 1, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0 }; | ||
| bool boolean_gate_flag = | ||
| (boolean_gate == selectors[1][cursor]) && (w_l_idx == w_r_idx) && (w_o_idx == 0) && (w_4_idx == 0); | ||
| (boolean_gate == selectors[idx][cursor]) && (w_l_idx == w_r_idx) && (w_o_idx == 0) && (w_4_idx == 0); | ||
| if (boolean_gate_flag) { | ||
| (Bool(w_l) == Bool(STerm(0, this->solver, this->type)) | Bool(w_l) == Bool(STerm(1, this->solver, this->type))) | ||
| .assert_term(); | ||
|
|
@@ -292,7 +292,7 @@ size_t UltraCircuit::handle_elliptic_relation(size_t cursor, size_t idx) | |
| y_add_identity == 0; // scaling_factor = 1 | ||
| } | ||
|
|
||
| bb::fr curve_b = this->selectors[3][cursor][11]; | ||
| bb::fr curve_b = this->selectors[idx][cursor][11]; | ||
| auto x_pow_4 = (y1_sqr - curve_b) * x_1; | ||
| auto y1_sqr_mul_4 = y1_sqr + y1_sqr; | ||
| y1_sqr_mul_4 += y1_sqr_mul_4; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -429,6 +429,35 @@ STerm STerm::rotl(const uint32_t& n) const | |
| return { res, this->solver, this->type }; | ||
| } | ||
|
|
||
| STerm STerm::truncate(const uint32_t& to_size) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please add a test and update README.md with these new methods? |
||
| { | ||
| if (!this->operations.contains(OpType::EXTRACT) || !this->operations.contains(OpType::BITVEC_PAD)) { | ||
| info("EXTRACT is not compatible with ", this->type); | ||
| return *this; | ||
| } | ||
| cvc5::Op extraction = solver->term_manager.mkOp(this->operations.at(OpType::EXTRACT), { to_size, 0 }); | ||
| cvc5::Term temp = solver->term_manager.mkTerm(extraction, { this->term }); | ||
| cvc5::Op padding = | ||
| solver->term_manager.mkOp(this->operations.at(OpType::BITVEC_PAD), | ||
| { this->solver->bv_sort.getBitVectorSize() - temp.getSort().getBitVectorSize() }); | ||
| cvc5::Term res = solver->term_manager.mkTerm(padding, { temp }); | ||
| return { res, this->solver, this->type }; | ||
| } | ||
|
|
||
| STerm STerm::extract_bit(const uint32_t& bit_index) | ||
| { | ||
| if (!this->operations.contains(OpType::EXTRACT) || !this->operations.contains(OpType::BITVEC_PAD)) { | ||
| info("EXTRACT is not compatible with ", this->type); | ||
| return *this; | ||
| } | ||
| cvc5::Op extraction = solver->term_manager.mkOp(this->operations.at(OpType::EXTRACT), { bit_index, bit_index }); | ||
| cvc5::Term temp = solver->term_manager.mkTerm(extraction, { this->term }); | ||
| cvc5::Op padding = | ||
| solver->term_manager.mkOp(this->operations.at(OpType::BITVEC_PAD), | ||
| { this->solver->bv_sort.getBitVectorSize() - temp.getSort().getBitVectorSize() }); | ||
| cvc5::Term res = solver->term_manager.mkTerm(padding, { temp }); | ||
| return { res, this->solver, this->type }; | ||
| } | ||
| /** | ||
| * @brief Create an inclusion constraint | ||
| * | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the
pow2_8, you should use bit_extraction rather then direct& 1value