Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
logic_constraint.test.cpp
Go to the documentation of this file.
2#include "acir_format.hpp"
4
7
8#include <gtest/gtest.h>
9#include <vector>
10
11using namespace ::acir_format;
12
13enum class InputConstancy : uint8_t { None, Input1, Input2, Both };
14
15template <typename Builder_, InputConstancy Constancy_, size_t num_bits_, bool is_xor_gate_>
17 using Builder = Builder_;
18 static constexpr InputConstancy Constancy = Constancy_;
19 static constexpr size_t num_bits = num_bits_;
20 static constexpr bool is_xor_gate = is_xor_gate_;
21};
22
27template <typename Builder_, InputConstancy Constancy, uint32_t num_bits, bool is_xor_gate>
29 public:
30 using Builder = Builder_;
31 using AcirConstraint = LogicConstraint;
32 using FF = bb::fr;
33
35 public:
36 enum class Target : uint8_t {
37 None,
38 Inputs, // Invalidate first input
39 Input1BitSize, // Invalidate first input
40 Input2BitSize, // Invalidate second input
41 };
42
47
48 static std::vector<std::string> get_labels() { return { "None", "Inputs", "Input1BitSize", "Input2BitSize" }; }
49 };
50
51 static void generate_constraints(AcirConstraint& logic_constraint, WitnessVector& witness_values)
52 {
53 // Helper to add an input
54 auto construct_input = [&](const bb::fr input, bool as_constant) -> WitnessOrConstant<FF> {
55 if (as_constant) {
56 // Input is constant
57 return { WitnessOrConstant<FF>::from_constant(input) };
58 }
59 // Input is witness
60 uint32_t input_index = add_to_witness_and_track_indices(witness_values, input);
61 return WitnessOrConstant<FF>::from_index(input_index);
62 };
63
64 bb::fr lhs = FF(static_cast<uint256_t>(1) << num_bits - 1); // All bits from 0 to num_bits-1 are set
65 bb::fr rhs = FF(static_cast<uint256_t>(1) << num_bits - 1); // All bits from 0 to num_bits-1 are set
66 bb::fr result = is_xor_gate ? (static_cast<uint256_t>(lhs) ^ static_cast<uint256_t>(rhs))
67 : (static_cast<uint256_t>(lhs) & static_cast<uint256_t>(rhs));
68
69 logic_constraint = AcirConstraint{
70 .a = construct_input(lhs, (Constancy == InputConstancy::Input1 || Constancy == InputConstancy::Both)),
71 .b = construct_input(rhs, (Constancy == InputConstancy::Input2 || Constancy == InputConstancy::Both)),
72 .result = add_to_witness_and_track_indices(witness_values, result),
73 .num_bits = num_bits,
74 .is_xor_gate = is_xor_gate,
75 };
76 };
77
78 static void invalidate_witness(AcirConstraint& constraint,
79 WitnessVector& witness_values,
80 const InvalidWitness::Target& invalid_witness_target)
81 {
82 switch (invalid_witness_target) {
84 break;
86 // Set rhs = 1 << (num_bits - 1)
87 if (Constancy != InputConstancy::Input2 && Constancy != InputConstancy::Both) {
88 witness_values[constraint.b.index] = FF(static_cast<uint256_t>(1) << (num_bits - 1));
89 } else {
90 constraint.b.value = FF(static_cast<uint256_t>(1) << (num_bits - 1));
91 }
92 // Set result to incorrect value: lhs ^ (1 << (num_bits - 1)) = 0, lhs & (1 << (num_bits - 1)) = 1
93 witness_values[constraint.result] = is_xor_gate ? FF::one() : FF::zero();
94 break;
95 }
97 if (Constancy != InputConstancy::Input1 && Constancy != InputConstancy::Both) {
98 witness_values[constraint.a.index] +=
99 (static_cast<uint256_t>(witness_values[constraint.a.index]) << 1); // Tamper input 1 bit size
100 } else {
101 constraint.a.value = static_cast<uint256_t>(constraint.a.value) << 1; // Tamper input 1 bit size
102 }
103 break;
104 }
106 if (Constancy != InputConstancy::Input2 && Constancy != InputConstancy::Both) {
107 witness_values[constraint.b.index] +=
108 (static_cast<uint256_t>(witness_values[constraint.b.index]) << 1); // Tamper input 1 bit size
109 } else {
110 constraint.b.value = static_cast<uint256_t>(constraint.b.value) << 1; // Tamper input 1 bit size
111 }
112 break;
113 }
114 }
115 }
116};
117
118template <InputConstancy Constancy>
120 testing::Types<LogicConstraintTestParams<UltraCircuitBuilder, Constancy, 251, false>, // Ultra, AND, max bits
136
137template <typename Params>
138class LogicConstraintTestsNoneConstant : public ::testing::Test,
139 public TestClass<LogicConstraintTestingFunctions<typename Params::Builder,
140 Params::Constancy,
141 Params::num_bits,
142 Params::is_xor_gate>> {
143 protected:
145};
146
147template <typename Params>
148class LogicConstraintTestsInput1Constant : public ::testing::Test,
149 public TestClass<LogicConstraintTestingFunctions<typename Params::Builder,
150 Params::Constancy,
151 Params::num_bits,
152 Params::is_xor_gate>> {
153 protected:
155};
156
157template <typename Params>
158class LogicConstraintTestsInput2Constant : public ::testing::Test,
159 public TestClass<LogicConstraintTestingFunctions<typename Params::Builder,
160 Params::Constancy,
161 Params::num_bits,
162 Params::is_xor_gate>> {
163 protected:
165};
166
167template <typename Params>
168class LogicConstraintTestsBothConstant : public ::testing::Test,
169 public TestClass<LogicConstraintTestingFunctions<typename Params::Builder,
170 Params::Constancy,
171 Params::num_bits,
172 Params::is_xor_gate>> {
173 protected:
175};
176
181
183{
184 using Flavor =
186 TestFixture::template test_vk_independence<Flavor>();
187}
188
190{
191 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_tampering();
192}
193
195{
196 using Flavor =
198 TestFixture::template test_vk_independence<Flavor>();
199}
200
202{
203 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_tampering();
204}
205
207{
208 using Flavor =
210 TestFixture::template test_vk_independence<Flavor>();
211}
212
214{
215 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_tampering();
216}
217
219{
220 using Flavor =
222 TestFixture::template test_vk_independence<Flavor>();
223}
224
226{
227 // We need to test tampering by hand because when both inputs are constant making the bit size invalid will not make
228 // the builder fail, it will raise an error.
229 {
230 auto [circuit_checker_result, builder_failed, builder_err] =
231 TestFixture::test_constraints(TestFixture::InvalidWitnessTarget::None);
232
233 EXPECT_TRUE(circuit_checker_result) << "Circuit checker failed unexpectedly for invalid witness target None";
234 EXPECT_FALSE(builder_failed) << "Builder failed unexpectedly for invalid witness target None";
235 }
236
237 {
238 auto [circuit_checker_result, builder_failed, builder_err] =
239 TestFixture::test_constraints(TestFixture::InvalidWitnessTarget::Inputs);
240 bool circuit_check_failed = !circuit_checker_result;
241 bool assert_eq_error_present = (builder_err.find("assert_eq") != std::string::npos);
242 EXPECT_TRUE(circuit_check_failed || assert_eq_error_present)
243 << "Circuit checker succeeded unexpectedly and no assert_eq failure for invalid witness target Inputs";
244 EXPECT_TRUE(builder_failed) << "Builder succeeded for invalid witness target Inputs";
245 }
246
247 {
248 EXPECT_THROW_OR_ABORT(TestFixture::test_constraints(TestFixture::InvalidWitnessTarget::Input1BitSize),
249 ::testing::HasSubstr("field_t: Left operand in logic gate exceeds specified bit length"));
250 }
251
252 {
254 TestFixture::test_constraints(TestFixture::InvalidWitnessTarget::Input2BitSize),
255 ::testing::HasSubstr("field_t: Right operand in logic gate exceeds specified bit length"));
256 }
257}
#define EXPECT_THROW_OR_ABORT(statement, matcher)
Definition assert.hpp:174
Testing functions to generate the LogicConstraintTest test suite. Constancy specifies which inputs to...
static void invalidate_witness(AcirConstraint &constraint, WitnessVector &witness_values, const InvalidWitness::Target &invalid_witness_target)
static void generate_constraints(AcirConstraint &logic_constraint, WitnessVector &witness_values)
testing::Types< LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 251, false >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 128, false >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 16, false >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 1, false >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 251, true >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 128, true >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 16, true >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 1, true >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 251, false >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 128, false >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 16, false >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 1, false >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 251, true >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 128, true >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 16, true >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 1, true > > LogicTestConfigs
TYPED_TEST(LogicConstraintTestsNoneConstant, GenerateVKFromConstraints)
TYPED_TEST_SUITE(LogicConstraintTestsNoneConstant, LogicTestConfigs< InputConstancy::None >)
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
field< Bn254FrParams > fr
Definition fr.hpp:174
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static constexpr size_t num_bits
static constexpr InputConstancy Constancy
static constexpr bool is_xor_gate
static constexpr field one()
static constexpr field zero()