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"
3
6
7#include <gtest/gtest.h>
8#include <vector>
9
10using namespace ::acir_format;
11
12enum class InputConstancy : uint8_t { None, Input1, Input2, Both };
13
14template <typename Builder_, InputConstancy Constancy_, size_t num_bits_, bool is_xor_gate_>
16 using Builder = Builder_;
17 static constexpr InputConstancy Constancy = Constancy_;
18 static constexpr size_t num_bits = num_bits_;
19 static constexpr bool is_xor_gate = is_xor_gate_;
20};
21
26template <typename Builder_, InputConstancy Constancy, uint32_t num_bits, bool is_xor_gate>
28 public:
29 using Builder = Builder_;
30 using AcirConstraint = LogicConstraint;
31 using FF = bb::fr;
32
34 public:
35 enum class Target : uint8_t {
36 None,
37 Inputs, // Invalidate first input
38 Input1BitSize, // Invalidate first input
39 Input2BitSize, // Invalidate second input
40 };
41
50
51 static std::vector<std::string> get_labels()
52 {
53 if constexpr (num_bits == bb::grumpkin::MAX_NO_WRAP_INTEGER_BIT_LENGTH) {
54 return { "None", "Inputs" };
55 }
56
57 return { "None", "Inputs", "Input1BitSize", "Input2BitSize" };
58 }
59 };
60
61 static ProgramMetadata generate_metadata() { return ProgramMetadata{}; }
62
63 static void generate_constraints(AcirConstraint& logic_constraint, WitnessVector& witness_values)
64 {
65 // Helper to add an input
66 auto construct_input = [&](const bb::fr input, bool as_constant) -> WitnessOrConstant<FF> {
67 if (as_constant) {
68 // Input is constant
69 return { WitnessOrConstant<FF>::from_constant(input) };
70 }
71 // Input is witness
72 uint32_t input_index = add_to_witness_and_track_indices(witness_values, input);
73 return WitnessOrConstant<FF>::from_index(input_index);
74 };
75
76 bb::fr lhs = FF(static_cast<uint256_t>(1) << num_bits - 1); // All bits from 0 to num_bits-1 are set
77 bb::fr rhs = FF(static_cast<uint256_t>(1) << num_bits - 1); // All bits from 0 to num_bits-1 are set
78 bb::fr result = is_xor_gate ? (static_cast<uint256_t>(lhs) ^ static_cast<uint256_t>(rhs))
79 : (static_cast<uint256_t>(lhs) & static_cast<uint256_t>(rhs));
80
81 logic_constraint = AcirConstraint{
82 .a = construct_input(lhs, (Constancy == InputConstancy::Input1 || Constancy == InputConstancy::Both)),
83 .b = construct_input(rhs, (Constancy == InputConstancy::Input2 || Constancy == InputConstancy::Both)),
84 .result = add_to_witness_and_track_indices(witness_values, result),
85 .num_bits = num_bits,
86 .is_xor_gate = is_xor_gate,
87 };
88 };
89
91 AcirConstraint constraint, WitnessVector witness_values, const InvalidWitness::Target& invalid_witness_target)
92 {
93 switch (invalid_witness_target) {
95 break;
97 // Set rhs = 1 << (num_bits - 1)
98 if (Constancy != InputConstancy::Input2 && Constancy != InputConstancy::Both) {
99 witness_values[constraint.b.index] = FF(static_cast<uint256_t>(1) << (num_bits - 1));
100 } else {
101 constraint.b.value = FF(static_cast<uint256_t>(1) << (num_bits - 1));
102 }
103 // Set result to incorrect value: lhs ^ (1 << (num_bits - 1)) = 0, lhs & (1 << (num_bits - 1)) = 1
104 witness_values[constraint.result] = is_xor_gate ? FF::one() : FF::zero();
105 break;
106 }
108 if (Constancy != InputConstancy::Input1 && Constancy != InputConstancy::Both) {
109 witness_values[constraint.a.index] +=
110 (static_cast<uint256_t>(witness_values[constraint.a.index]) << 1); // Tamper input 1 bit size
111 } else {
112 constraint.a.value = static_cast<uint256_t>(constraint.a.value) << 1; // Tamper input 1 bit size
113 }
114 break;
115 }
117 if (Constancy != InputConstancy::Input2 && Constancy != InputConstancy::Both) {
118 witness_values[constraint.b.index] +=
119 (static_cast<uint256_t>(witness_values[constraint.b.index]) << 1); // Tamper input 1 bit size
120 } else {
121 constraint.b.value = static_cast<uint256_t>(constraint.b.value) << 1; // Tamper input 1 bit size
122 }
123 break;
124 }
125 }
126
127 return { constraint, witness_values };
128 }
129};
130
131template <InputConstancy Constancy>
133 testing::Types<LogicConstraintTestParams<UltraCircuitBuilder,
134 Constancy,
136 false>, // Ultra, AND, max bits
140 LogicConstraintTestParams<UltraCircuitBuilder,
141 Constancy,
143 true>, // Ultra, XOR
147 LogicConstraintTestParams<MegaCircuitBuilder,
148 Constancy,
150 false>, // Mega, AND
154 LogicConstraintTestParams<MegaCircuitBuilder,
155 Constancy,
157 true>, // Mega,
158 // XOR
162
163template <typename Params>
164class LogicConstraintTestsNoneConstant : public ::testing::Test,
165 public TestClass<LogicConstraintTestingFunctions<typename Params::Builder,
166 Params::Constancy,
167 Params::num_bits,
168 Params::is_xor_gate>> {
169 protected:
171};
172
173template <typename Params>
174class LogicConstraintTestsInput1Constant : public ::testing::Test,
175 public TestClass<LogicConstraintTestingFunctions<typename Params::Builder,
176 Params::Constancy,
177 Params::num_bits,
178 Params::is_xor_gate>> {
179 protected:
181};
182
183template <typename Params>
184class LogicConstraintTestsInput2Constant : public ::testing::Test,
185 public TestClass<LogicConstraintTestingFunctions<typename Params::Builder,
186 Params::Constancy,
187 Params::num_bits,
188 Params::is_xor_gate>> {
189 protected:
191};
192
193template <typename Params>
194class LogicConstraintTestsBothConstant : public ::testing::Test,
195 public TestClass<LogicConstraintTestingFunctions<typename Params::Builder,
196 Params::Constancy,
197 Params::num_bits,
198 Params::is_xor_gate>> {
199 protected:
201};
202
207
209{
210 using Flavor =
212 TestFixture::template test_vk_independence<Flavor>();
213}
214
216{
217 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_tampering();
218}
219
221{
222 using Flavor =
224 TestFixture::template test_vk_independence<Flavor>();
225}
226
228{
229 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_tampering();
230}
231
233{
234 using Flavor =
236 TestFixture::template test_vk_independence<Flavor>();
237}
238
240{
241 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_tampering();
242}
243
245{
246 using Flavor =
248 TestFixture::template test_vk_independence<Flavor>();
249}
250
252{
253 typename TestFixture::AcirConstraint constraint;
254 WitnessVector witness_values;
255 TestFixture::Base::generate_constraints(constraint, witness_values);
256
257 // We need to test tampering by hand because when both inputs are constant making the bit size invalid will not
258 // make the builder fail, it will raise an error.
259 {
260 auto [circuit_checker_result, builder_failed, builder_err] =
261 TestFixture::test_constraints(constraint, witness_values, TestFixture::InvalidWitnessTarget::None);
262 EXPECT_TRUE(circuit_checker_result) << "Circuit checker failed unexpectedly for invalid witness target None";
263 EXPECT_FALSE(builder_failed) << "Builder failed unexpectedly for invalid witness target None";
264 }
265
266 {
267 auto [circuit_checker_result, builder_failed, builder_err] =
268 TestFixture::test_constraints(constraint, witness_values, TestFixture::InvalidWitnessTarget::Inputs);
269 bool circuit_check_failed = !circuit_checker_result;
270 bool assert_eq_error_present = (builder_err.find("assert_eq") != std::string::npos);
271 EXPECT_TRUE(circuit_check_failed || assert_eq_error_present)
272 << "Circuit checker succeeded unexpectedly and no assert_eq failure for invalid witness target Inputs";
273 EXPECT_TRUE(builder_failed) << "Builder succeeded for invalid witness target Inputs";
274 }
275
276 {
278 TestFixture::test_constraints(constraint, witness_values, TestFixture::InvalidWitnessTarget::Input1BitSize),
279 "field_t: Left operand in logic gate exceeds specified bit length");
280 }
281
282 {
284 TestFixture::test_constraints(constraint, witness_values, TestFixture::InvalidWitnessTarget::Input2BitSize),
285 "field_t: Right operand in logic gate exceeds specified bit length");
286 }
287}
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
Definition assert.hpp:192
Testing functions to generate the LogicConstraintTest test suite. Constancy specifies which inputs to...
static std::pair< AcirConstraint, WitnessVector > invalidate_witness(AcirConstraint constraint, WitnessVector witness_values, const InvalidWitness::Target &invalid_witness_target)
static ProgramMetadata generate_metadata()
static void generate_constraints(AcirConstraint &logic_constraint, WitnessVector &witness_values)
TYPED_TEST(LogicConstraintTestsNoneConstant, GenerateVKFromConstraints)
TYPED_TEST_SUITE(LogicConstraintTestsNoneConstant, LogicTestConfigs< InputConstancy::None >)
testing::Types< LogicConstraintTestParams< UltraCircuitBuilder, Constancy, bb::grumpkin::MAX_NO_WRAP_INTEGER_BIT_LENGTH, false >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 128, false >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 16, false >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 1, false >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, bb::grumpkin::MAX_NO_WRAP_INTEGER_BIT_LENGTH, true >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 128, true >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 16, true >, LogicConstraintTestParams< UltraCircuitBuilder, Constancy, 1, true >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, bb::grumpkin::MAX_NO_WRAP_INTEGER_BIT_LENGTH, false >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 128, false >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 16, false >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 1, false >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, bb::grumpkin::MAX_NO_WRAP_INTEGER_BIT_LENGTH, true >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 128, true >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 16, true >, LogicConstraintTestParams< MegaCircuitBuilder, Constancy, 1, true > > LogicTestConfigs
constexpr size_t MAX_NO_WRAP_INTEGER_BIT_LENGTH
Definition grumpkin.hpp:15
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()