Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ecc_trace.test.cpp
Go to the documentation of this file.
1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
3
8
9namespace bb::avm2::tracegen {
10namespace {
11
12using testing::ElementsAre;
13using testing::Field;
14
16
17TEST(EccTraceGenTest, TraceGenerationAdd)
18{
19 TestTraceContainer trace;
20 EccTraceBuilder builder;
21
22 FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
23 FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
24 EmbeddedCurvePoint p(p_x, p_y);
25 FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7");
26 FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3");
27 EmbeddedCurvePoint q(q_x, q_y);
28 FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6");
29 FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
30 EmbeddedCurvePoint r(r_x, r_y);
31 builder.process_add({ { .p = p, .q = q, .result = r } }, trace);
32
33 EXPECT_THAT(trace.as_rows(),
34 ElementsAre(
35 // Only one row.
36 AllOf(ROW_FIELD_EQ(ecc_add_op, 1),
37 ROW_FIELD_EQ(ecc_double_op, 0),
38 ROW_FIELD_EQ(ecc_inv_2_p_y, FF::zero()),
39 ROW_FIELD_EQ(ecc_inv_x_diff, (q.x() - p.x()).invert()),
40 ROW_FIELD_EQ(ecc_inv_y_diff, (q.y() - p.y()).invert()),
41 ROW_FIELD_EQ(ecc_lambda, (q.y() - p.y()) / (q.x() - p.x())),
42 ROW_FIELD_EQ(ecc_p_is_inf, p.is_infinity()),
43 ROW_FIELD_EQ(ecc_p_x, p.x()),
44 ROW_FIELD_EQ(ecc_p_y, p.y()),
45 ROW_FIELD_EQ(ecc_q_is_inf, q.is_infinity()),
46 ROW_FIELD_EQ(ecc_q_x, q.x()),
47 ROW_FIELD_EQ(ecc_q_y, q.y()),
48 ROW_FIELD_EQ(ecc_r_x, r.x()),
49 ROW_FIELD_EQ(ecc_r_y, r.y()),
50 ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()),
51 ROW_FIELD_EQ(ecc_sel, 1),
52 ROW_FIELD_EQ(ecc_x_match, 0),
53 ROW_FIELD_EQ(ecc_y_match, 0))));
54}
55
56TEST(EccTraceGenTest, TraceGenerationDouble)
57{
58 TestTraceContainer trace;
59 EccTraceBuilder builder;
60
61 FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
62 FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
63 EmbeddedCurvePoint p(p_x, p_y);
65 FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6");
66 FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
67 EmbeddedCurvePoint r(r_x, r_y);
68
69 builder.process_add({ { .p = p, .q = q, .result = r } }, trace);
70
71 EXPECT_THAT(trace.as_rows(),
72 ElementsAre(
73 // Only one row.
74 AllOf(ROW_FIELD_EQ(ecc_add_op, 0),
75 ROW_FIELD_EQ(ecc_double_op, 1),
76 ROW_FIELD_EQ(ecc_inv_2_p_y, (p.y() * 2).invert()),
77 ROW_FIELD_EQ(ecc_inv_x_diff, FF::zero()),
78 ROW_FIELD_EQ(ecc_inv_y_diff, FF::zero()),
79 ROW_FIELD_EQ(ecc_lambda, (p.x() * p.x() * 3) / (p.y() * 2)),
80 ROW_FIELD_EQ(ecc_p_is_inf, p.is_infinity()),
81 ROW_FIELD_EQ(ecc_p_x, p.x()),
82 ROW_FIELD_EQ(ecc_p_y, p.y()),
83 ROW_FIELD_EQ(ecc_q_is_inf, q.is_infinity()),
84 ROW_FIELD_EQ(ecc_q_x, p.x()),
85 ROW_FIELD_EQ(ecc_q_y, p.y()),
86 ROW_FIELD_EQ(ecc_r_x, r.x()),
87 ROW_FIELD_EQ(ecc_r_y, r.y()),
88 ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()),
89 ROW_FIELD_EQ(ecc_sel, 1),
90 ROW_FIELD_EQ(ecc_x_match, 1),
91 ROW_FIELD_EQ(ecc_y_match, 1))));
92}
93
94TEST(EccTraceGenTest, TraceGenerationInfResult)
95{
96 TestTraceContainer trace;
97 EccTraceBuilder builder;
98
99 FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
100 FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
101 EmbeddedCurvePoint p(p_x, p_y);
102
103 EmbeddedCurvePoint q(p.x(), -p.y());
104 EmbeddedCurvePoint r = p + q;
105
106 builder.process_add({ { .p = p, .q = q, .result = r } }, trace);
107
108 EXPECT_THAT(trace.as_rows(),
109 ElementsAre(
110 // Only one row.
111 AllOf(ROW_FIELD_EQ(ecc_add_op, 0),
112 ROW_FIELD_EQ(ecc_double_op, 0),
113 ROW_FIELD_EQ(ecc_inv_2_p_y, 0),
114 ROW_FIELD_EQ(ecc_inv_x_diff, FF::zero()),
115 ROW_FIELD_EQ(ecc_inv_y_diff, (q.y() - p.y()).invert()),
116 ROW_FIELD_EQ(ecc_lambda, 0),
117 ROW_FIELD_EQ(ecc_p_is_inf, p.is_infinity()),
118 ROW_FIELD_EQ(ecc_p_x, p.x()),
119 ROW_FIELD_EQ(ecc_p_y, p.y()),
120 ROW_FIELD_EQ(ecc_q_is_inf, q.is_infinity()),
121 ROW_FIELD_EQ(ecc_q_x, q.x()),
122 ROW_FIELD_EQ(ecc_q_y, q.y()),
123 ROW_FIELD_EQ(ecc_r_x, r.x()),
124 ROW_FIELD_EQ(ecc_r_y, r.y()),
125 ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()),
126 ROW_FIELD_EQ(ecc_sel, 1),
127 ROW_FIELD_EQ(ecc_x_match, 1),
128 ROW_FIELD_EQ(ecc_y_match, 0))));
129}
130
131TEST(EccTraceGenTest, TraceGenerationInfAdd)
132{
133 TestTraceContainer trace;
134 EccTraceBuilder builder;
135
136 FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
137 FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
138 EmbeddedCurvePoint p(p_x, p_y);
139
140 // We always assume infinity coordinates have been normalized to (0,0) before reaching tracegen
142 EmbeddedCurvePoint r = p;
143
144 builder.process_add({ { .p = p, .q = q, .result = r } }, trace);
145
146 EXPECT_THAT(trace.as_rows(),
147 ElementsAre(
148 // Only one row.
149 AllOf(ROW_FIELD_EQ(ecc_add_op, 1),
150 ROW_FIELD_EQ(ecc_double_op, 0),
151 ROW_FIELD_EQ(ecc_inv_2_p_y, 0),
152 ROW_FIELD_EQ(ecc_inv_x_diff, (q.x() - p.x()).invert()),
153 ROW_FIELD_EQ(ecc_inv_y_diff, (q.y() - p.y()).invert()),
154 ROW_FIELD_EQ(ecc_lambda, (q.y() - p.y()) / (q.x() - p.x())),
155 ROW_FIELD_EQ(ecc_p_is_inf, p.is_infinity()),
156 ROW_FIELD_EQ(ecc_p_x, p.x()),
157 ROW_FIELD_EQ(ecc_p_y, p.y()),
158 ROW_FIELD_EQ(ecc_q_is_inf, q.is_infinity()),
159 ROW_FIELD_EQ(ecc_q_x, q.x()),
160 ROW_FIELD_EQ(ecc_q_y, q.y()),
161 ROW_FIELD_EQ(ecc_r_x, r.x()),
162 ROW_FIELD_EQ(ecc_r_y, r.y()),
163 ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()),
164 ROW_FIELD_EQ(ecc_sel, 1),
165 ROW_FIELD_EQ(ecc_x_match, 0),
166 ROW_FIELD_EQ(ecc_y_match, 0))));
167}
168
169TEST(EccTraceGenTest, TraceGenerationInfDouble)
170{
171 TestTraceContainer trace;
172 EccTraceBuilder builder;
173
175 EmbeddedCurvePoint r = p;
176
177 builder.process_add({ { .p = p, .q = p, .result = r } }, trace);
178
179 EXPECT_THAT(trace.as_rows(),
180 ElementsAre(
181 // Only one row.
182 AllOf(ROW_FIELD_EQ(ecc_add_op, 0),
183 ROW_FIELD_EQ(ecc_double_op, 1),
184 ROW_FIELD_EQ(ecc_inv_2_p_y, 0),
185 ROW_FIELD_EQ(ecc_inv_x_diff, 0),
186 ROW_FIELD_EQ(ecc_inv_y_diff, 0),
187 ROW_FIELD_EQ(ecc_lambda, 0),
188 ROW_FIELD_EQ(ecc_p_is_inf, p.is_infinity()),
189 ROW_FIELD_EQ(ecc_p_x, p.x()),
190 ROW_FIELD_EQ(ecc_p_y, p.y()),
191 ROW_FIELD_EQ(ecc_q_is_inf, p.is_infinity()),
192 ROW_FIELD_EQ(ecc_q_x, p.x()),
193 ROW_FIELD_EQ(ecc_q_y, p.y()),
194 ROW_FIELD_EQ(ecc_r_x, r.x()),
195 ROW_FIELD_EQ(ecc_r_y, r.y()),
196 ROW_FIELD_EQ(ecc_result_infinity, r.is_infinity()),
197 ROW_FIELD_EQ(ecc_sel, 1),
198 ROW_FIELD_EQ(ecc_x_match, 1),
199 ROW_FIELD_EQ(ecc_y_match, 1))));
200}
201
202TEST(EccTraceGenTest, TraceGenerationAddMemoryInfDiffInvWitnesses)
203{
204 TestTraceContainer trace;
205 EccTraceBuilder builder;
206
207 FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
208 FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
209 EmbeddedCurvePoint p(p_x, p_y);
210 FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7");
211 FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3");
212 EmbeddedCurvePoint q(q_x, q_y);
214 EmbeddedCurvePoint r = p + q;
215
216 // Row 0: P and Q both non-inf
217 // Row 1: P non-inf, Q inf
218 // Row 2: P and Q both inf
219 builder.process_add_with_memory(
220 {
221 { .execution_clk = 0, .space_id = 0, .p = p, .q = q, .result = r, .dst_address = 0x1000 },
222 { .execution_clk = 1, .space_id = 0, .p = p, .q = inf, .result = p, .dst_address = 0x1000 },
223 { .execution_clk = 2, .space_id = 0, .p = inf, .q = inf, .result = inf, .dst_address = 0x1000 },
224 },
225 trace);
226
227 EXPECT_THAT(trace.as_rows(),
228 ElementsAre(AllOf(ROW_FIELD_EQ(ecc_add_mem_sel, 1),
229 ROW_FIELD_EQ(ecc_add_mem_p_is_inf, 0),
230 ROW_FIELD_EQ(ecc_add_mem_q_is_inf, 0),
231 ROW_FIELD_EQ(ecc_add_mem_p_x_inf_diff_inv, (p.x() - inf.x()).invert()),
232 ROW_FIELD_EQ(ecc_add_mem_p_y_inf_diff_inv, (p.y() - inf.y()).invert()),
233 ROW_FIELD_EQ(ecc_add_mem_q_x_inf_diff_inv, (q.x() - inf.x()).invert()),
234 ROW_FIELD_EQ(ecc_add_mem_q_y_inf_diff_inv, (q.y() - inf.y()).invert())),
235 AllOf(ROW_FIELD_EQ(ecc_add_mem_sel, 1),
236 ROW_FIELD_EQ(ecc_add_mem_p_x, p.x()),
237 ROW_FIELD_EQ(ecc_add_mem_p_y, p.y()),
238 ROW_FIELD_EQ(ecc_add_mem_p_is_inf, 0),
239 ROW_FIELD_EQ(ecc_add_mem_q_x, inf.x()),
240 ROW_FIELD_EQ(ecc_add_mem_q_y, inf.y()),
241 ROW_FIELD_EQ(ecc_add_mem_q_is_inf, 1),
242 ROW_FIELD_EQ(ecc_add_mem_p_x_inf_diff_inv, (p.x() - inf.x()).invert()),
243 ROW_FIELD_EQ(ecc_add_mem_p_y_inf_diff_inv, (p.y() - inf.y()).invert()),
244 ROW_FIELD_EQ(ecc_add_mem_q_x_inf_diff_inv, FF::zero()),
245 ROW_FIELD_EQ(ecc_add_mem_q_y_inf_diff_inv, FF::zero())),
246 AllOf(ROW_FIELD_EQ(ecc_add_mem_sel, 1),
247 ROW_FIELD_EQ(ecc_add_mem_p_is_inf, 1),
248 ROW_FIELD_EQ(ecc_add_mem_q_is_inf, 1),
249 ROW_FIELD_EQ(ecc_add_mem_p_x_inf_diff_inv, FF::zero()),
250 ROW_FIELD_EQ(ecc_add_mem_p_y_inf_diff_inv, FF::zero()),
251 ROW_FIELD_EQ(ecc_add_mem_q_x_inf_diff_inv, FF::zero()),
252 ROW_FIELD_EQ(ecc_add_mem_q_y_inf_diff_inv, FF::zero()))));
253}
254
255} // namespace
256} // namespace bb::avm2::tracegen
std::vector< AvmFullRowConstRef > as_rows() const
AluTraceBuilder builder
Definition alu.test.cpp:124
TestTraceContainer trace
#define ROW_FIELD_EQ(field_name, expression)
Definition macros.hpp:7
StandardAffinePoint< AvmFlavorSettings::EmbeddedCurve::AffineElement > EmbeddedCurvePoint
Definition field.hpp:12
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)