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"
3
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
24template <typename Builder_, InputConstancy Constancy> class EcOperationsTestingFunctions {
25 public:
26 using Builder = Builder_;
27 using AcirConstraint = EcAdd;
30 using FF = bb::fr;
31
33 public:
34 enum class Target : uint8_t {
35 None,
36 Input1, // Invalidate first input point
37 Input2, // Invalidate second input point
38 Result // Invalidate result output
39 };
40
45
46 static std::vector<std::string> get_labels() { return { "None", "Input1", "Input2", "Result" }; }
47 };
48
49 static ProgramMetadata generate_metadata() { return ProgramMetadata{}; }
50
51 static void generate_constraints(AcirConstraint& ec_add_constraint, WitnessVector& witness_values)
52 {
53 // Generate points on Grumpkin
56 GrumpkinPoint result = input1 + input2;
57 BB_ASSERT(result != GrumpkinPoint::one()); // Ensure that tampering works correctly
58
59 // Helper to add a point: either as witness or constant
60 auto construct_point = [&](const GrumpkinPoint& point, bool as_constant) -> std::vector<WitnessOrConstant<FF>> {
61 if (as_constant) {
62 // Point is constant
63 return { WitnessOrConstant<FF>::from_constant(point.x),
64 WitnessOrConstant<FF>::from_constant(point.y),
65 WitnessOrConstant<FF>::from_constant(point.is_point_at_infinity() ? FF(1) : FF(0)) };
66 }
67 // Point is witness
68 std::vector<uint32_t> point_indices = add_to_witness_and_track_indices(witness_values, point);
69 return { WitnessOrConstant<FF>::from_index(point_indices[0]),
70 WitnessOrConstant<FF>::from_index(point_indices[1]),
71 WitnessOrConstant<FF>::from_index(point_indices[2]) };
72 };
73
74 // Determine which inputs are constants based on the Constancy template parameter
75 constexpr bool input1_is_constant = (Constancy == InputConstancy::Input1 || Constancy == InputConstancy::Both);
76 constexpr bool input2_is_constant = (Constancy == InputConstancy::Input2 || Constancy == InputConstancy::Both);
77
78 // Add inputs according to constancy template parameter
79 auto input1_fields = construct_point(input1, input1_is_constant);
80 auto input2_fields = construct_point(input2, input2_is_constant);
81
82 // Construct result and predicate as witnesses
83 std::vector<uint32_t> result_indices = add_to_witness_and_track_indices(witness_values, result);
84 uint32_t predicate_index = add_to_witness_and_track_indices(witness_values, FF(1));
85
86 // Build the constraint
87 ec_add_constraint = EcAdd{
88 .input1_x = input1_fields[0],
89 .input1_y = input1_fields[1],
90 .input1_infinite = input1_fields[2],
91 .input2_x = input2_fields[0],
92 .input2_y = input2_fields[1],
93 .input2_infinite = input2_fields[2],
94 .predicate = WitnessOrConstant<FF>::from_index(predicate_index),
95 .result_x = result_indices[0],
96 .result_y = result_indices[1],
97 .result_infinite = result_indices[2],
98 };
99 }
100
102 AcirConstraint constraint, WitnessVector witness_values, 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 return { constraint, witness_values };
136 };
137};
138
139template <typename Builder>
141 : public ::testing::Test,
142 public TestClassWithPredicate<EcOperationsTestingFunctions<Builder, InputConstancy::None>> {
143 protected:
145};
146
147template <typename Builder>
149 : public ::testing::Test,
150 public TestClassWithPredicate<EcOperationsTestingFunctions<Builder, InputConstancy::Input1>> {
151 protected:
153};
154
155template <typename Builder>
157 : public ::testing::Test,
158 public TestClassWithPredicate<EcOperationsTestingFunctions<Builder, InputConstancy::Input2>> {
159 protected:
161};
162
163template <typename Builder>
165 : public ::testing::Test,
166 public TestClassWithPredicate<EcOperationsTestingFunctions<Builder, InputConstancy::Both>> {
167 protected:
169};
170
171using BuilderTypes = testing::Types<UltraCircuitBuilder, MegaCircuitBuilder>;
172
177
178TYPED_TEST(EcOperationsTestsNoneConstant, GenerateVKFromConstraints)
179{
181 TestFixture::template test_vk_independence<Flavor>();
182}
183
185{
187 TestFixture::test_constant_true(TestFixture::InvalidWitnessTarget::Result);
188}
189
191{
193 TestFixture::test_witness_true(TestFixture::InvalidWitnessTarget::Result);
194}
195
197{
199 TestFixture::test_witness_false_slow();
200}
201
203{
205 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_invalid_witnesses();
206}
207
209{
211 TestFixture::template test_vk_independence<Flavor>();
212}
213
215{
217 TestFixture::test_constant_true(TestFixture::InvalidWitnessTarget::Result);
218}
219
221{
223 TestFixture::test_witness_true(TestFixture::InvalidWitnessTarget::Result);
224}
225
227{
229 TestFixture::test_witness_false_slow();
230}
231
233{
235 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_invalid_witnesses();
236}
237
239{
241 TestFixture::template test_vk_independence<Flavor>();
242}
243
245{
247 TestFixture::test_constant_true(TestFixture::InvalidWitnessTarget::Result);
248}
249
251{
253 TestFixture::test_witness_true(TestFixture::InvalidWitnessTarget::Result);
254}
255
257{
259 TestFixture::test_witness_false_slow();
260}
261
263{
265 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_invalid_witnesses();
266}
267
268TYPED_TEST(EcOperationsTestsBothConstant, GenerateVKFromConstraints)
269{
271 TestFixture::template test_vk_independence<Flavor>();
272}
273
275{
277 TestFixture::test_constant_true(TestFixture::InvalidWitnessTarget::Result);
278}
279
281{
283 TestFixture::test_witness_true(TestFixture::InvalidWitnessTarget::Result);
284}
285
287{
289 TestFixture::test_witness_false_slow();
290}
291
293{
295 [[maybe_unused]] std::vector<std::string> _ = TestFixture::test_invalid_witnesses();
296}
#define BB_ASSERT(expression,...)
Definition assert.hpp:80
#define BB_DISABLE_ASSERTS()
Definition assert.hpp:33
static std::vector< std::string > get_labels()
Testing functions to generate the EcOperationTest test suite. Constancy specifies which inputs to the...
static ProgramMetadata generate_metadata()
static void generate_constraints(AcirConstraint &ec_add_constraint, WitnessVector &witness_values)
static std::pair< AcirConstraint, WitnessVector > invalidate_witness(AcirConstraint constraint, WitnessVector witness_values, const InvalidWitness::Target &invalid_witness_target)
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()