Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ec_operations.test.cpp
Go to the documentation of this file.
1#include "ec_operations.hpp"
2#include "acir_format.hpp"
4
8
9#include <gtest/gtest.h>
10#include <vector>
11
12using namespace ::acir_format;
13
14enum class InputConstancy : uint8_t { None, Input1, Input2, Both };
15
25template <typename Builder_, InputConstancy Constancy> class EcOperationsTestingFunctions {
26 public:
27 using Builder = Builder_;
28 using AcirConstraint = EcAdd;
31 using FF = bb::fr;
32
34 public:
35 enum class Target : uint8_t {
36 None,
37 Input1, // Invalidate first input point
38 Input2, // Invalidate second input point
39 Result // Invalidate result output
40 };
41
46
47 static std::vector<std::string> get_labels() { return { "None", "Input1", "Input2", "Result" }; }
48 };
49
50 static void generate_constraints(AcirConstraint& ec_add_constraint, WitnessVector& witness_values)
51 {
52 // Generate points on Grumpkin
55 GrumpkinPoint result = input1 + input2;
56 BB_ASSERT(result != GrumpkinPoint::one()); // Ensure that tampering works correctly
57
58 // Helper to add a point: either as witness or constant
59 auto construct_point = [&](const GrumpkinPoint& point, bool as_constant) -> std::vector<WitnessOrConstant<FF>> {
60 if (as_constant) {
61 // Point is constant
62 return { WitnessOrConstant<FF>::from_constant(point.x),
63 WitnessOrConstant<FF>::from_constant(point.y),
64 WitnessOrConstant<FF>::from_constant(point.is_point_at_infinity() ? FF(1) : FF(0)) };
65 }
66 // Point is witness
67 std::vector<uint32_t> point_indices = add_to_witness_and_track_indices(witness_values, point);
68 return { WitnessOrConstant<FF>::from_index(point_indices[0]),
69 WitnessOrConstant<FF>::from_index(point_indices[1]),
70 WitnessOrConstant<FF>::from_index(point_indices[2]) };
71 };
72
73 // Determine which inputs are constants based on the Constancy template parameter
74 constexpr bool input1_is_constant = (Constancy == InputConstancy::Input1 || Constancy == InputConstancy::Both);
75 constexpr bool input2_is_constant = (Constancy == InputConstancy::Input2 || Constancy == InputConstancy::Both);
76
77 // Add inputs according to constancy template parameter
78 auto input1_fields = construct_point(input1, input1_is_constant);
79 auto input2_fields = construct_point(input2, input2_is_constant);
80
81 // Construct result and predicate as witnesses
82 std::vector<uint32_t> result_indices = add_to_witness_and_track_indices(witness_values, result);
83 uint32_t predicate_index = add_to_witness_and_track_indices(witness_values, FF(1));
84
85 // Build the constraint
86 ec_add_constraint = EcAdd{
87 .input1_x = input1_fields[0],
88 .input1_y = input1_fields[1],
89 .input1_infinite = input1_fields[2],
90 .input2_x = input2_fields[0],
91 .input2_y = input2_fields[1],
92 .input2_infinite = input2_fields[2],
93 .predicate = WitnessOrConstant<FF>::from_index(predicate_index),
94 .result_x = result_indices[0],
95 .result_y = result_indices[1],
96 .result_infinite = result_indices[2],
97 };
98 }
99
100 static void invalidate_witness(AcirConstraint& constraint,
101 WitnessVector& witness_values,
102 const InvalidWitness::Target& invalid_witness_target)
103 {
104 switch (invalid_witness_target) {
106 // Invalidate the first input by adding 1 to x coordinate
107 if constexpr (Constancy == InputConstancy::None || Constancy == InputConstancy::Input2) {
108 witness_values[constraint.input1_x.index] += bb::fr(1);
109 } else {
110 constraint.input1_x = WitnessOrConstant<FF>::from_constant(constraint.input1_x.value + bb::fr(1));
111 }
112 break;
113 }
115 // Invalidate the second input by adding 1 to x coordinate
116 if constexpr (Constancy == InputConstancy::None || Constancy == InputConstancy::Input1) {
117 witness_values[constraint.input2_x.index] += bb::fr(1);
118 } else {
119 constraint.input2_x = WitnessOrConstant<FF>::from_constant(constraint.input2_x.value + bb::fr(1));
120 }
121 break;
122 }
124 // Tamper with the result (always a witness) by setting it to the generator point
125 witness_values[constraint.result_x] = GrumpkinPoint::one().x;
126 witness_values[constraint.result_y] = GrumpkinPoint::one().y;
127 witness_values[constraint.result_infinite] = FF::zero();
128 break;
129 }
131 default:
132 break;
133 }
134 };
135};
136
137template <typename Builder>
139 : public ::testing::Test,
140 public TestClassWithPredicate<EcOperationsTestingFunctions<Builder, InputConstancy::None>> {
141 protected:
143};
144
145template <typename Builder>
147 : public ::testing::Test,
148 public TestClassWithPredicate<EcOperationsTestingFunctions<Builder, InputConstancy::Input1>> {
149 protected:
151};
152
153template <typename Builder>
155 : public ::testing::Test,
156 public TestClassWithPredicate<EcOperationsTestingFunctions<Builder, InputConstancy::Input2>> {
157 protected:
159};
160
161template <typename Builder>
163 : public ::testing::Test,
164 public TestClassWithPredicate<EcOperationsTestingFunctions<Builder, InputConstancy::Both>> {
165 protected:
167};
168
169using BuilderTypes = testing::Types<UltraCircuitBuilder, MegaCircuitBuilder>;
170
175
176TYPED_TEST(EcOperationsTestsNoneConstant, GenerateVKFromConstraints)
177{
179 TestFixture::template test_vk_independence<Flavor>();
180}
181
183{
185 TestFixture::test_constant_true(TestFixture::InvalidWitnessTarget::Result);
186}
187
189{
191 TestFixture::test_witness_true(TestFixture::InvalidWitnessTarget::Result);
192}
193
195{
197 TestFixture::test_witness_false_slow();
198}
199
201{
203 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_invalid_witnesses();
204}
205
207{
209 TestFixture::template test_vk_independence<Flavor>();
210}
211
213{
215 TestFixture::test_constant_true(TestFixture::InvalidWitnessTarget::Result);
216}
217
219{
221 TestFixture::test_witness_true(TestFixture::InvalidWitnessTarget::Result);
222}
223
225{
227 TestFixture::test_witness_false_slow();
228}
229
231{
233 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_invalid_witnesses();
234}
235
237{
239 TestFixture::template test_vk_independence<Flavor>();
240}
241
243{
245 TestFixture::test_constant_true(TestFixture::InvalidWitnessTarget::Result);
246}
247
249{
251 TestFixture::test_witness_true(TestFixture::InvalidWitnessTarget::Result);
252}
253
255{
257 TestFixture::test_witness_false_slow();
258}
259
261{
263 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_invalid_witnesses();
264}
265
266TYPED_TEST(EcOperationsTestsBothConstant, GenerateVKFromConstraints)
267{
269 TestFixture::template test_vk_independence<Flavor>();
270}
271
273{
275 TestFixture::test_constant_true(TestFixture::InvalidWitnessTarget::Result);
276}
277
279{
281 TestFixture::test_witness_true(TestFixture::InvalidWitnessTarget::Result);
282}
283
285{
287 TestFixture::test_witness_false_slow();
288}
289
291{
293 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_invalid_witnesses();
294}
#define BB_ASSERT(expression,...)
Definition assert.hpp:67
#define BB_DISABLE_ASSERTS()
Definition assert.hpp:32
static std::vector< std::string > get_labels()
Testing functions to generate the EcOperationTest test suite. Constancy specifies which inputs to the...
static void invalidate_witness(AcirConstraint &constraint, WitnessVector &witness_values, const InvalidWitness::Target &invalid_witness_target)
static void generate_constraints(AcirConstraint &ec_add_constraint, WitnessVector &witness_values)
constexpr bool is_point_at_infinity() const noexcept
static affine_element random_element(numeric::RNG *engine=nullptr) noexcept
Samples a random point on the curve.
static constexpr affine_element one() noexcept
group class. Represents an elliptic curve group element. Group is parametrised by Fq and Fr
Definition group.hpp:36
group_elements::affine_element< Fq, Fr, Params > affine_element
Definition group.hpp:42
TYPED_TEST_SUITE(EcOperationsTestsNoneConstant, BuilderTypes)
TYPED_TEST(EcOperationsTestsNoneConstant, GenerateVKFromConstraints)
bb::group< bb::fr, bb::fq, G1Params > g1
Definition grumpkin.hpp:45
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
::testing::Types< UltraCircuitBuilder, MegaCircuitBuilder > BuilderTypes
static constexpr field zero()