117 InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
118 const auto& w_1 = input_elements.
w_l;
119 const auto& w_1_shift = input_elements.
w_l_shift;
120 const auto& w_2 = input_elements.
w_r;
121 const auto& w_3 = input_elements.
w_o;
122 const auto& w_4 = input_elements.
w_4;
123 const auto& w_4_shift = input_elements.
w_4_shift;
124 const auto& q_m = input_elements.
q_m;
125 const auto& q_l = input_elements.
q_l;
126 const auto& q_r = input_elements.
q_r;
127 const auto& q_o = input_elements.
q_o;
128 const auto& q_4 = input_elements.
q_4;
129 const auto& q_c = input_elements.
q_c;
132 input_elements.
q_arith = q_arith_value;
133 const auto& q_arith = input_elements.
q_arith;
135 SumcheckArrayOfValuesOverSubrelations expected_values;
138 FF contribution_1 =
FF(0);
139 FF contribution_2 =
FF(0);
140 if (q_arith ==
FF(1)) {
142 contribution_1 = (q_m * w_2 * w_1) + (q_l * w_1) + (q_r * w_2) + (q_o * w_3) + (q_4 * w_4) + q_c;
145 }
else if (q_arith ==
FF(2)) {
147 contribution_1 = (q_m * w_2 * w_1);
148 contribution_1 += ((q_l * w_1) + (q_r * w_2) + (q_o * w_3) + (q_4 * w_4) + w_4_shift + q_c) *
FF(2);
151 }
else if (q_arith ==
FF(3)) {
153 contribution_1 = (q_l * w_1) + (q_r * w_2) + (q_o * w_3) + (q_4 * w_4) + q_c;
154 contribution_1 += w_4_shift *
FF(2);
155 contribution_1 *=
FF(3);
158 contribution_2 = (w_1 + w_4 - w_1_shift + q_m) *
FF(6);
161 contribution_1 = (q_arith - 3) * (q_m * w_2 * w_1) * neg_half;
162 contribution_1 += (q_l * w_1) + (q_r * w_2) + (q_o * w_3) + (q_4 * w_4) + q_c;
163 contribution_1 += (q_arith - 1) * w_4_shift;
164 contribution_1 *= q_arith;
167 contribution_2 = (w_1 + w_4 - w_1_shift + q_m);
168 contribution_2 *= (q_arith - 2) * (q_arith - 1) * q_arith;
171 expected_values[0] = contribution_1;
172 expected_values[1] = contribution_2;
176 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
180 run_test(
true,
FF(1));
181 run_test(
true,
FF(2));
182 run_test(
true,
FF(3));
187 const auto run_test = [](
bool random_inputs) {
191 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
192 const auto& w_1 = input_elements.
w_l;
193 const auto& w_2 = input_elements.
w_r;
194 const auto& w_3 = input_elements.
w_o;
195 const auto& w_4 = input_elements.
w_4;
196 const auto& sigma_1 = input_elements.
sigma_1;
197 const auto& sigma_2 = input_elements.
sigma_2;
198 const auto& sigma_3 = input_elements.
sigma_3;
199 const auto& sigma_4 = input_elements.
sigma_4;
200 const auto& id_1 = input_elements.
id_1;
201 const auto& id_2 = input_elements.
id_2;
202 const auto& id_3 = input_elements.
id_3;
203 const auto& id_4 = input_elements.
id_4;
204 const auto& z_perm = input_elements.
z_perm;
209 SumcheckArrayOfValuesOverSubrelations expected_values;
212 const auto& beta = parameters.beta;
213 const auto& gamma = parameters.gamma;
214 const auto& public_input_delta = parameters.public_input_delta;
217 auto contribution_1 = (z_perm + lagrange_first) * (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) *
218 (w_3 + id_3 * beta + gamma) * (w_4 + id_4 * beta + gamma) -
219 (z_perm_shift + lagrange_last * public_input_delta) * (w_1 + sigma_1 * beta + gamma) *
220 (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma) *
221 (w_4 + sigma_4 * beta + gamma);
222 expected_values[0] = contribution_1;
225 auto contribution_2 = z_perm_shift * lagrange_last;
226 expected_values[1] = contribution_2;
229 auto contribution_3 = lagrange_first * z_perm;
230 expected_values[2] = contribution_3;
232 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
240 const auto run_test = [](
bool random_inputs) {
244 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
245 const auto& w_1 = input_elements.
w_l;
246 const auto& w_2 = input_elements.
w_r;
247 const auto& w_3 = input_elements.
w_o;
248 const auto& w_4 = input_elements.
w_4;
249 const auto& w_1_shift = input_elements.
w_l_shift;
252 auto delta_1 = w_2 - w_1;
253 auto delta_2 = w_3 - w_2;
254 auto delta_3 = w_4 - w_3;
255 auto delta_4 = w_1_shift - w_4;
257 auto contribution_1 = delta_1 * (delta_1 - 1) * (delta_1 - 2) * (delta_1 - 3);
258 auto contribution_2 = delta_2 * (delta_2 - 1) * (delta_2 - 2) * (delta_2 - 3);
259 auto contribution_3 = delta_3 * (delta_3 - 1) * (delta_3 - 2) * (delta_3 - 3);
260 auto contribution_4 = delta_4 * (delta_4 - 1) * (delta_4 - 2) * (delta_4 - 3);
262 SumcheckArrayOfValuesOverSubrelations expected_values;
264 expected_values[0] = contribution_1 * q_delta_range;
265 expected_values[1] = contribution_2 * q_delta_range;
266 expected_values[2] = contribution_3 * q_delta_range;
267 expected_values[3] = contribution_4 * q_delta_range;
271 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
279 const auto run_test = [](
bool random_inputs) {
283 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
285 const auto& x_1 = input_elements.
w_r;
286 const auto& y_1 = input_elements.
w_o;
288 const auto& x_2 = input_elements.
w_l_shift;
289 const auto& y_2 = input_elements.
w_4_shift;
290 const auto& x_3 = input_elements.
w_r_shift;
291 const auto& y_3 = input_elements.
w_o_shift;
296 input_elements.
q_l =
FF(-1);
297 const auto& q_sign = input_elements.
q_l;
298 const auto& q_elliptic = input_elements.
q_elliptic;
299 const auto& q_is_double = input_elements.
q_m;
301 SumcheckArrayOfValuesOverSubrelations expected_values;
304 auto y_diff = (q_sign * y_2 - y_1);
305 auto x_diff = (x_2 - x_1);
306 auto x_diff_sqr = x_diff * x_diff;
307 auto lambda = y_diff / x_diff;
308 auto lambda_sqr = lambda * lambda;
314 auto x_add_identity = (x_3 - lambda_sqr + (x_1 + x_2)) * x_diff_sqr;
319 auto y_add_identity = (y_3 - lambda * (x_1 - x_3) + y_1) * x_diff;
324 auto y1_sqr = (y_1 * y_1);
325 auto x_pow_4 = (y1_sqr - curve_b) * x_1;
326 lambda_sqr = x_pow_4 * 9 / (y1_sqr * 4);
327 lambda = (x_1 * x_1 * 3) / (y_1 * 2);
333 auto x_double_identity = (x_3 - lambda_sqr + x_1 * 2) * (y1_sqr * 4);
339 auto y_double_identity = (y_3 - lambda * (x_1 - x_3) + y_1) * (y_1 * 2) *
FF(-1);
342 expected_values[0] = (x_add_identity * (-q_is_double + 1) + (x_double_identity * q_is_double)) * q_elliptic;
343 expected_values[1] = (y_add_identity * (-q_is_double + 1) + (y_double_identity * q_is_double)) * q_elliptic;
348 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
356 const auto run_test = [](
bool random_inputs) {
360 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
361 const auto& w_1 = input_elements.
w_l;
362 const auto& w_2 = input_elements.
w_r;
363 const auto& w_3 = input_elements.
w_o;
364 const auto& w_4 = input_elements.
w_4;
365 const auto& w_1_shift = input_elements.
w_l_shift;
366 const auto& w_2_shift = input_elements.
w_r_shift;
367 const auto& w_3_shift = input_elements.
w_o_shift;
368 const auto& w_4_shift = input_elements.
w_4_shift;
370 const auto& q_2 = input_elements.
q_r;
371 const auto& q_3 = input_elements.
q_o;
372 const auto& q_4 = input_elements.
q_4;
373 const auto& q_m = input_elements.
q_m;
374 const auto& q_nnf = input_elements.
q_nnf;
378 constexpr FF SUBLIMB_SHIFT_2(SUBLIMB_SHIFT * SUBLIMB_SHIFT);
379 constexpr FF SUBLIMB_SHIFT_3(SUBLIMB_SHIFT_2 * SUBLIMB_SHIFT);
380 constexpr FF SUBLIMB_SHIFT_4(SUBLIMB_SHIFT_3 * SUBLIMB_SHIFT);
382 SumcheckArrayOfValuesOverSubrelations expected_values;
385 auto nnf_gate_1 = (w_1 * w_2_shift + w_1_shift * w_2) * LIMB_SIZE;
386 nnf_gate_1 += (w_1_shift * w_2_shift);
387 nnf_gate_1 -= (w_3 + w_4);
390 auto nnf_gate_2 = (w_1 * w_4 + w_2 * w_3 - w_3_shift) * LIMB_SIZE;
391 nnf_gate_2 -= w_4_shift;
392 nnf_gate_2 += w_1 * w_2_shift + w_1_shift * w_2;
395 auto nnf_gate_3 = (w_1 * w_2_shift + w_1_shift * w_2) * LIMB_SIZE;
396 nnf_gate_3 += (w_1_shift * w_2_shift);
398 nnf_gate_3 -= (w_3_shift + w_4_shift);
400 auto limb_accumulator_1 = w_1 + w_2 * SUBLIMB_SHIFT + w_3 * SUBLIMB_SHIFT_2 + w_1_shift * SUBLIMB_SHIFT_3 +
401 w_2_shift * SUBLIMB_SHIFT_4 - w_4;
403 auto limb_accumulator_2 = w_3 + w_4 * SUBLIMB_SHIFT + w_1_shift * SUBLIMB_SHIFT_2 +
404 w_2_shift * SUBLIMB_SHIFT_3 + w_3_shift * SUBLIMB_SHIFT_4 - w_4_shift;
407 nnf_gate_1 *= (q_2 * q_3);
408 nnf_gate_2 *= (q_2 * q_4);
409 nnf_gate_3 *= (q_2 * q_m);
410 limb_accumulator_1 *= (q_3 * q_4);
411 limb_accumulator_2 *= (q_3 * q_m);
413 auto non_native_field_identity = nnf_gate_1 + nnf_gate_2 + nnf_gate_3;
414 auto limb_accumulator_identity = limb_accumulator_1 + limb_accumulator_2;
416 expected_values[0] = non_native_field_identity + limb_accumulator_identity;
417 expected_values[0] *= q_nnf;
421 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
429 const auto run_test = [](
bool random_inputs) {
433 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
434 const auto& w_1 = input_elements.
w_l;
435 const auto& w_2 = input_elements.
w_r;
436 const auto& w_3 = input_elements.
w_o;
437 const auto& w_4 = input_elements.
w_4;
438 const auto& w_1_shift = input_elements.
w_l_shift;
439 const auto& w_2_shift = input_elements.
w_r_shift;
440 const auto& w_3_shift = input_elements.
w_o_shift;
441 const auto& w_4_shift = input_elements.
w_4_shift;
443 const auto& q_1 = input_elements.
q_l;
444 const auto& q_2 = input_elements.
q_r;
445 const auto& q_3 = input_elements.
q_o;
446 const auto& q_4 = input_elements.
q_4;
447 const auto& q_m = input_elements.
q_m;
448 const auto& q_c = input_elements.
q_c;
449 const auto& q_memory = input_elements.
q_memory;
452 const auto& eta = parameters.eta;
453 const auto& eta_two = parameters.eta_two;
454 const auto& eta_three = parameters.eta_three;
456 SumcheckArrayOfValuesOverSubrelations expected_values;
461 auto memory_record_check = w_3 * eta_three;
462 memory_record_check += w_2 * eta_two;
463 memory_record_check += w_1 * eta;
464 memory_record_check += q_c;
465 auto partial_record_check = memory_record_check;
466 memory_record_check = memory_record_check - w_4;
471 auto index_delta = w_1_shift - w_1;
472 auto record_delta = w_4_shift - w_4;
474 auto index_is_monotonically_increasing = index_delta * index_delta - index_delta;
477 auto adjacent_values_match_if_adjacent_indices_match = (index_delta *
FF(-1) +
FF(1)) * record_delta;
479 expected_values[1] = adjacent_values_match_if_adjacent_indices_match * (q_1 * q_2);
480 expected_values[2] = index_is_monotonically_increasing * (q_1 * q_2);
481 auto ROM_consistency_check_identity = memory_record_check * (q_1 * q_2);
486 auto access_type = (w_4 - partial_record_check);
487 auto access_check = access_type * access_type - access_type;
489 auto next_gate_access_type = w_3_shift * eta_three;
490 next_gate_access_type += w_2_shift * eta_two;
491 next_gate_access_type += w_1_shift * eta;
492 next_gate_access_type = w_4_shift - next_gate_access_type;
494 auto value_delta = w_3_shift - w_3;
495 auto adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =
496 (index_delta *
FF(-1) +
FF(1)) * value_delta * (next_gate_access_type *
FF(-1) +
FF(1));
502 auto next_gate_access_type_is_boolean = next_gate_access_type * next_gate_access_type - next_gate_access_type;
506 adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation * (q_3);
507 expected_values[4] = index_is_monotonically_increasing * (q_3);
508 expected_values[5] = next_gate_access_type_is_boolean * (q_3);
509 auto RAM_consistency_check_identity = access_check * (q_3);
514 memory_record_check *= (q_1 * q_m);
519 auto timestamp_delta = w_2_shift - w_2;
520 auto RAM_timestamp_check_identity = (index_delta *
FF(-1) +
FF(1)) * timestamp_delta - w_3;
521 RAM_timestamp_check_identity *= (q_1 * q_4);
526 auto memory_identity = ROM_consistency_check_identity;
527 memory_identity += RAM_timestamp_check_identity;
528 memory_identity += memory_record_check;
529 memory_identity += RAM_consistency_check_identity;
531 expected_values[0] = memory_identity;
532 expected_values[0] *= q_memory;
533 expected_values[1] *= q_memory;
534 expected_values[2] *= q_memory;
535 expected_values[3] *= q_memory;
536 expected_values[4] *= q_memory;
537 expected_values[5] *= q_memory;
539 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
547 const auto run_test = []([[maybe_unused]]
bool random_inputs) {
550 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
552 const auto& w_1 = input_elements.
w_l;
553 const auto& w_2 = input_elements.
w_r;
554 const auto& w_3 = input_elements.
w_o;
555 const auto& w_4 = input_elements.
w_4;
556 const auto& w_1_shift = input_elements.
w_l_shift;
557 const auto& w_2_shift = input_elements.
w_r_shift;
558 const auto& w_3_shift = input_elements.
w_o_shift;
559 const auto& w_4_shift = input_elements.
w_4_shift;
560 const auto& q_1 = input_elements.
q_l;
561 const auto& q_2 = input_elements.
q_r;
562 const auto& q_3 = input_elements.
q_o;
563 const auto& q_4 = input_elements.
q_4;
565 SumcheckArrayOfValuesOverSubrelations expected_values;
605 expected_values[0] = q_poseidon2_external * (v1 - w_1_shift);
606 expected_values[1] = q_poseidon2_external * (v2 - w_2_shift);
607 expected_values[2] = q_poseidon2_external * (v3 - w_3_shift);
608 expected_values[3] = q_poseidon2_external * (v4 - w_4_shift);
611 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
621 const auto run_test = []([[maybe_unused]]
bool random_inputs) {
624 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
626 const auto& w_1 = input_elements.
w_l;
627 const auto& w_2 = input_elements.
w_r;
628 const auto& w_3 = input_elements.
w_o;
629 const auto& w_4 = input_elements.
w_4;
630 const auto& w_1_shift = input_elements.
w_l_shift;
631 const auto& w_2_shift = input_elements.
w_r_shift;
632 const auto& w_3_shift = input_elements.
w_o_shift;
633 const auto& w_4_shift = input_elements.
w_4_shift;
634 const auto& q_1 = input_elements.
q_l;
636 SumcheckArrayOfValuesOverSubrelations expected_values;
648 auto sum = u1 + w_2 + w_3 + w_4;
658 expected_values[0] = q_poseidon2_internal * (t0 - w_1_shift);
659 expected_values[1] = q_poseidon2_internal * (t1 - w_2_shift);
660 expected_values[2] = q_poseidon2_internal * (t2 - w_3_shift);
661 expected_values[3] = q_poseidon2_internal * (t3 - w_4_shift);
664 validate_relation_execution<Relation>(expected_values, input_elements, parameters);