Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
translator_relation_consistency.test.cpp
Go to the documentation of this file.
1
16#include <gtest/gtest.h>
17
18using namespace bb;
19
21using FF = typename Flavor::FF;
23
25{
27 for (FF& element : result.get_all()) {
28 element = FF::random_element();
29 }
30 return result;
31}
32
33InputElements get_special_input() // use non-random values
34{
36 FF idx = 0;
37 for (FF& element : result.get_all()) {
38 idx += FF(1);
39 element = idx;
40 }
41 return result;
42}
43
44class TranslatorRelationConsistency : public testing::Test {
45 public:
46 template <typename Relation>
47 static void validate_relation_execution(const auto& expected_values,
48 const InputElements& input_elements,
49 const auto& parameters)
50 {
52 std::fill(accumulator.begin(), accumulator.end(), FF(0));
53 Relation::accumulate(accumulator, input_elements, parameters, 1);
54 EXPECT_EQ(accumulator, expected_values);
55 };
56};
57
59{
60 const auto run_test = [](bool random_inputs) {
62 using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations;
63
64 const InputElements input_elements = random_inputs ? get_random_input() : get_special_input();
65 const auto& concatenated_range_constraints_0 = input_elements.concatenated_range_constraints_0;
66 const auto& concatenated_range_constraints_1 = input_elements.concatenated_range_constraints_1;
67 const auto& concatenated_range_constraints_2 = input_elements.concatenated_range_constraints_2;
68 const auto& concatenated_range_constraints_3 = input_elements.concatenated_range_constraints_3;
69 const auto& ordered_range_constraints_0 = input_elements.ordered_range_constraints_0;
70 const auto& ordered_range_constraints_1 = input_elements.ordered_range_constraints_1;
71 const auto& ordered_range_constraints_2 = input_elements.ordered_range_constraints_2;
72 const auto& ordered_range_constraints_3 = input_elements.ordered_range_constraints_3;
73 const auto& ordered_range_constraints_4 = input_elements.ordered_range_constraints_4;
74 const auto& ordered_extra_range_constraints_numerator =
75 input_elements.ordered_extra_range_constraints_numerator;
76 const auto& z_perm = input_elements.z_perm;
77 const auto& z_perm_shift = input_elements.z_perm_shift;
78 const auto& lagrange_first = input_elements.lagrange_first;
79 const auto& lagrange_last = input_elements.lagrange_last;
80 const auto& lagrange_masking = input_elements.lagrange_masking;
81 const auto& lagrange_ordered_masking = input_elements.lagrange_ordered_masking;
82
83 RelationValues expected_values;
84
85 const auto parameters = RelationParameters<FF>::get_random();
86 const auto& gamma = parameters.gamma;
87 const auto& beta = parameters.beta;
88
89 // (Contribution 1)
90 // First 4 numerator factors use scattered masking (lagrange_masking),
91 // 5th numerator factor and all denominator factors use contiguous masking (lagrange_ordered_masking)
92 auto contribution_1 =
93 (z_perm + lagrange_first) * (concatenated_range_constraints_0 + lagrange_masking * beta + gamma) *
94 (concatenated_range_constraints_1 + lagrange_masking * beta + gamma) *
95 (concatenated_range_constraints_2 + lagrange_masking * beta + gamma) *
96 (concatenated_range_constraints_3 + lagrange_masking * beta + gamma) *
97 (ordered_extra_range_constraints_numerator + lagrange_ordered_masking * beta + gamma) -
98 (z_perm_shift + lagrange_last) * (ordered_range_constraints_0 + lagrange_ordered_masking * beta + gamma) *
99 (ordered_range_constraints_1 + lagrange_ordered_masking * beta + gamma) *
100 (ordered_range_constraints_2 + lagrange_ordered_masking * beta + gamma) *
101 (ordered_range_constraints_3 + lagrange_ordered_masking * beta + gamma) *
102 (ordered_range_constraints_4 + lagrange_ordered_masking * beta + gamma);
103 expected_values[0] = contribution_1;
104
105 // (Contribution 2)
106 auto contribution_2 = z_perm_shift * lagrange_last;
107 expected_values[1] = contribution_2;
108
109 // (Contribution 3)
110 auto contribution_3 = lagrange_first * z_perm;
111 expected_values[2] = contribution_3;
112
113 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
114 };
115 run_test(/*random_inputs=*/false);
116 run_test(/*random_inputs=*/true);
117};
118
120{
121 const auto run_test = [](bool random_inputs) {
123 using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations;
124
125 const InputElements input_elements = random_inputs ? get_random_input() : get_special_input();
126
127 const auto& ordered_range_constraints_0 = input_elements.ordered_range_constraints_0;
128 const auto& ordered_range_constraints_1 = input_elements.ordered_range_constraints_1;
129 const auto& ordered_range_constraints_2 = input_elements.ordered_range_constraints_2;
130 const auto& ordered_range_constraints_3 = input_elements.ordered_range_constraints_3;
131 const auto& ordered_range_constraints_4 = input_elements.ordered_range_constraints_4;
132 const auto& ordered_range_constraints_0_shift = input_elements.ordered_range_constraints_0_shift;
133 const auto& ordered_range_constraints_1_shift = input_elements.ordered_range_constraints_1_shift;
134 const auto& ordered_range_constraints_2_shift = input_elements.ordered_range_constraints_2_shift;
135 const auto& ordered_range_constraints_3_shift = input_elements.ordered_range_constraints_3_shift;
136 const auto& ordered_range_constraints_4_shift = input_elements.ordered_range_constraints_4_shift;
137 const auto& lagrange_ordered_masking = input_elements.lagrange_ordered_masking;
138 const auto& lagrange_real_last = input_elements.lagrange_real_last;
139
140 RelationValues expected_values;
141
142 const auto parameters = RelationParameters<FF>::get_random();
143
144 const size_t MICRO_LIMB_BITS = 14;
145 const auto minus_one = FF(-1);
146 const auto minus_two = FF(-2);
147 const auto minus_three = FF(-3);
148 const auto maximum_value = -FF((1 << MICRO_LIMB_BITS) - 1);
149
150 // First compute individual deltas
151 const auto delta_1 = ordered_range_constraints_0_shift - ordered_range_constraints_0;
152 const auto delta_2 = ordered_range_constraints_1_shift - ordered_range_constraints_1;
153 const auto delta_3 = ordered_range_constraints_2_shift - ordered_range_constraints_2;
154 const auto delta_4 = ordered_range_constraints_3_shift - ordered_range_constraints_3;
155 const auto delta_5 = ordered_range_constraints_4_shift - ordered_range_constraints_4;
156
157 const auto not_last_or_masking = lagrange_real_last + lagrange_ordered_masking + minus_one;
158
159 // Check the delta is {0,1,2,3}
160 auto delta_in_range = [&](auto delta) {
161 return not_last_or_masking * delta * (delta + minus_one) * (delta + minus_two) * (delta + minus_three);
162 };
163
164 // Check delta correctness
165 expected_values[0] = delta_in_range(delta_1);
166 expected_values[1] = delta_in_range(delta_2);
167 expected_values[2] = delta_in_range(delta_3);
168 expected_values[3] = delta_in_range(delta_4);
169 expected_values[4] = delta_in_range(delta_5);
170 // Check that the last value is maximum allowed
171 expected_values[5] = lagrange_real_last * (ordered_range_constraints_0 + maximum_value);
172 expected_values[6] = lagrange_real_last * (ordered_range_constraints_1 + maximum_value);
173 expected_values[7] = lagrange_real_last * (ordered_range_constraints_2 + maximum_value);
174 expected_values[8] = lagrange_real_last * (ordered_range_constraints_3 + maximum_value);
175 expected_values[9] = lagrange_real_last * (ordered_range_constraints_4 + maximum_value);
176 // We don't check that the first value is zero, because the shift mechanism already ensures it
177
178 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
179 };
180 run_test(/*random_inputs=*/false);
181 run_test(/*random_inputs=*/true);
182};
183
184TEST_F(TranslatorRelationConsistency, ShiftableFirstCoeffZeroRelation)
185{
186 const auto run_test = [](bool random_inputs) {
188 using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations;
189
190 const InputElements input_elements = random_inputs ? get_random_input() : get_special_input();
191
192 const auto& ordered_range_constraints_0 = input_elements.ordered_range_constraints_0;
193 const auto& ordered_range_constraints_1 = input_elements.ordered_range_constraints_1;
194 const auto& ordered_range_constraints_2 = input_elements.ordered_range_constraints_2;
195 const auto& ordered_range_constraints_3 = input_elements.ordered_range_constraints_3;
196 const auto& ordered_range_constraints_4 = input_elements.ordered_range_constraints_4;
197 const auto& lagrange_first = input_elements.lagrange_first;
198
199 RelationValues expected_values;
200
201 const auto parameters = RelationParameters<FF>::get_random();
202
203 // Each ordered_range_constraints wire must be zero at the first row (lower endpoint of the sorted range).
204 expected_values[0] = lagrange_first * ordered_range_constraints_0;
205 expected_values[1] = lagrange_first * ordered_range_constraints_1;
206 expected_values[2] = lagrange_first * ordered_range_constraints_2;
207 expected_values[3] = lagrange_first * ordered_range_constraints_3;
208 expected_values[4] = lagrange_first * ordered_range_constraints_4;
209
210 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
211 };
212 run_test(/*random_inputs=*/false);
213 run_test(/*random_inputs=*/true);
214};
215
217{
218 const auto run_test = [](bool random_inputs) {
220 using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations;
221
222 const InputElements input_elements = random_inputs ? get_random_input() : get_special_input();
223
224 // Get all the wires
225 const auto& p_x_low_limbs_range_constraint_0 = input_elements.p_x_low_limbs_range_constraint_0;
226 const auto& p_x_low_limbs_range_constraint_1 = input_elements.p_x_low_limbs_range_constraint_1;
227 const auto& p_x_low_limbs_range_constraint_2 = input_elements.p_x_low_limbs_range_constraint_2;
228 const auto& p_x_low_limbs_range_constraint_3 = input_elements.p_x_low_limbs_range_constraint_3;
229 const auto& p_x_low_limbs_range_constraint_4 = input_elements.p_x_low_limbs_range_constraint_4;
230 const auto& p_x_low_limbs_range_constraint_tail = input_elements.p_x_low_limbs_range_constraint_tail;
231 const auto& p_x_low_limbs = input_elements.p_x_low_limbs;
232 const auto& p_x_high_limbs_range_constraint_0 = input_elements.p_x_high_limbs_range_constraint_0;
233 const auto& p_x_high_limbs_range_constraint_1 = input_elements.p_x_high_limbs_range_constraint_1;
234 const auto& p_x_high_limbs_range_constraint_2 = input_elements.p_x_high_limbs_range_constraint_2;
235 const auto& p_x_high_limbs_range_constraint_3 = input_elements.p_x_high_limbs_range_constraint_3;
236 const auto& p_x_high_limbs_range_constraint_4 = input_elements.p_x_high_limbs_range_constraint_4;
237 const auto& p_x_high_limbs_range_constraint_tail = input_elements.p_x_high_limbs_range_constraint_tail;
238 const auto& p_x_high_limbs = input_elements.p_x_high_limbs;
239 const auto& p_x_low_limbs_range_constraint_0_shift = input_elements.p_x_low_limbs_range_constraint_0_shift;
240 const auto& p_x_low_limbs_range_constraint_1_shift = input_elements.p_x_low_limbs_range_constraint_1_shift;
241 const auto& p_x_low_limbs_range_constraint_2_shift = input_elements.p_x_low_limbs_range_constraint_2_shift;
242 const auto& p_x_low_limbs_range_constraint_3_shift = input_elements.p_x_low_limbs_range_constraint_3_shift;
243 const auto& p_x_low_limbs_range_constraint_4_shift = input_elements.p_x_low_limbs_range_constraint_4_shift;
244 const auto& p_x_low_limbs_range_constraint_tail_shift =
245 input_elements.p_x_low_limbs_range_constraint_tail_shift;
246 const auto& p_x_low_limbs_shift = input_elements.p_x_low_limbs_shift;
247 const auto& p_x_high_limbs_range_constraint_0_shift = input_elements.p_x_high_limbs_range_constraint_0_shift;
248 const auto& p_x_high_limbs_range_constraint_1_shift = input_elements.p_x_high_limbs_range_constraint_1_shift;
249 const auto& p_x_high_limbs_range_constraint_2_shift = input_elements.p_x_high_limbs_range_constraint_2_shift;
250 const auto& p_x_high_limbs_range_constraint_3_shift = input_elements.p_x_high_limbs_range_constraint_3_shift;
251 const auto& p_x_high_limbs_range_constraint_4_shift = input_elements.p_x_high_limbs_range_constraint_4_shift;
252 const auto& p_x_high_limbs_range_constraint_tail_shift =
253 input_elements.p_x_high_limbs_range_constraint_tail_shift;
254 const auto& p_x_high_limbs_shift = input_elements.p_x_high_limbs_shift;
255 const auto& p_y_low_limbs_range_constraint_0 = input_elements.p_y_low_limbs_range_constraint_0;
256 const auto& p_y_low_limbs_range_constraint_1 = input_elements.p_y_low_limbs_range_constraint_1;
257 const auto& p_y_low_limbs_range_constraint_2 = input_elements.p_y_low_limbs_range_constraint_2;
258 const auto& p_y_low_limbs_range_constraint_3 = input_elements.p_y_low_limbs_range_constraint_3;
259 const auto& p_y_low_limbs_range_constraint_4 = input_elements.p_y_low_limbs_range_constraint_4;
260 const auto& p_y_low_limbs_range_constraint_tail = input_elements.p_y_low_limbs_range_constraint_tail;
261 const auto& p_y_low_limbs = input_elements.p_y_low_limbs;
262 const auto& p_y_high_limbs_range_constraint_0 = input_elements.p_y_high_limbs_range_constraint_0;
263 const auto& p_y_high_limbs_range_constraint_1 = input_elements.p_y_high_limbs_range_constraint_1;
264 const auto& p_y_high_limbs_range_constraint_2 = input_elements.p_y_high_limbs_range_constraint_2;
265 const auto& p_y_high_limbs_range_constraint_3 = input_elements.p_y_high_limbs_range_constraint_3;
266 const auto& p_y_high_limbs_range_constraint_4 = input_elements.p_y_high_limbs_range_constraint_4;
267 const auto& p_y_high_limbs_range_constraint_tail = input_elements.p_y_high_limbs_range_constraint_tail;
268 const auto& p_y_high_limbs = input_elements.p_y_high_limbs;
269 const auto& p_y_low_limbs_range_constraint_0_shift = input_elements.p_y_low_limbs_range_constraint_0_shift;
270 const auto& p_y_low_limbs_range_constraint_1_shift = input_elements.p_y_low_limbs_range_constraint_1_shift;
271 const auto& p_y_low_limbs_range_constraint_2_shift = input_elements.p_y_low_limbs_range_constraint_2_shift;
272 const auto& p_y_low_limbs_range_constraint_3_shift = input_elements.p_y_low_limbs_range_constraint_3_shift;
273 const auto& p_y_low_limbs_range_constraint_4_shift = input_elements.p_y_low_limbs_range_constraint_4_shift;
274 const auto& p_y_low_limbs_range_constraint_tail_shift =
275 input_elements.p_y_low_limbs_range_constraint_tail_shift;
276 const auto& p_y_low_limbs_shift = input_elements.p_y_low_limbs_shift;
277 const auto& p_y_high_limbs_range_constraint_0_shift = input_elements.p_y_high_limbs_range_constraint_0_shift;
278 const auto& p_y_high_limbs_range_constraint_1_shift = input_elements.p_y_high_limbs_range_constraint_1_shift;
279 const auto& p_y_high_limbs_range_constraint_2_shift = input_elements.p_y_high_limbs_range_constraint_2_shift;
280 const auto& p_y_high_limbs_range_constraint_3_shift = input_elements.p_y_high_limbs_range_constraint_3_shift;
281 const auto& p_y_high_limbs_range_constraint_4_shift = input_elements.p_y_high_limbs_range_constraint_4_shift;
282 const auto& p_y_high_limbs_range_constraint_tail_shift =
283 input_elements.p_y_high_limbs_range_constraint_tail_shift;
284 const auto& p_y_high_limbs_shift = input_elements.p_y_high_limbs_shift;
285 const auto& z_low_limbs_range_constraint_0 = input_elements.z_low_limbs_range_constraint_0;
286 const auto& z_low_limbs_range_constraint_1 = input_elements.z_low_limbs_range_constraint_1;
287 const auto& z_low_limbs_range_constraint_2 = input_elements.z_low_limbs_range_constraint_2;
288 const auto& z_low_limbs_range_constraint_3 = input_elements.z_low_limbs_range_constraint_3;
289 const auto& z_low_limbs_range_constraint_4 = input_elements.z_low_limbs_range_constraint_4;
290 const auto& z_low_limbs_range_constraint_tail = input_elements.z_low_limbs_range_constraint_tail;
291 const auto& z_low_limbs = input_elements.z_low_limbs;
292 const auto& z_low_limbs_range_constraint_0_shift = input_elements.z_low_limbs_range_constraint_0_shift;
293 const auto& z_low_limbs_range_constraint_1_shift = input_elements.z_low_limbs_range_constraint_1_shift;
294 const auto& z_low_limbs_range_constraint_2_shift = input_elements.z_low_limbs_range_constraint_2_shift;
295 const auto& z_low_limbs_range_constraint_3_shift = input_elements.z_low_limbs_range_constraint_3_shift;
296 const auto& z_low_limbs_range_constraint_4_shift = input_elements.z_low_limbs_range_constraint_4_shift;
297 const auto& z_low_limbs_range_constraint_tail_shift = input_elements.z_low_limbs_range_constraint_tail_shift;
298 const auto& z_low_limbs_shift = input_elements.z_low_limbs_shift;
299 const auto& z_high_limbs_range_constraint_0 = input_elements.z_high_limbs_range_constraint_0;
300 const auto& z_high_limbs_range_constraint_1 = input_elements.z_high_limbs_range_constraint_1;
301 const auto& z_high_limbs_range_constraint_2 = input_elements.z_high_limbs_range_constraint_2;
302 const auto& z_high_limbs_range_constraint_3 = input_elements.z_high_limbs_range_constraint_3;
303 const auto& z_high_limbs_range_constraint_4 = input_elements.z_high_limbs_range_constraint_4;
304 const auto& z_high_limbs_range_constraint_tail = input_elements.z_high_limbs_range_constraint_tail;
305 const auto& z_high_limbs = input_elements.z_high_limbs;
306 const auto& z_high_limbs_range_constraint_0_shift = input_elements.z_high_limbs_range_constraint_0_shift;
307 const auto& z_high_limbs_range_constraint_1_shift = input_elements.z_high_limbs_range_constraint_1_shift;
308 const auto& z_high_limbs_range_constraint_2_shift = input_elements.z_high_limbs_range_constraint_2_shift;
309 const auto& z_high_limbs_range_constraint_3_shift = input_elements.z_high_limbs_range_constraint_3_shift;
310 const auto& z_high_limbs_range_constraint_4_shift = input_elements.z_high_limbs_range_constraint_4_shift;
311 const auto& z_high_limbs_range_constraint_tail_shift = input_elements.z_high_limbs_range_constraint_tail_shift;
312 const auto& z_high_limbs_shift = input_elements.z_high_limbs_shift;
313 const auto& accumulator_low_limbs_range_constraint_0 = input_elements.accumulator_low_limbs_range_constraint_0;
314 const auto& accumulator_low_limbs_range_constraint_1 = input_elements.accumulator_low_limbs_range_constraint_1;
315 const auto& accumulator_low_limbs_range_constraint_2 = input_elements.accumulator_low_limbs_range_constraint_2;
316 const auto& accumulator_low_limbs_range_constraint_3 = input_elements.accumulator_low_limbs_range_constraint_3;
317 const auto& accumulator_low_limbs_range_constraint_4 = input_elements.accumulator_low_limbs_range_constraint_4;
318 const auto& accumulator_low_limbs_range_constraint_tail =
319 input_elements.accumulator_low_limbs_range_constraint_tail;
320 const auto& accumulator_low_limbs_range_constraint_0_shift =
321 input_elements.accumulator_low_limbs_range_constraint_0_shift;
322 const auto& accumulator_low_limbs_range_constraint_1_shift =
323 input_elements.accumulator_low_limbs_range_constraint_1_shift;
324 const auto& accumulator_low_limbs_range_constraint_2_shift =
325 input_elements.accumulator_low_limbs_range_constraint_2_shift;
326 const auto& accumulator_low_limbs_range_constraint_3_shift =
327 input_elements.accumulator_low_limbs_range_constraint_3_shift;
328 const auto& accumulator_low_limbs_range_constraint_4_shift =
329 input_elements.accumulator_low_limbs_range_constraint_4_shift;
330 const auto& accumulator_low_limbs_range_constraint_tail_shift =
331 input_elements.accumulator_low_limbs_range_constraint_tail_shift;
332 const auto& accumulator_high_limbs_range_constraint_0 =
333 input_elements.accumulator_high_limbs_range_constraint_0;
334 const auto& accumulator_high_limbs_range_constraint_1 =
335 input_elements.accumulator_high_limbs_range_constraint_1;
336 const auto& accumulator_high_limbs_range_constraint_2 =
337 input_elements.accumulator_high_limbs_range_constraint_2;
338 const auto& accumulator_high_limbs_range_constraint_3 =
339 input_elements.accumulator_high_limbs_range_constraint_3;
340 const auto& accumulator_high_limbs_range_constraint_4 =
341 input_elements.accumulator_high_limbs_range_constraint_4;
342 const auto& accumulator_high_limbs_range_constraint_tail =
343 input_elements.accumulator_high_limbs_range_constraint_tail;
344 const auto& accumulator_high_limbs_range_constraint_0_shift =
345 input_elements.accumulator_high_limbs_range_constraint_0_shift;
346 const auto& accumulator_high_limbs_range_constraint_1_shift =
347 input_elements.accumulator_high_limbs_range_constraint_1_shift;
348 const auto& accumulator_high_limbs_range_constraint_2_shift =
349 input_elements.accumulator_high_limbs_range_constraint_2_shift;
350 const auto& accumulator_high_limbs_range_constraint_3_shift =
351 input_elements.accumulator_high_limbs_range_constraint_3_shift;
352 const auto& accumulator_high_limbs_range_constraint_4_shift =
353 input_elements.accumulator_high_limbs_range_constraint_4_shift;
354 const auto& accumulator_high_limbs_range_constraint_tail_shift =
355 input_elements.accumulator_high_limbs_range_constraint_tail_shift;
356 const auto& accumulators_binary_limbs_0 = input_elements.accumulators_binary_limbs_0;
357 const auto& accumulators_binary_limbs_1 = input_elements.accumulators_binary_limbs_1;
358 const auto& accumulators_binary_limbs_2 = input_elements.accumulators_binary_limbs_2;
359 const auto& accumulators_binary_limbs_3 = input_elements.accumulators_binary_limbs_3;
360 const auto& quotient_low_limbs_range_constraint_0 = input_elements.quotient_low_limbs_range_constraint_0;
361 const auto& quotient_low_limbs_range_constraint_1 = input_elements.quotient_low_limbs_range_constraint_1;
362 const auto& quotient_low_limbs_range_constraint_2 = input_elements.quotient_low_limbs_range_constraint_2;
363 const auto& quotient_low_limbs_range_constraint_3 = input_elements.quotient_low_limbs_range_constraint_3;
364 const auto& quotient_low_limbs_range_constraint_4 = input_elements.quotient_low_limbs_range_constraint_4;
365 const auto& quotient_low_limbs_range_constraint_tail = input_elements.quotient_low_limbs_range_constraint_tail;
366 const auto& quotient_low_limbs_range_constraint_0_shift =
367 input_elements.quotient_low_limbs_range_constraint_0_shift;
368 const auto& quotient_low_limbs_range_constraint_1_shift =
369 input_elements.quotient_low_limbs_range_constraint_1_shift;
370 const auto& quotient_low_limbs_range_constraint_2_shift =
371 input_elements.quotient_low_limbs_range_constraint_2_shift;
372 const auto& quotient_low_limbs_range_constraint_3_shift =
373 input_elements.quotient_low_limbs_range_constraint_3_shift;
374 const auto& quotient_low_limbs_range_constraint_4_shift =
375 input_elements.quotient_low_limbs_range_constraint_4_shift;
376 const auto& quotient_low_limbs_range_constraint_tail_shift =
377 input_elements.quotient_low_limbs_range_constraint_tail_shift;
378 const auto& quotient_high_limbs_range_constraint_0 = input_elements.quotient_high_limbs_range_constraint_0;
379 const auto& quotient_high_limbs_range_constraint_1 = input_elements.quotient_high_limbs_range_constraint_1;
380 const auto& quotient_high_limbs_range_constraint_2 = input_elements.quotient_high_limbs_range_constraint_2;
381 const auto& quotient_high_limbs_range_constraint_3 = input_elements.quotient_high_limbs_range_constraint_3;
382 const auto& quotient_high_limbs_range_constraint_4 = input_elements.quotient_high_limbs_range_constraint_4;
383 const auto& quotient_high_limbs_range_constraint_tail =
384 input_elements.quotient_high_limbs_range_constraint_tail;
385 const auto& quotient_high_limbs_range_constraint_0_shift =
386 input_elements.quotient_high_limbs_range_constraint_0_shift;
387 const auto& quotient_high_limbs_range_constraint_1_shift =
388 input_elements.quotient_high_limbs_range_constraint_1_shift;
389 const auto& quotient_high_limbs_range_constraint_2_shift =
390 input_elements.quotient_high_limbs_range_constraint_2_shift;
391 const auto& quotient_high_limbs_range_constraint_3_shift =
392 input_elements.quotient_high_limbs_range_constraint_3_shift;
393 const auto& quotient_high_limbs_range_constraint_4_shift =
394 input_elements.quotient_high_limbs_range_constraint_4_shift;
395 const auto& quotient_high_limbs_range_constraint_tail_shift =
396 input_elements.quotient_high_limbs_range_constraint_tail_shift;
397 const auto& quotient_low_binary_limbs = input_elements.quotient_low_binary_limbs;
398 const auto& quotient_low_binary_limbs_shift = input_elements.quotient_low_binary_limbs_shift;
399 const auto& quotient_high_binary_limbs = input_elements.quotient_high_binary_limbs;
400 const auto& quotient_high_binary_limbs_shift = input_elements.quotient_high_binary_limbs_shift;
401 const auto& relation_wide_limbs_range_constraint_0 = input_elements.relation_wide_limbs_range_constraint_0;
402 const auto& relation_wide_limbs_range_constraint_1 = input_elements.relation_wide_limbs_range_constraint_1;
403 const auto& relation_wide_limbs_range_constraint_2 = input_elements.relation_wide_limbs_range_constraint_2;
404 const auto& relation_wide_limbs_range_constraint_3 = input_elements.relation_wide_limbs_range_constraint_3;
405 const auto& relation_wide_limbs_range_constraint_0_shift =
406 input_elements.relation_wide_limbs_range_constraint_0_shift;
407 const auto& relation_wide_limbs_range_constraint_1_shift =
408 input_elements.relation_wide_limbs_range_constraint_1_shift;
409 const auto& relation_wide_limbs_range_constraint_2_shift =
410 input_elements.relation_wide_limbs_range_constraint_2_shift;
411 const auto& relation_wide_limbs_range_constraint_3_shift =
412 input_elements.relation_wide_limbs_range_constraint_3_shift;
413 const auto& relation_wide_limbs = input_elements.relation_wide_limbs;
414 const auto& relation_wide_limbs_shift = input_elements.relation_wide_limbs_shift;
415
416 const auto& x_lo_y_hi = input_elements.x_lo_y_hi;
417 const auto& x_hi_z_1 = input_elements.x_hi_z_1;
418 const auto& y_lo_z_2 = input_elements.y_lo_z_2;
419 const auto& x_lo_y_hi_shift = input_elements.x_lo_y_hi_shift;
420 const auto& x_hi_z_1_shift = input_elements.x_hi_z_1_shift;
421 const auto& y_lo_z_2_shift = input_elements.y_lo_z_2_shift;
422 const auto& op = input_elements.op;
423
424 const auto& lagrange_even_in_minicircuit = input_elements.lagrange_even_in_minicircuit;
425
426 RelationValues expected_values;
427
428 const auto parameters = RelationParameters<FF>::get_random();
429
430 const size_t NUM_MICRO_LIMB_BITS = 14;
431 const size_t NUM_LIMB_BITS = 68;
432 const auto MICRO_LIMB_SHIFT = FF(uint256_t(1) << NUM_MICRO_LIMB_BITS);
433 const auto MICRO_LIMB_SHIFTx2 = MICRO_LIMB_SHIFT * MICRO_LIMB_SHIFT;
434 const auto MICRO_LIMB_SHIFTx3 = MICRO_LIMB_SHIFTx2 * MICRO_LIMB_SHIFT;
435 const auto MICRO_LIMB_SHIFTx4 = MICRO_LIMB_SHIFTx3 * MICRO_LIMB_SHIFT;
436 const auto MICRO_LIMB_SHIFTx5 = MICRO_LIMB_SHIFTx4 * MICRO_LIMB_SHIFT;
437
438 const auto SHIFT_10_TO_14 = FF(1 << 4);
439 const auto SHIFT_12_TO_14 = FF(1 << 2);
440 const auto SHIFT_4_TO_14 = FF(1 << 10);
441 const auto SHIFT_8_TO_14 = FF(1 << 6);
442 const auto LIMB_SHIFT = FF(uint256_t(1) << NUM_LIMB_BITS);
443
444 // All decomposition happen only at odd indices, so we use lagrange odd
450 auto check_relation_limb_decomposition = [MICRO_LIMB_SHIFT,
451 MICRO_LIMB_SHIFTx2,
452 MICRO_LIMB_SHIFTx3,
453 MICRO_LIMB_SHIFTx4,
454 MICRO_LIMB_SHIFTx5,
455 lagrange_even_in_minicircuit](auto& micro_limb_0,
456 auto& micro_limb_1,
457 auto& micro_limb_2,
458 auto& micro_limb_3,
459 auto& micro_limb_4,
460 auto& micro_limb_5,
461 auto& decomposed_limb) {
462 return (micro_limb_0 + micro_limb_1 * MICRO_LIMB_SHIFT + micro_limb_2 * MICRO_LIMB_SHIFTx2 +
463 micro_limb_3 * MICRO_LIMB_SHIFTx3 + micro_limb_4 * MICRO_LIMB_SHIFTx4 +
464 micro_limb_5 * MICRO_LIMB_SHIFTx5 - decomposed_limb) *
465 lagrange_even_in_minicircuit;
466 };
467
473 auto check_standard_limb_decomposition = [MICRO_LIMB_SHIFT,
474 MICRO_LIMB_SHIFTx2,
475 MICRO_LIMB_SHIFTx3,
476 MICRO_LIMB_SHIFTx4,
477 lagrange_even_in_minicircuit](auto& micro_limb_0,
478 auto& micro_limb_1,
479 auto& micro_limb_2,
480 auto& micro_limb_3,
481 auto& micro_limb_4,
482 auto& decomposed_limb) {
483 return (micro_limb_0 + micro_limb_1 * MICRO_LIMB_SHIFT + micro_limb_2 * MICRO_LIMB_SHIFTx2 +
484 micro_limb_3 * MICRO_LIMB_SHIFTx3 + micro_limb_4 * MICRO_LIMB_SHIFTx4 - decomposed_limb) *
485 lagrange_even_in_minicircuit;
486 };
487
492 auto check_standard_top_limb_decomposition =
493 [MICRO_LIMB_SHIFT, MICRO_LIMB_SHIFTx2, MICRO_LIMB_SHIFTx3, lagrange_even_in_minicircuit](
494 auto& micro_limb_0, auto& micro_limb_1, auto& micro_limb_2, auto& micro_limb_3, auto& decomposed_limb) {
495 return (micro_limb_0 + micro_limb_1 * MICRO_LIMB_SHIFT + micro_limb_2 * MICRO_LIMB_SHIFTx2 +
496 micro_limb_3 * MICRO_LIMB_SHIFTx3 - decomposed_limb) *
497 lagrange_even_in_minicircuit;
498 };
499
505 auto check_standard_tail_micro_limb_correctness =
506 [SHIFT_12_TO_14, lagrange_even_in_minicircuit](auto& nonshifted_micro_limb, auto shifted_micro_limb) {
507 return (nonshifted_micro_limb * SHIFT_12_TO_14 - shifted_micro_limb) * lagrange_even_in_minicircuit;
508 };
509
515 auto check_top_tail_micro_limb_correctness =
516 [SHIFT_8_TO_14, lagrange_even_in_minicircuit](auto& nonshifted_micro_limb, auto shifted_micro_limb) {
517 return (nonshifted_micro_limb * SHIFT_8_TO_14 - shifted_micro_limb) * lagrange_even_in_minicircuit;
518 };
519
525 auto check_z_top_tail_micro_limb_correctness =
526 [SHIFT_4_TO_14, lagrange_even_in_minicircuit](auto& nonshifted_micro_limb, auto shifted_micro_limb) {
527 return (nonshifted_micro_limb * SHIFT_4_TO_14 - shifted_micro_limb) * lagrange_even_in_minicircuit;
528 };
529
535 auto check_quotient_top_tail_micro_limb_correctness =
536 [SHIFT_10_TO_14, lagrange_even_in_minicircuit](auto& nonshifted_micro_limb, auto shifted_micro_limb) {
537 return (nonshifted_micro_limb * SHIFT_10_TO_14 - shifted_micro_limb) * lagrange_even_in_minicircuit;
538 };
539
544 auto check_wide_limb_into_regular_limb_correctness =
545 [LIMB_SHIFT, lagrange_even_in_minicircuit](auto& low_limb, auto& high_limb, auto& wide_limb) {
546 return (low_limb + high_limb * LIMB_SHIFT - wide_limb) * lagrange_even_in_minicircuit;
547 };
548
549 // Check decomposition 50-72 bit limbs into microlimbs
550 expected_values[0] = op * check_standard_limb_decomposition(accumulator_low_limbs_range_constraint_0,
551 accumulator_low_limbs_range_constraint_1,
552 accumulator_low_limbs_range_constraint_2,
553 accumulator_low_limbs_range_constraint_3,
554 accumulator_low_limbs_range_constraint_4,
555 accumulators_binary_limbs_0);
556 expected_values[1] = op * check_standard_limb_decomposition(accumulator_low_limbs_range_constraint_0_shift,
557 accumulator_low_limbs_range_constraint_1_shift,
558 accumulator_low_limbs_range_constraint_2_shift,
559 accumulator_low_limbs_range_constraint_3_shift,
560 accumulator_low_limbs_range_constraint_4_shift,
561 accumulators_binary_limbs_1);
562 expected_values[2] = op * check_standard_limb_decomposition(accumulator_high_limbs_range_constraint_0,
563 accumulator_high_limbs_range_constraint_1,
564 accumulator_high_limbs_range_constraint_2,
565 accumulator_high_limbs_range_constraint_3,
566 accumulator_high_limbs_range_constraint_4,
567 accumulators_binary_limbs_2);
568 expected_values[3] = op * check_standard_top_limb_decomposition(accumulator_high_limbs_range_constraint_0_shift,
569 accumulator_high_limbs_range_constraint_1_shift,
570 accumulator_high_limbs_range_constraint_2_shift,
571 accumulator_high_limbs_range_constraint_3_shift,
572 accumulators_binary_limbs_3);
573
574 expected_values[4] = check_standard_limb_decomposition(p_y_low_limbs_range_constraint_0,
575 p_y_low_limbs_range_constraint_1,
576 p_y_low_limbs_range_constraint_2,
577 p_y_low_limbs_range_constraint_3,
578 p_y_low_limbs_range_constraint_4,
579 p_y_low_limbs);
580 expected_values[5] = check_standard_limb_decomposition(p_y_low_limbs_range_constraint_0_shift,
581 p_y_low_limbs_range_constraint_1_shift,
582 p_y_low_limbs_range_constraint_2_shift,
583 p_y_low_limbs_range_constraint_3_shift,
584 p_y_low_limbs_range_constraint_4_shift,
585 p_y_low_limbs_shift);
586 expected_values[6] = check_standard_limb_decomposition(p_y_high_limbs_range_constraint_0,
587 p_y_high_limbs_range_constraint_1,
588 p_y_high_limbs_range_constraint_2,
589 p_y_high_limbs_range_constraint_3,
590 p_y_high_limbs_range_constraint_4,
591 p_y_high_limbs);
592 expected_values[7] = check_standard_top_limb_decomposition(p_y_high_limbs_range_constraint_0_shift,
593 p_y_high_limbs_range_constraint_1_shift,
594 p_y_high_limbs_range_constraint_2_shift,
595 p_y_high_limbs_range_constraint_3_shift,
596 p_y_high_limbs_shift);
597 expected_values[8] = check_standard_limb_decomposition(z_low_limbs_range_constraint_0,
598 z_low_limbs_range_constraint_1,
599 z_low_limbs_range_constraint_2,
600 z_low_limbs_range_constraint_3,
601 z_low_limbs_range_constraint_4,
602 z_low_limbs);
603 expected_values[9] = check_standard_limb_decomposition(z_low_limbs_range_constraint_0_shift,
604 z_low_limbs_range_constraint_1_shift,
605 z_low_limbs_range_constraint_2_shift,
606 z_low_limbs_range_constraint_3_shift,
607 z_low_limbs_range_constraint_4_shift,
608 z_low_limbs_shift);
609 expected_values[10] = check_standard_limb_decomposition(z_high_limbs_range_constraint_0,
610 z_high_limbs_range_constraint_1,
611 z_high_limbs_range_constraint_2,
612 z_high_limbs_range_constraint_3,
613 z_high_limbs_range_constraint_4,
614 z_high_limbs);
615 expected_values[11] = check_standard_limb_decomposition(z_high_limbs_range_constraint_0_shift,
616 z_high_limbs_range_constraint_1_shift,
617 z_high_limbs_range_constraint_2_shift,
618 z_high_limbs_range_constraint_3_shift,
619 z_high_limbs_range_constraint_4_shift,
620 z_high_limbs_shift);
621 expected_values[12] = check_standard_limb_decomposition(p_x_low_limbs_range_constraint_0,
622 p_x_low_limbs_range_constraint_1,
623 p_x_low_limbs_range_constraint_2,
624 p_x_low_limbs_range_constraint_3,
625 p_x_low_limbs_range_constraint_4,
626 p_x_low_limbs);
627 expected_values[13] = check_standard_limb_decomposition(p_x_low_limbs_range_constraint_0_shift,
628 p_x_low_limbs_range_constraint_1_shift,
629 p_x_low_limbs_range_constraint_2_shift,
630 p_x_low_limbs_range_constraint_3_shift,
631 p_x_low_limbs_range_constraint_4_shift,
632 p_x_low_limbs_shift);
633 expected_values[14] = check_standard_limb_decomposition(p_x_high_limbs_range_constraint_0,
634 p_x_high_limbs_range_constraint_1,
635 p_x_high_limbs_range_constraint_2,
636 p_x_high_limbs_range_constraint_3,
637 p_x_high_limbs_range_constraint_4,
638 p_x_high_limbs);
639 expected_values[15] = check_standard_top_limb_decomposition(p_x_high_limbs_range_constraint_0_shift,
640 p_x_high_limbs_range_constraint_1_shift,
641 p_x_high_limbs_range_constraint_2_shift,
642 p_x_high_limbs_range_constraint_3_shift,
643 p_x_high_limbs_shift);
644
645 expected_values[16] = check_standard_limb_decomposition(quotient_low_limbs_range_constraint_0,
646 quotient_low_limbs_range_constraint_1,
647 quotient_low_limbs_range_constraint_2,
648 quotient_low_limbs_range_constraint_3,
649 quotient_low_limbs_range_constraint_4,
650 quotient_low_binary_limbs);
651 expected_values[17] = check_standard_limb_decomposition(quotient_low_limbs_range_constraint_0_shift,
652 quotient_low_limbs_range_constraint_1_shift,
653 quotient_low_limbs_range_constraint_2_shift,
654 quotient_low_limbs_range_constraint_3_shift,
655 quotient_low_limbs_range_constraint_4_shift,
656 quotient_low_binary_limbs_shift);
657 expected_values[18] = check_standard_limb_decomposition(quotient_high_limbs_range_constraint_0,
658 quotient_high_limbs_range_constraint_1,
659 quotient_high_limbs_range_constraint_2,
660 quotient_high_limbs_range_constraint_3,
661 quotient_high_limbs_range_constraint_4,
662 quotient_high_binary_limbs);
663 expected_values[19] = check_standard_top_limb_decomposition(quotient_high_limbs_range_constraint_0_shift,
664 quotient_high_limbs_range_constraint_1_shift,
665 quotient_high_limbs_range_constraint_2_shift,
666 quotient_high_limbs_range_constraint_3_shift,
667 quotient_high_binary_limbs_shift);
668
669 expected_values[20] = check_relation_limb_decomposition(relation_wide_limbs_range_constraint_0,
670 relation_wide_limbs_range_constraint_1,
671 relation_wide_limbs_range_constraint_2,
672 relation_wide_limbs_range_constraint_3,
673 p_x_high_limbs_range_constraint_tail_shift,
674 accumulator_high_limbs_range_constraint_tail_shift,
675 relation_wide_limbs);
676 expected_values[21] = check_relation_limb_decomposition(relation_wide_limbs_range_constraint_0_shift,
677 relation_wide_limbs_range_constraint_1_shift,
678 relation_wide_limbs_range_constraint_2_shift,
679 relation_wide_limbs_range_constraint_3_shift,
680 p_y_high_limbs_range_constraint_tail_shift,
681 quotient_high_limbs_range_constraint_tail_shift,
682 relation_wide_limbs_shift);
683
684 // Contributions enforcing tail range constraints (range constraints less than 14 bits)
685 expected_values[22] = check_standard_tail_micro_limb_correctness(p_x_low_limbs_range_constraint_4,
686 p_x_low_limbs_range_constraint_tail);
687
688 expected_values[23] = check_standard_tail_micro_limb_correctness(p_x_low_limbs_range_constraint_4_shift,
689 p_x_low_limbs_range_constraint_tail_shift);
690
691 expected_values[24] = check_standard_tail_micro_limb_correctness(p_x_high_limbs_range_constraint_4,
692 p_x_high_limbs_range_constraint_tail);
693
694 expected_values[25] = check_top_tail_micro_limb_correctness(p_x_high_limbs_range_constraint_3_shift,
695 p_x_high_limbs_range_constraint_4_shift);
696
697 expected_values[26] = check_standard_tail_micro_limb_correctness(p_y_low_limbs_range_constraint_4,
698 p_y_low_limbs_range_constraint_tail);
699
700 expected_values[27] = check_standard_tail_micro_limb_correctness(p_y_low_limbs_range_constraint_4_shift,
701 p_y_low_limbs_range_constraint_tail_shift);
702
703 expected_values[28] = check_standard_tail_micro_limb_correctness(p_y_high_limbs_range_constraint_4,
704 p_y_high_limbs_range_constraint_tail);
705
706 expected_values[29] = check_top_tail_micro_limb_correctness(p_y_high_limbs_range_constraint_3_shift,
707 p_y_high_limbs_range_constraint_4_shift);
708
709 expected_values[30] = check_standard_tail_micro_limb_correctness(z_low_limbs_range_constraint_4,
710 z_low_limbs_range_constraint_tail);
711
712 expected_values[31] = check_standard_tail_micro_limb_correctness(z_low_limbs_range_constraint_4_shift,
713 z_low_limbs_range_constraint_tail_shift);
714
715 expected_values[32] = check_z_top_tail_micro_limb_correctness(z_high_limbs_range_constraint_4,
716 z_high_limbs_range_constraint_tail);
717
718 expected_values[33] = check_z_top_tail_micro_limb_correctness(z_high_limbs_range_constraint_4_shift,
719 z_high_limbs_range_constraint_tail_shift);
720
721 expected_values[34] = check_standard_tail_micro_limb_correctness(accumulator_low_limbs_range_constraint_4,
722 accumulator_low_limbs_range_constraint_tail);
723 expected_values[35] = check_standard_tail_micro_limb_correctness(
724 accumulator_low_limbs_range_constraint_4_shift, accumulator_low_limbs_range_constraint_tail_shift);
725
726 expected_values[36] = check_standard_tail_micro_limb_correctness(accumulator_high_limbs_range_constraint_4,
727 accumulator_high_limbs_range_constraint_tail);
728
729 expected_values[37] = check_top_tail_micro_limb_correctness(accumulator_high_limbs_range_constraint_3_shift,
730 accumulator_high_limbs_range_constraint_4_shift);
731
732 expected_values[38] = check_standard_tail_micro_limb_correctness(quotient_low_limbs_range_constraint_4,
733 quotient_low_limbs_range_constraint_tail);
734
735 expected_values[39] = check_standard_tail_micro_limb_correctness(
736 quotient_low_limbs_range_constraint_4_shift, quotient_low_limbs_range_constraint_tail_shift);
737
738 expected_values[40] = check_standard_tail_micro_limb_correctness(quotient_high_limbs_range_constraint_4,
739 quotient_high_limbs_range_constraint_tail);
740
741 expected_values[41] = check_quotient_top_tail_micro_limb_correctness(
742 quotient_high_limbs_range_constraint_3_shift, quotient_high_limbs_range_constraint_4_shift);
743
744 // Constraints for decomposition of EccOpQueue values
745
746 expected_values[42] =
747 check_wide_limb_into_regular_limb_correctness(p_x_low_limbs, p_x_low_limbs_shift, x_lo_y_hi);
748
749 expected_values[43] =
750 check_wide_limb_into_regular_limb_correctness(p_x_high_limbs, p_x_high_limbs_shift, x_hi_z_1);
751
752 expected_values[44] =
753 check_wide_limb_into_regular_limb_correctness(p_y_low_limbs, p_y_low_limbs_shift, y_lo_z_2);
754
755 expected_values[45] =
756 check_wide_limb_into_regular_limb_correctness(p_y_high_limbs, p_y_high_limbs_shift, x_lo_y_hi_shift);
757
758 expected_values[46] = check_wide_limb_into_regular_limb_correctness(z_low_limbs, z_high_limbs, x_hi_z_1_shift);
759
760 expected_values[47] =
761 check_wide_limb_into_regular_limb_correctness(z_low_limbs_shift, z_high_limbs_shift, y_lo_z_2_shift);
762
763 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
764 };
765 run_test(/*random_inputs=*/false);
766 run_test(/*random_inputs=*/true);
767};
768
769TEST_F(TranslatorRelationConsistency, OpcodeConstraintRelation)
770{
771 const auto run_test = [](bool random_inputs) {
773 using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations;
774
775 const InputElements input_elements = random_inputs ? get_random_input() : get_special_input();
776 const auto& op = input_elements.op;
777 const auto& accumulators_binary_limbs_0 = input_elements.accumulators_binary_limbs_0;
778 const auto& accumulators_binary_limbs_1 = input_elements.accumulators_binary_limbs_1;
779 const auto& accumulators_binary_limbs_2 = input_elements.accumulators_binary_limbs_2;
780 const auto& accumulators_binary_limbs_3 = input_elements.accumulators_binary_limbs_3;
781 const auto& accumulators_binary_limbs_0_shift = input_elements.accumulators_binary_limbs_0_shift;
782 const auto& accumulators_binary_limbs_1_shift = input_elements.accumulators_binary_limbs_1_shift;
783 const auto& accumulators_binary_limbs_2_shift = input_elements.accumulators_binary_limbs_2_shift;
784 const auto& accumulators_binary_limbs_3_shift = input_elements.accumulators_binary_limbs_3_shift;
785
786 const auto& lagrange_even_in_minicircuit = input_elements.lagrange_even_in_minicircuit;
787 const auto& lagrange_odd_in_minicircuit = input_elements.lagrange_odd_in_minicircuit;
788
789 RelationValues expected_values;
790
791 const auto parameters = RelationParameters<FF>::get_random();
792
793 // Opcode constraints - on even rows: op is 0, 3, 4, or 8; on odd rows: op is 0
794 expected_values[0] = op * (op - FF(3)) * (op - FF(4)) * (op - FF(8)) * lagrange_even_in_minicircuit +
795 op * lagrange_odd_in_minicircuit;
796
797 auto shared = (op - FF(3)) * (op - FF(4)) * (op - FF(8)) * lagrange_even_in_minicircuit;
798 expected_values[1] = shared * (accumulators_binary_limbs_0 - accumulators_binary_limbs_0_shift);
799 expected_values[2] = shared * (accumulators_binary_limbs_1 - accumulators_binary_limbs_1_shift);
800 expected_values[3] = shared * (accumulators_binary_limbs_2 - accumulators_binary_limbs_2_shift);
801 expected_values[4] = shared * (accumulators_binary_limbs_3 - accumulators_binary_limbs_3_shift);
802
803 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
804 };
805 run_test(/*random_inputs=*/false);
806 run_test(/*random_inputs=*/true);
807};
808
809TEST_F(TranslatorRelationConsistency, AccumulatorTransferRelation)
810{
811 const auto run_test = [](bool random_inputs) {
813 using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations;
814
815 const InputElements input_elements = random_inputs ? get_random_input() : get_special_input();
816
817 const auto& lagrange_odd_in_minicircuit = input_elements.lagrange_odd_in_minicircuit;
818 const auto& lagrange_result_row = input_elements.lagrange_result_row;
819 const auto& lagrange_last_in_minicircuit = input_elements.lagrange_last_in_minicircuit;
820 const auto& accumulators_binary_limbs_0 = input_elements.accumulators_binary_limbs_0;
821 const auto& accumulators_binary_limbs_0_shift = input_elements.accumulators_binary_limbs_0_shift;
822 const auto& accumulators_binary_limbs_1 = input_elements.accumulators_binary_limbs_1;
823 const auto& accumulators_binary_limbs_1_shift = input_elements.accumulators_binary_limbs_1_shift;
824 const auto& accumulators_binary_limbs_2 = input_elements.accumulators_binary_limbs_2;
825 const auto& accumulators_binary_limbs_2_shift = input_elements.accumulators_binary_limbs_2_shift;
826 const auto& accumulators_binary_limbs_3 = input_elements.accumulators_binary_limbs_3;
827 const auto& accumulators_binary_limbs_3_shift = input_elements.accumulators_binary_limbs_3_shift;
828
829 RelationValues expected_values;
830
831 const auto parameters = RelationParameters<FF>::get_random();
832
833 const auto [accumulated_result_0, accumulated_result_1, accumulated_result_2, accumulated_result_3] =
834 parameters.accumulated_result;
835
836 // Check transfer of accumulator at even indices
837 expected_values[0] = lagrange_odd_in_minicircuit * (lagrange_last_in_minicircuit - FF(1)) *
838 (accumulators_binary_limbs_0 - accumulators_binary_limbs_0_shift);
839 expected_values[1] = lagrange_odd_in_minicircuit * (lagrange_last_in_minicircuit - FF(1)) *
840 (accumulators_binary_limbs_1 - accumulators_binary_limbs_1_shift);
841 expected_values[2] = lagrange_odd_in_minicircuit * (lagrange_last_in_minicircuit - FF(1)) *
842 (accumulators_binary_limbs_2 - accumulators_binary_limbs_2_shift);
843 expected_values[3] = lagrange_odd_in_minicircuit * (lagrange_last_in_minicircuit - FF(1)) *
844 (accumulators_binary_limbs_3 - accumulators_binary_limbs_3_shift);
845
846 // Check the accumulator starts as zero
847 expected_values[4] = accumulators_binary_limbs_0 * lagrange_last_in_minicircuit;
848 expected_values[5] = accumulators_binary_limbs_1 * lagrange_last_in_minicircuit;
849 expected_values[6] = accumulators_binary_limbs_2 * lagrange_last_in_minicircuit;
850 expected_values[7] = accumulators_binary_limbs_3 * lagrange_last_in_minicircuit;
851
852 // Check the accumulator results in submitted value
853 expected_values[8] = (accumulators_binary_limbs_0 - accumulated_result_0) * lagrange_result_row;
854 expected_values[9] = (accumulators_binary_limbs_1 - accumulated_result_1) * lagrange_result_row;
855 expected_values[10] = (accumulators_binary_limbs_2 - accumulated_result_2) * lagrange_result_row;
856 expected_values[11] = (accumulators_binary_limbs_3 - accumulated_result_3) * lagrange_result_row;
857 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
858 };
859 run_test(/*random_inputs=*/false);
860 run_test(/*random_inputs=*/true);
861};
862
863TEST_F(TranslatorRelationConsistency, ZeroConstraintsRelation)
864{
865 const auto run_test = [](bool random_inputs) {
867 using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations;
868
869 const InputElements input_elements = random_inputs ? get_random_input() : get_special_input();
870
871 // Get all the wires
872 const auto& p_x_low_limbs_range_constraint_0 = input_elements.p_x_low_limbs_range_constraint_0;
873 const auto& p_x_low_limbs_range_constraint_1 = input_elements.p_x_low_limbs_range_constraint_1;
874 const auto& p_x_low_limbs_range_constraint_2 = input_elements.p_x_low_limbs_range_constraint_2;
875 const auto& p_x_low_limbs_range_constraint_3 = input_elements.p_x_low_limbs_range_constraint_3;
876 const auto& p_x_low_limbs_range_constraint_4 = input_elements.p_x_low_limbs_range_constraint_4;
877 const auto& p_x_low_limbs_range_constraint_tail = input_elements.p_x_low_limbs_range_constraint_tail;
878 const auto& p_x_high_limbs_range_constraint_0 = input_elements.p_x_high_limbs_range_constraint_0;
879 const auto& p_x_high_limbs_range_constraint_1 = input_elements.p_x_high_limbs_range_constraint_1;
880 const auto& p_x_high_limbs_range_constraint_2 = input_elements.p_x_high_limbs_range_constraint_2;
881 const auto& p_x_high_limbs_range_constraint_3 = input_elements.p_x_high_limbs_range_constraint_3;
882 const auto& p_x_high_limbs_range_constraint_4 = input_elements.p_x_high_limbs_range_constraint_4;
883 const auto& p_x_high_limbs_range_constraint_tail = input_elements.p_x_high_limbs_range_constraint_tail;
884 const auto& p_y_low_limbs_range_constraint_0 = input_elements.p_y_low_limbs_range_constraint_0;
885 const auto& p_y_low_limbs_range_constraint_1 = input_elements.p_y_low_limbs_range_constraint_1;
886 const auto& p_y_low_limbs_range_constraint_2 = input_elements.p_y_low_limbs_range_constraint_2;
887 const auto& p_y_low_limbs_range_constraint_3 = input_elements.p_y_low_limbs_range_constraint_3;
888 const auto& p_y_low_limbs_range_constraint_4 = input_elements.p_y_low_limbs_range_constraint_4;
889 const auto& p_y_low_limbs_range_constraint_tail = input_elements.p_y_low_limbs_range_constraint_tail;
890 const auto& p_y_high_limbs_range_constraint_0 = input_elements.p_y_high_limbs_range_constraint_0;
891 const auto& p_y_high_limbs_range_constraint_1 = input_elements.p_y_high_limbs_range_constraint_1;
892 const auto& p_y_high_limbs_range_constraint_2 = input_elements.p_y_high_limbs_range_constraint_2;
893 const auto& p_y_high_limbs_range_constraint_3 = input_elements.p_y_high_limbs_range_constraint_3;
894 const auto& p_y_high_limbs_range_constraint_4 = input_elements.p_y_high_limbs_range_constraint_4;
895 const auto& p_y_high_limbs_range_constraint_tail = input_elements.p_y_high_limbs_range_constraint_tail;
896 const auto& z_low_limbs_range_constraint_0 = input_elements.z_low_limbs_range_constraint_0;
897 const auto& z_low_limbs_range_constraint_1 = input_elements.z_low_limbs_range_constraint_1;
898 const auto& z_low_limbs_range_constraint_2 = input_elements.z_low_limbs_range_constraint_2;
899 const auto& z_low_limbs_range_constraint_3 = input_elements.z_low_limbs_range_constraint_3;
900 const auto& z_low_limbs_range_constraint_4 = input_elements.z_low_limbs_range_constraint_4;
901 const auto& z_low_limbs_range_constraint_tail = input_elements.z_low_limbs_range_constraint_tail;
902 const auto& z_high_limbs_range_constraint_0 = input_elements.z_high_limbs_range_constraint_0;
903 const auto& z_high_limbs_range_constraint_1 = input_elements.z_high_limbs_range_constraint_1;
904 const auto& z_high_limbs_range_constraint_2 = input_elements.z_high_limbs_range_constraint_2;
905 const auto& z_high_limbs_range_constraint_3 = input_elements.z_high_limbs_range_constraint_3;
906 const auto& z_high_limbs_range_constraint_4 = input_elements.z_high_limbs_range_constraint_4;
907 const auto& z_high_limbs_range_constraint_tail = input_elements.z_high_limbs_range_constraint_tail;
908 const auto& accumulator_low_limbs_range_constraint_0 = input_elements.accumulator_low_limbs_range_constraint_0;
909 const auto& accumulator_low_limbs_range_constraint_1 = input_elements.accumulator_low_limbs_range_constraint_1;
910 const auto& accumulator_low_limbs_range_constraint_2 = input_elements.accumulator_low_limbs_range_constraint_2;
911 const auto& accumulator_low_limbs_range_constraint_3 = input_elements.accumulator_low_limbs_range_constraint_3;
912 const auto& accumulator_low_limbs_range_constraint_4 = input_elements.accumulator_low_limbs_range_constraint_4;
913 const auto& accumulator_low_limbs_range_constraint_tail =
914 input_elements.accumulator_low_limbs_range_constraint_tail;
915 const auto& accumulator_high_limbs_range_constraint_0 =
916 input_elements.accumulator_high_limbs_range_constraint_0;
917 const auto& accumulator_high_limbs_range_constraint_1 =
918 input_elements.accumulator_high_limbs_range_constraint_1;
919 const auto& accumulator_high_limbs_range_constraint_2 =
920 input_elements.accumulator_high_limbs_range_constraint_2;
921 const auto& accumulator_high_limbs_range_constraint_3 =
922 input_elements.accumulator_high_limbs_range_constraint_3;
923 const auto& accumulator_high_limbs_range_constraint_4 =
924 input_elements.accumulator_high_limbs_range_constraint_4;
925 const auto& accumulator_high_limbs_range_constraint_tail =
926 input_elements.accumulator_high_limbs_range_constraint_tail;
927 const auto& quotient_low_limbs_range_constraint_0 = input_elements.quotient_low_limbs_range_constraint_0;
928 const auto& quotient_low_limbs_range_constraint_1 = input_elements.quotient_low_limbs_range_constraint_1;
929 const auto& quotient_low_limbs_range_constraint_2 = input_elements.quotient_low_limbs_range_constraint_2;
930 const auto& quotient_low_limbs_range_constraint_3 = input_elements.quotient_low_limbs_range_constraint_3;
931 const auto& quotient_low_limbs_range_constraint_4 = input_elements.quotient_low_limbs_range_constraint_4;
932 const auto& quotient_low_limbs_range_constraint_tail = input_elements.quotient_low_limbs_range_constraint_tail;
933 const auto& quotient_high_limbs_range_constraint_0 = input_elements.quotient_high_limbs_range_constraint_0;
934 const auto& quotient_high_limbs_range_constraint_1 = input_elements.quotient_high_limbs_range_constraint_1;
935 const auto& quotient_high_limbs_range_constraint_2 = input_elements.quotient_high_limbs_range_constraint_2;
936 const auto& quotient_high_limbs_range_constraint_3 = input_elements.quotient_high_limbs_range_constraint_3;
937 const auto& quotient_high_limbs_range_constraint_4 = input_elements.quotient_high_limbs_range_constraint_4;
938 const auto& quotient_high_limbs_range_constraint_tail =
939 input_elements.quotient_high_limbs_range_constraint_tail;
940 const auto& relation_wide_limbs_range_constraint_0 = input_elements.relation_wide_limbs_range_constraint_0;
941 const auto& relation_wide_limbs_range_constraint_1 = input_elements.relation_wide_limbs_range_constraint_1;
942 const auto& relation_wide_limbs_range_constraint_2 = input_elements.relation_wide_limbs_range_constraint_2;
943 const auto& relation_wide_limbs_range_constraint_3 = input_elements.relation_wide_limbs_range_constraint_3;
944 const auto& op = input_elements.op;
945 const auto& x_lo_y_hi = input_elements.x_lo_y_hi;
946 const auto& x_hi_z_1 = input_elements.x_hi_z_1;
947 const auto& y_lo_z_2 = input_elements.y_lo_z_2;
948 const auto& lagrange_odd_in_minicircuit = input_elements.lagrange_odd_in_minicircuit;
949 const auto& lagrange_even_in_minicircuit = input_elements.lagrange_even_in_minicircuit;
950 const auto& lagrange_mini_masking = input_elements.lagrange_mini_masking;
951
952 RelationValues expected_values;
953
954 const auto parameters = RelationParameters<FF>::get_random();
955
956 // 0 in the minicircuit, -1 outside (matches the implementation)
957 const auto not_in_minicircuit_or_masked =
958 lagrange_even_in_minicircuit + lagrange_odd_in_minicircuit + lagrange_mini_masking - FF(1);
959
960 expected_values[0] = not_in_minicircuit_or_masked * p_x_low_limbs_range_constraint_0;
961 expected_values[1] = not_in_minicircuit_or_masked * p_x_low_limbs_range_constraint_1;
962 expected_values[2] = not_in_minicircuit_or_masked * p_x_low_limbs_range_constraint_2;
963 expected_values[3] = not_in_minicircuit_or_masked * p_x_low_limbs_range_constraint_3;
964 expected_values[4] = not_in_minicircuit_or_masked * p_x_low_limbs_range_constraint_4;
965 expected_values[5] = not_in_minicircuit_or_masked * p_x_high_limbs_range_constraint_0;
966 expected_values[6] = not_in_minicircuit_or_masked * p_x_high_limbs_range_constraint_1;
967 expected_values[7] = not_in_minicircuit_or_masked * p_x_high_limbs_range_constraint_2;
968 expected_values[8] = not_in_minicircuit_or_masked * p_x_high_limbs_range_constraint_3;
969 expected_values[9] = not_in_minicircuit_or_masked * p_x_high_limbs_range_constraint_4;
970 expected_values[10] = not_in_minicircuit_or_masked * p_y_low_limbs_range_constraint_0;
971 expected_values[11] = not_in_minicircuit_or_masked * p_y_low_limbs_range_constraint_1;
972 expected_values[12] = not_in_minicircuit_or_masked * p_y_low_limbs_range_constraint_2;
973 expected_values[13] = not_in_minicircuit_or_masked * p_y_low_limbs_range_constraint_3;
974 expected_values[14] = not_in_minicircuit_or_masked * p_y_low_limbs_range_constraint_4;
975 expected_values[15] = not_in_minicircuit_or_masked * p_y_high_limbs_range_constraint_0;
976 expected_values[16] = not_in_minicircuit_or_masked * p_y_high_limbs_range_constraint_1;
977 expected_values[17] = not_in_minicircuit_or_masked * p_y_high_limbs_range_constraint_2;
978 expected_values[18] = not_in_minicircuit_or_masked * p_y_high_limbs_range_constraint_3;
979 expected_values[19] = not_in_minicircuit_or_masked * p_y_high_limbs_range_constraint_4;
980 expected_values[20] = not_in_minicircuit_or_masked * z_low_limbs_range_constraint_0;
981 expected_values[21] = not_in_minicircuit_or_masked * z_low_limbs_range_constraint_1;
982 expected_values[22] = not_in_minicircuit_or_masked * z_low_limbs_range_constraint_2;
983 expected_values[23] = not_in_minicircuit_or_masked * z_low_limbs_range_constraint_3;
984 expected_values[24] = not_in_minicircuit_or_masked * z_low_limbs_range_constraint_4;
985 expected_values[25] = not_in_minicircuit_or_masked * z_high_limbs_range_constraint_0;
986 expected_values[26] = not_in_minicircuit_or_masked * z_high_limbs_range_constraint_1;
987 expected_values[27] = not_in_minicircuit_or_masked * z_high_limbs_range_constraint_2;
988 expected_values[28] = not_in_minicircuit_or_masked * z_high_limbs_range_constraint_3;
989 expected_values[29] = not_in_minicircuit_or_masked * z_high_limbs_range_constraint_4;
990 expected_values[30] = not_in_minicircuit_or_masked * accumulator_low_limbs_range_constraint_0;
991 expected_values[31] = not_in_minicircuit_or_masked * accumulator_low_limbs_range_constraint_1;
992 expected_values[32] = not_in_minicircuit_or_masked * accumulator_low_limbs_range_constraint_2;
993 expected_values[33] = not_in_minicircuit_or_masked * accumulator_low_limbs_range_constraint_3;
994 expected_values[34] = not_in_minicircuit_or_masked * accumulator_low_limbs_range_constraint_4;
995 expected_values[35] = not_in_minicircuit_or_masked * accumulator_high_limbs_range_constraint_0;
996 expected_values[36] = not_in_minicircuit_or_masked * accumulator_high_limbs_range_constraint_1;
997 expected_values[37] = not_in_minicircuit_or_masked * accumulator_high_limbs_range_constraint_2;
998 expected_values[38] = not_in_minicircuit_or_masked * accumulator_high_limbs_range_constraint_3;
999 expected_values[39] = not_in_minicircuit_or_masked * accumulator_high_limbs_range_constraint_4;
1000 expected_values[40] = not_in_minicircuit_or_masked * quotient_low_limbs_range_constraint_0;
1001 expected_values[41] = not_in_minicircuit_or_masked * quotient_low_limbs_range_constraint_1;
1002 expected_values[42] = not_in_minicircuit_or_masked * quotient_low_limbs_range_constraint_2;
1003 expected_values[43] = not_in_minicircuit_or_masked * quotient_low_limbs_range_constraint_3;
1004 expected_values[44] = not_in_minicircuit_or_masked * quotient_low_limbs_range_constraint_4;
1005 expected_values[45] = not_in_minicircuit_or_masked * quotient_high_limbs_range_constraint_0;
1006 expected_values[46] = not_in_minicircuit_or_masked * quotient_high_limbs_range_constraint_1;
1007 expected_values[47] = not_in_minicircuit_or_masked * quotient_high_limbs_range_constraint_2;
1008 expected_values[48] = not_in_minicircuit_or_masked * quotient_high_limbs_range_constraint_3;
1009 expected_values[49] = not_in_minicircuit_or_masked * quotient_high_limbs_range_constraint_4;
1010 expected_values[50] = not_in_minicircuit_or_masked * relation_wide_limbs_range_constraint_0;
1011 expected_values[51] = not_in_minicircuit_or_masked * relation_wide_limbs_range_constraint_1;
1012 expected_values[52] = not_in_minicircuit_or_masked * relation_wide_limbs_range_constraint_2;
1013 expected_values[53] = not_in_minicircuit_or_masked * relation_wide_limbs_range_constraint_3;
1014 expected_values[54] = not_in_minicircuit_or_masked * p_x_low_limbs_range_constraint_tail;
1015 expected_values[55] = not_in_minicircuit_or_masked * p_x_high_limbs_range_constraint_tail;
1016 expected_values[56] = not_in_minicircuit_or_masked * p_y_low_limbs_range_constraint_tail;
1017 expected_values[57] = not_in_minicircuit_or_masked * p_y_high_limbs_range_constraint_tail;
1018 expected_values[58] = not_in_minicircuit_or_masked * z_low_limbs_range_constraint_tail;
1019 expected_values[59] = not_in_minicircuit_or_masked * z_high_limbs_range_constraint_tail;
1020 expected_values[60] = not_in_minicircuit_or_masked * accumulator_low_limbs_range_constraint_tail;
1021 expected_values[61] = not_in_minicircuit_or_masked * accumulator_high_limbs_range_constraint_tail;
1022 expected_values[62] = not_in_minicircuit_or_masked * quotient_low_limbs_range_constraint_tail;
1023 expected_values[63] = not_in_minicircuit_or_masked * quotient_high_limbs_range_constraint_tail;
1024 expected_values[64] = not_in_minicircuit_or_masked * op;
1025 expected_values[65] = not_in_minicircuit_or_masked * x_lo_y_hi;
1026 expected_values[66] = not_in_minicircuit_or_masked * x_hi_z_1;
1027 expected_values[67] = not_in_minicircuit_or_masked * y_lo_z_2;
1028
1029 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
1030 };
1031 run_test(/*random_inputs=*/false);
1032 run_test(/*random_inputs=*/true);
1033};
1034
1036{
1037 const auto run_test = [](bool random_inputs) {
1038 const size_t NUM_LIMB_BITS = 68;
1039 const FF shift = FF(uint256_t(1) << NUM_LIMB_BITS);
1040 const FF shiftx2 = FF(uint256_t(1) << (NUM_LIMB_BITS * 2));
1041 const FF shiftx3 = FF(uint256_t(1) << (NUM_LIMB_BITS * 3));
1043 const uint512_t BINARY_BASIS_MODULUS = uint512_t(1) << (NUM_LIMB_BITS << 2);
1044 const uint512_t NEGATIVE_PRIME_MODULUS = BINARY_BASIS_MODULUS - MODULUS_U512;
1045 const std::array<FF, 5> NEGATIVE_MODULUS_LIMBS = {
1046 FF(NEGATIVE_PRIME_MODULUS.slice(0, NUM_LIMB_BITS).lo),
1047 FF(NEGATIVE_PRIME_MODULUS.slice(NUM_LIMB_BITS, NUM_LIMB_BITS * 2).lo),
1048 FF(NEGATIVE_PRIME_MODULUS.slice(NUM_LIMB_BITS * 2, NUM_LIMB_BITS * 3).lo),
1049 FF(NEGATIVE_PRIME_MODULUS.slice(NUM_LIMB_BITS * 3, NUM_LIMB_BITS * 4).lo),
1051 };
1052
1054 using RelationValues = typename Relation::SumcheckArrayOfValuesOverSubrelations;
1055
1056 const InputElements input_elements = random_inputs ? get_random_input() : get_special_input();
1057
1058 auto& op = input_elements.op;
1059 auto& p_x_low_limbs = input_elements.p_x_low_limbs;
1060 auto& p_y_low_limbs = input_elements.p_y_low_limbs;
1061 auto& p_x_high_limbs = input_elements.p_x_high_limbs;
1062 auto& p_y_high_limbs = input_elements.p_y_high_limbs;
1063 auto& accumulators_binary_limbs_0 = input_elements.accumulators_binary_limbs_0;
1064 auto& accumulators_binary_limbs_1 = input_elements.accumulators_binary_limbs_1;
1065 auto& accumulators_binary_limbs_2 = input_elements.accumulators_binary_limbs_2;
1066 auto& accumulators_binary_limbs_3 = input_elements.accumulators_binary_limbs_3;
1067 auto& z_low_limbs = input_elements.z_low_limbs;
1068 auto& z_high_limbs = input_elements.z_high_limbs;
1069 auto& quotient_low_binary_limbs = input_elements.quotient_low_binary_limbs;
1070 auto& quotient_high_binary_limbs = input_elements.quotient_high_binary_limbs;
1071 auto& p_x_low_limbs_shift = input_elements.p_x_low_limbs_shift;
1072 auto& p_y_low_limbs_shift = input_elements.p_y_low_limbs_shift;
1073 auto& p_x_high_limbs_shift = input_elements.p_x_high_limbs_shift;
1074 auto& p_y_high_limbs_shift = input_elements.p_y_high_limbs_shift;
1075 auto& accumulators_binary_limbs_0_shift = input_elements.accumulators_binary_limbs_0_shift;
1076 auto& accumulators_binary_limbs_1_shift = input_elements.accumulators_binary_limbs_1_shift;
1077 auto& accumulators_binary_limbs_2_shift = input_elements.accumulators_binary_limbs_2_shift;
1078 auto& accumulators_binary_limbs_3_shift = input_elements.accumulators_binary_limbs_3_shift;
1079 auto& z_low_limbs_shift = input_elements.z_low_limbs_shift;
1080 auto& z_high_limbs_shift = input_elements.z_high_limbs_shift;
1081 auto& quotient_low_binary_limbs_shift = input_elements.quotient_low_binary_limbs_shift;
1082 auto& quotient_high_binary_limbs_shift = input_elements.quotient_high_binary_limbs_shift;
1083 auto& relation_wide_limbs = input_elements.relation_wide_limbs;
1084 auto& relation_wide_limbs_shift = input_elements.relation_wide_limbs_shift;
1085 auto& lagrange_even_in_minicircuit = input_elements.lagrange_even_in_minicircuit;
1086
1087 RelationValues expected_values;
1088
1089 const auto parameters = RelationParameters<FF>::get_random();
1090
1091 // A detailed description of these subrelations is located in the relation's documentation
1092
1093 // Lower wide limb (lower 136 bits) subrelation
1094 expected_values[0] =
1095 (accumulators_binary_limbs_0_shift * parameters.evaluation_input_x[0] + op +
1096 p_x_low_limbs * parameters.batching_challenge_v[0][0] +
1097 p_y_low_limbs * parameters.batching_challenge_v[1][0] +
1098 z_low_limbs * parameters.batching_challenge_v[2][0] +
1099 z_low_limbs_shift * parameters.batching_challenge_v[3][0] +
1100 quotient_low_binary_limbs * NEGATIVE_MODULUS_LIMBS[0] - accumulators_binary_limbs_0 +
1101 (accumulators_binary_limbs_1_shift * parameters.evaluation_input_x[0] +
1102 accumulators_binary_limbs_0_shift * parameters.evaluation_input_x[1] +
1103 p_x_low_limbs * parameters.batching_challenge_v[0][1] +
1104 p_x_low_limbs_shift * parameters.batching_challenge_v[0][0] +
1105 p_y_low_limbs * parameters.batching_challenge_v[1][1] +
1106 p_y_low_limbs_shift * parameters.batching_challenge_v[1][0] +
1107 z_low_limbs * parameters.batching_challenge_v[2][1] +
1108 z_high_limbs * parameters.batching_challenge_v[2][0] +
1109 z_low_limbs_shift * parameters.batching_challenge_v[3][1] +
1110 z_high_limbs_shift * parameters.batching_challenge_v[3][0] +
1111 quotient_low_binary_limbs * NEGATIVE_MODULUS_LIMBS[1] +
1112 quotient_low_binary_limbs_shift * NEGATIVE_MODULUS_LIMBS[0] - accumulators_binary_limbs_1) *
1113 shift -
1114 relation_wide_limbs * shiftx2) *
1115 lagrange_even_in_minicircuit * op;
1116
1117 // Higher wide limb subrelation
1118 expected_values[1] =
1119 (relation_wide_limbs + accumulators_binary_limbs_2_shift * parameters.evaluation_input_x[0] +
1120 accumulators_binary_limbs_1_shift * parameters.evaluation_input_x[1] +
1121 accumulators_binary_limbs_0_shift * parameters.evaluation_input_x[2] +
1122 p_x_high_limbs * parameters.batching_challenge_v[0][0] +
1123 p_x_low_limbs_shift * parameters.batching_challenge_v[0][1] +
1124 p_x_low_limbs * parameters.batching_challenge_v[0][2] +
1125 p_y_high_limbs * parameters.batching_challenge_v[1][0] +
1126 p_y_low_limbs_shift * parameters.batching_challenge_v[1][1] +
1127 p_y_low_limbs * parameters.batching_challenge_v[1][2] +
1128 z_high_limbs * parameters.batching_challenge_v[2][1] +
1129 z_low_limbs * parameters.batching_challenge_v[2][2] +
1130 z_high_limbs_shift * parameters.batching_challenge_v[3][1] +
1131 z_low_limbs_shift * parameters.batching_challenge_v[3][2] +
1132 quotient_high_binary_limbs * NEGATIVE_MODULUS_LIMBS[0] +
1133 quotient_low_binary_limbs_shift * NEGATIVE_MODULUS_LIMBS[1] +
1134 quotient_low_binary_limbs * NEGATIVE_MODULUS_LIMBS[2] - accumulators_binary_limbs_2 +
1135 (accumulators_binary_limbs_3_shift * parameters.evaluation_input_x[0] +
1136 accumulators_binary_limbs_2_shift * parameters.evaluation_input_x[1] +
1137 accumulators_binary_limbs_1_shift * parameters.evaluation_input_x[2] +
1138 accumulators_binary_limbs_0_shift * parameters.evaluation_input_x[3] +
1139 p_x_high_limbs_shift * parameters.batching_challenge_v[0][0] +
1140 p_x_high_limbs * parameters.batching_challenge_v[0][1] +
1141 p_x_low_limbs_shift * parameters.batching_challenge_v[0][2] +
1142 p_x_low_limbs * parameters.batching_challenge_v[0][3] +
1143 p_y_high_limbs_shift * parameters.batching_challenge_v[1][0] +
1144 p_y_high_limbs * parameters.batching_challenge_v[1][1] +
1145 p_y_low_limbs_shift * parameters.batching_challenge_v[1][2] +
1146 p_y_low_limbs * parameters.batching_challenge_v[1][3] +
1147 z_high_limbs * parameters.batching_challenge_v[2][2] +
1148 z_low_limbs * parameters.batching_challenge_v[2][3] +
1149 z_high_limbs_shift * parameters.batching_challenge_v[3][2] +
1150 z_low_limbs_shift * parameters.batching_challenge_v[3][3] +
1151 quotient_high_binary_limbs_shift * NEGATIVE_MODULUS_LIMBS[0] +
1152 quotient_high_binary_limbs * NEGATIVE_MODULUS_LIMBS[1] +
1153 quotient_low_binary_limbs_shift * NEGATIVE_MODULUS_LIMBS[2] +
1154 quotient_low_binary_limbs * NEGATIVE_MODULUS_LIMBS[3] - accumulators_binary_limbs_3) *
1155 shift -
1156 relation_wide_limbs_shift * shiftx2) *
1157 lagrange_even_in_minicircuit * op;
1158 auto reconstructed_p_x =
1159 (p_x_low_limbs + p_x_low_limbs_shift * shift + p_x_high_limbs * shiftx2 + p_x_high_limbs_shift * shiftx3);
1160 auto reconstructed_p_y =
1161 (p_y_low_limbs + p_y_low_limbs_shift * shift + p_y_high_limbs * shiftx2 + p_y_high_limbs_shift * shiftx3);
1162 auto reconstructed_previous_accumulator =
1163 (accumulators_binary_limbs_0_shift + accumulators_binary_limbs_1_shift * shift +
1164 accumulators_binary_limbs_2_shift * shiftx2 + accumulators_binary_limbs_3_shift * shiftx3);
1165 auto reconstructed_current_accumulator =
1166 (accumulators_binary_limbs_0 + accumulators_binary_limbs_1 * shift + accumulators_binary_limbs_2 * shiftx2 +
1167 accumulators_binary_limbs_3 * shiftx3);
1168 auto reconstructed_z1 = (z_low_limbs + z_high_limbs * shift);
1169 auto reconstructed_z2 = (z_low_limbs_shift + z_high_limbs_shift * shift);
1170 auto reconstructed_quotient =
1171 (quotient_low_binary_limbs + quotient_low_binary_limbs_shift * shift +
1172 quotient_high_binary_limbs * shiftx2 + quotient_high_binary_limbs_shift * shiftx3);
1173
1174 // Native field relation
1175 expected_values[2] = (reconstructed_previous_accumulator * parameters.evaluation_input_x[4] + op +
1176 reconstructed_p_x * parameters.batching_challenge_v[0][4] +
1177 reconstructed_p_y * parameters.batching_challenge_v[1][4] +
1178 reconstructed_z1 * parameters.batching_challenge_v[2][4] +
1179 reconstructed_z2 * parameters.batching_challenge_v[3][4] +
1180 reconstructed_quotient * NEGATIVE_MODULUS_LIMBS[4] - reconstructed_current_accumulator) *
1181 lagrange_even_in_minicircuit * op;
1182
1183 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
1184 };
1185 run_test(/*random_inputs=*/false);
1186 run_test(/*random_inputs=*/true);
1187};
static void validate_relation_execution(const auto &expected_values, const InputElements &input_elements, const auto &parameters)
A field element for each entity of the flavor. These entities represent the prover polynomials evalua...
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
ArrayOfValues< FF, RelationImpl::SUBRELATION_PARTIAL_LENGTHS > SumcheckArrayOfValuesOverSubrelations
Curve::ScalarField FF
constexpr uintx slice(const uint64_t start, const uint64_t end) const
Definition uintx.hpp:81
uintx< uint256_t > uint512_t
Definition uintx.hpp:309
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:160
constexpr ScalarIndex shift(ScalarIndex ctx, size_t d)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static RelationParameters get_random()
static constexpr uint256_t modulus
static field random_element(numeric::RNG *engine=nullptr) noexcept
typename Flavor::FF FF
InputElements get_random_input()
InputElements get_special_input()
typename Flavor::AllValues InputElements
VectorField result