6#include <gtest/gtest.h>
11#pragma GCC diagnostic ignored "-Wunused-const-variable"
17template <
class Builder_>
class BoolTest :
public ::testing::Test {
34 for (
bool is_const : {
false,
true }) {
35 for (
bool value : {
false,
true }) {
36 for (
bool is_inverted : {
false,
true }) {
52 const std::function<
bool(
bool,
bool)>& expected_op)
61 size_t num_gates_start =
builder.get_num_finalized_gates_inefficient();
63 if (!
a.is_constant() && !
b.is_constant()) {
64 a.set_origin_tag(submitted_value_origin_tag);
65 b.set_origin_tag(challenge_origin_tag);
69 bool expected = expected_op(lhs.value ^ lhs.is_inverted, rhs.value ^ rhs.is_inverted);
72 <<
"Failed on " << op_name <<
" with inputs: lhs = {const=" << lhs.is_const <<
", val=" << lhs.value
73 <<
", inv=" << lhs.is_inverted <<
"}, rhs = {const=" << rhs.is_const <<
", val=" << rhs.value
74 <<
", inv=" << rhs.is_inverted <<
"}";
76 if (
a.is_constant() &&
b.is_constant()) {
80 if (!
a.is_constant() && !
b.is_constant()) {
87 size_t diff =
builder.get_num_finalized_gates_inefficient() - num_gates_start;
89 EXPECT_EQ(diff,
static_cast<size_t>(!
a.is_constant() && !
b.is_constant()));
99 size_t num_gates_start =
builder.get_num_finalized_gates_inefficient();
107 EXPECT_TRUE(num_gates_start ==
builder.get_num_finalized_gates_inefficient());
113 size_t num_gates_start =
builder.get_num_finalized_gates_inefficient();
114 const size_t witness_idx_zero =
builder.add_variable(
bb::fr(0));
115 const size_t witness_idx_one =
builder.add_variable(
bb::fr(1));
116 const size_t non_bool_witness_idx =
builder.add_variable(
bb::fr(15));
119 EXPECT_EQ(bool_witness.
get_value(),
false);
122 EXPECT_EQ(bool_witness.
get_value(),
true);
124 EXPECT_EQ(
builder.get_num_finalized_gates_inefficient() - num_gates_start, 0);
128 "bool_t: creating a witness bool from a non-boolean value");
133 size_t num_gates_start =
builder.get_num_finalized_gates_inefficient();
142 EXPECT_TRUE(
builder.get_num_finalized_gates_inefficient() - num_gates_start == 2);
149 if (random_value * random_value - random_value != 0) {
151 "((other.witness == bb::fr::one()) || (other.witness == bb::fr::zero()))");
157 const bool use_range_constraint =
true;
159 for (
size_t num_inputs = 1; num_inputs < 50; num_inputs++) {
161 size_t num_gates_start =
builder.get_num_finalized_gates_inefficient();
163 std::vector<uint32_t> indices;
164 for (
size_t idx = 0; idx < num_inputs; idx++) {
169 size_t sorted_list_size = num_inputs + 2;
171 sorted_list_size =
std::max(sorted_list_size, 8UL);
173 size_t fixed_additional_gates = 4;
175 size_t expected =
numeric::ceil_div(sorted_list_size, 4UL) + fixed_additional_gates;
177 size_t actual =
builder.get_num_finalized_gates_inefficient() - num_gates_start;
179 EXPECT_EQ(actual, expected);
181 builder.create_unconstrained_gates(indices);
189 "bool_t: witness value is not 0 or 1");
226 [](
bool a,
bool b) {
return !
a ||
b; });
234 [](
bool a,
bool b) {
return !(
a ^
b); });
247 if (
a.is_constant() &&
b.is_constant() && !(!
a.get_value() ||
b.get_value())) {
250 bool result_is_constant = (!
a ||
b).is_constant();
252 size_t num_gates_start =
builder.get_num_finalized_gates_inefficient();
254 if (!
a.is_constant() && !
b.is_constant()) {
255 a.set_origin_tag(submitted_value_origin_tag);
256 b.set_origin_tag(challenge_origin_tag);
261 bool expected = !(lhs.value ^ lhs.is_inverted) || rhs.value ^ rhs.is_inverted;
263 size_t diff =
builder.get_num_finalized_gates_inefficient() - num_gates_start;
265 if (!
a.is_constant() && !
b.is_constant()) {
270 if (result_is_constant) {
275 if (!result_is_constant &&
a.is_constant() && !
b.is_constant()) {
279 if (!result_is_constant && !
a.is_constant() &&
b.is_constant()) {
300 if (
a.is_constant() &&
b.is_constant() &&
a.get_value() ==
b.get_value()) {
303 return (
a.is_inverted()) ? 1 : 0;
310 if (!
a.is_constant() && !
b.is_constant()) {
314 }
else if (!
a.is_constant()) {
323 return b.get_value() ? 2 : 1;
324 }
else if (!
b.is_constant()) {
333 return a.get_value() ? 2 : 1;
340 }
else if (lhs.
value) {
365 size_t num_gates_start =
builder.get_num_finalized_gates_inefficient();
366 if (!
a.is_constant() && !
b.is_constant()) {
368 a.set_origin_tag(challenge_origin_tag);
369 b.set_origin_tag(next_challenge_tag);
373 size_t diff =
builder.get_num_finalized_gates_inefficient() - num_gates_start;
374 if (!
a.is_constant() && !
b.is_constant()) {
375 EXPECT_EQ(result.
get_origin_tag(), first_second_third_merged_tag);
379 bool expected = (condition.
get_value()) ?
a.get_value() :
b.get_value();
387 (
a.is_constant() &&
b.is_constant() &&
a.get_value() ==
b.get_value())) {
390 EXPECT_EQ(diff, expected_gates);
391 }
else if (!
a.is_constant() && !
b.is_constant()) {
393 EXPECT_EQ(diff, 3UL);
411 size_t num_gates_start =
builder.get_num_finalized_gates_inefficient();
412 if (!
a.is_constant()) {
413 a.set_origin_tag(submitted_value_origin_tag);
417 if (!
a.is_constant()) {
421 size_t diff =
builder.get_num_finalized_gates_inefficient() - num_gates_start;
424 EXPECT_EQ(diff,
static_cast<size_t>(!
a.is_constant() && a_raw.is_inverted));
440 bool failed =
a.get_value() !=
b.get_value();
442 if (!
a.is_constant() && !
b.is_constant()) {
445 EXPECT_EQ(
builder.failed(), failed);
446 }
else if (!
a.is_constant() || !
b.is_constant()) {
462 auto gates_before =
builder.get_num_finalized_gates_inefficient();
467 a.set_origin_tag(submitted_value_origin_tag);
468 b.set_origin_tag(challenge_origin_tag);
471 EXPECT_EQ(
a.get_value(), 1);
474 EXPECT_EQ(
a.get_origin_tag(), first_two_merged_tag);
477 EXPECT_EQ(
b.get_value(), 1);
480 EXPECT_EQ(
b.get_origin_tag(), challenge_origin_tag);
482 a.set_origin_tag(submitted_value_origin_tag);
511 EXPECT_EQ(result,
true);
513 auto gates_after =
builder.get_num_finalized_gates_inefficient();
514 EXPECT_EQ(gates_after - gates_before, 6UL);
536 bool_ct rhs = ((
a &&
b) || (
a && c)) ^ (!d || f);
542 info(
"a: ",
a.get_value(),
" b: ",
b.get_value(),
" c: ", c.
get_value());
561 TestFixture::test_construct_from_const_bool();
566 TestFixture::test_construct_from_witness();
570 TestFixture::test_construct_from_witness_range_constraint();
575 TestFixture::test_normalize();
579 TestFixture::test_xor();
584 TestFixture::test_AND();
589 TestFixture::test_OR();
594 TestFixture::test_EQ();
599 TestFixture::test_NEQ();
604 TestFixture::test_implies();
609 TestFixture::test_implies_both_ways();
614 TestFixture::test_must_imply();
619 TestFixture::test_conditional_assign();
624 TestFixture::test_basic_operations_tags();
629 TestFixture::test_simple_proof();
633 TestFixture::test_assert_equal();
#define EXPECT_THROW_OR_ABORT(statement, matcher)
void test_construct_from_witness_index()
void test_implies_both_ways()
void test_conditional_assign()
void test_binary_op(std::string const &op_name, const std::function< bool_ct(const bool_ct &, const bool_ct &)> &op, const std::function< bool(bool, bool)> &expected_op)
void test_basic_operations_tags()
void test_construct_from_const_bool()
static size_t compute_conditional_assign_gates(const bool_ct &condition, const bool_ct &a, const bool_ct &b, const BoolInput &lhs, const BoolInput &rhs)
std::array< BoolInput, 8 > all_inputs
void test_construct_from_witness_range_constraint()
stdlib::witness_t< Builder > witness_ct
void test_construct_from_witness()
static bool_ct create_bool_ct(const BoolInput &in, Builder *builder)
stdlib::bool_t< Builder > bool_ct
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
virtual uint256_t get_random_uint256()=0
Implements boolean logic in-circuit.
void set_origin_tag(const OriginTag &new_tag) const
bool_t implies(const bool_t &other) const
Implements implication operator in circuit.
static bool_t conditional_assign(const bool_t< Builder > &predicate, const bool_t &lhs, const bool_t &rhs)
Conditionally assign lhs or rhs based on predicate, always returns normalized result.
static bool_t from_witness_index_unsafe(Builder *ctx, uint32_t witness_index)
Create a bool_t from a witness index that is known to contain a constrained bool value.
bool_t implies_both_ways(const bool_t &other) const
Implements a "double-implication" (<=>), a.k.a "iff", a.k.a. "biconditional".
OriginTag get_origin_tag() const
constexpr T ceil_div(const T &numerator, const T &denominator)
Computes the ceiling of the division of two integral types.
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Entry point for Barretenberg command-line interface.
TYPED_TEST_SUITE(ShpleminiTest, TestSettings)
TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
This file contains part of the logic for the Origin Tag mechanism that tracks the use of in-circuit p...
#define STANDARD_TESTING_TAGS
testing::Types< bb::MegaCircuitBuilder, bb::UltraCircuitBuilder > CircuitTypes
static constexpr field one()
static constexpr field zero()