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;
228 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
236 const auto run_test = [](
bool random_inputs) {
240 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
241 const auto& w_1 = input_elements.
w_l;
242 const auto& w_2 = input_elements.
w_r;
243 const auto& w_3 = input_elements.
w_o;
244 const auto& w_4 = input_elements.
w_4;
245 const auto& w_1_shift = input_elements.
w_l_shift;
248 auto delta_1 = w_2 - w_1;
249 auto delta_2 = w_3 - w_2;
250 auto delta_3 = w_4 - w_3;
251 auto delta_4 = w_1_shift - w_4;
253 auto contribution_1 = delta_1 * (delta_1 - 1) * (delta_1 - 2) * (delta_1 - 3);
254 auto contribution_2 = delta_2 * (delta_2 - 1) * (delta_2 - 2) * (delta_2 - 3);
255 auto contribution_3 = delta_3 * (delta_3 - 1) * (delta_3 - 2) * (delta_3 - 3);
256 auto contribution_4 = delta_4 * (delta_4 - 1) * (delta_4 - 2) * (delta_4 - 3);
258 SumcheckArrayOfValuesOverSubrelations expected_values;
260 expected_values[0] = contribution_1 * q_delta_range;
261 expected_values[1] = contribution_2 * q_delta_range;
262 expected_values[2] = contribution_3 * q_delta_range;
263 expected_values[3] = contribution_4 * q_delta_range;
267 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
275 const auto run_test = [](
bool random_inputs) {
279 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
281 const auto& x_1 = input_elements.
w_r;
282 const auto& y_1 = input_elements.
w_o;
284 const auto& x_2 = input_elements.
w_l_shift;
285 const auto& y_2 = input_elements.
w_4_shift;
286 const auto& x_3 = input_elements.
w_r_shift;
287 const auto& y_3 = input_elements.
w_o_shift;
292 input_elements.
q_l =
FF(-1);
293 const auto& q_sign = input_elements.
q_l;
294 const auto& q_elliptic = input_elements.
q_elliptic;
295 const auto& q_is_double = input_elements.
q_m;
297 SumcheckArrayOfValuesOverSubrelations expected_values;
300 auto y_diff = (q_sign * y_2 - y_1);
301 auto x_diff = (x_2 - x_1);
302 auto x_diff_sqr = x_diff * x_diff;
303 auto lambda = y_diff / x_diff;
304 auto lambda_sqr = lambda * lambda;
310 auto x_add_identity = (x_3 - lambda_sqr + (x_1 + x_2)) * x_diff_sqr;
315 auto y_add_identity = (y_3 - lambda * (x_1 - x_3) + y_1) * x_diff;
320 auto y1_sqr = (y_1 * y_1);
321 auto x_pow_4 = (y1_sqr - curve_b) * x_1;
322 lambda_sqr = x_pow_4 * 9 / (y1_sqr * 4);
323 lambda = (x_1 * x_1 * 3) / (y_1 * 2);
329 auto x_double_identity = (x_3 - lambda_sqr + x_1 * 2) * (y1_sqr * 4);
335 auto y_double_identity = (y_3 - lambda * (x_1 - x_3) + y_1) * (y_1 * 2) *
FF(-1);
338 expected_values[0] = (x_add_identity * (-q_is_double + 1) + (x_double_identity * q_is_double)) * q_elliptic;
339 expected_values[1] = (y_add_identity * (-q_is_double + 1) + (y_double_identity * q_is_double)) * q_elliptic;
344 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
352 const auto run_test = [](
bool random_inputs) {
356 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
357 const auto& w_1 = input_elements.
w_l;
358 const auto& w_2 = input_elements.
w_r;
359 const auto& w_3 = input_elements.
w_o;
360 const auto& w_4 = input_elements.
w_4;
361 const auto& w_1_shift = input_elements.
w_l_shift;
362 const auto& w_2_shift = input_elements.
w_r_shift;
363 const auto& w_3_shift = input_elements.
w_o_shift;
364 const auto& w_4_shift = input_elements.
w_4_shift;
366 const auto& q_2 = input_elements.
q_r;
367 const auto& q_3 = input_elements.
q_o;
368 const auto& q_4 = input_elements.
q_4;
369 const auto& q_m = input_elements.
q_m;
370 const auto& q_nnf = input_elements.
q_nnf;
374 constexpr FF SUBLIMB_SHIFT_2(SUBLIMB_SHIFT * SUBLIMB_SHIFT);
375 constexpr FF SUBLIMB_SHIFT_3(SUBLIMB_SHIFT_2 * SUBLIMB_SHIFT);
376 constexpr FF SUBLIMB_SHIFT_4(SUBLIMB_SHIFT_3 * SUBLIMB_SHIFT);
378 SumcheckArrayOfValuesOverSubrelations expected_values;
381 auto nnf_gate_1 = (w_1 * w_2_shift + w_1_shift * w_2) * LIMB_SIZE;
382 nnf_gate_1 += (w_1_shift * w_2_shift);
383 nnf_gate_1 -= (w_3 + w_4);
386 auto nnf_gate_2 = (w_1 * w_4 + w_2 * w_3 - w_3_shift) * LIMB_SIZE;
387 nnf_gate_2 -= w_4_shift;
388 nnf_gate_2 += w_1 * w_2_shift + w_1_shift * w_2;
391 auto nnf_gate_3 = (w_1 * w_2_shift + w_1_shift * w_2) * LIMB_SIZE;
392 nnf_gate_3 += (w_1_shift * w_2_shift);
394 nnf_gate_3 -= (w_3_shift + w_4_shift);
396 auto limb_accumulator_1 = w_1 + w_2 * SUBLIMB_SHIFT + w_3 * SUBLIMB_SHIFT_2 + w_1_shift * SUBLIMB_SHIFT_3 +
397 w_2_shift * SUBLIMB_SHIFT_4 - w_4;
399 auto limb_accumulator_2 = w_3 + w_4 * SUBLIMB_SHIFT + w_1_shift * SUBLIMB_SHIFT_2 +
400 w_2_shift * SUBLIMB_SHIFT_3 + w_3_shift * SUBLIMB_SHIFT_4 - w_4_shift;
403 nnf_gate_1 *= (q_2 * q_3);
404 nnf_gate_2 *= (q_2 * q_4);
405 nnf_gate_3 *= (q_2 * q_m);
406 limb_accumulator_1 *= (q_3 * q_4);
407 limb_accumulator_2 *= (q_3 * q_m);
409 auto non_native_field_identity = nnf_gate_1 + nnf_gate_2 + nnf_gate_3;
410 auto limb_accumulator_identity = limb_accumulator_1 + limb_accumulator_2;
412 expected_values[0] = non_native_field_identity + limb_accumulator_identity;
413 expected_values[0] *= q_nnf;
417 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
425 const auto run_test = [](
bool random_inputs) {
429 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
430 const auto& w_1 = input_elements.
w_l;
431 const auto& w_2 = input_elements.
w_r;
432 const auto& w_3 = input_elements.
w_o;
433 const auto& w_4 = input_elements.
w_4;
434 const auto& w_1_shift = input_elements.
w_l_shift;
435 const auto& w_2_shift = input_elements.
w_r_shift;
436 const auto& w_3_shift = input_elements.
w_o_shift;
437 const auto& w_4_shift = input_elements.
w_4_shift;
439 const auto& q_1 = input_elements.
q_l;
440 const auto& q_2 = input_elements.
q_r;
441 const auto& q_3 = input_elements.
q_o;
442 const auto& q_4 = input_elements.
q_4;
443 const auto& q_m = input_elements.
q_m;
444 const auto& q_c = input_elements.
q_c;
445 const auto& q_memory = input_elements.
q_memory;
448 const auto& eta = parameters.eta;
449 const auto& eta_two = parameters.eta_two;
450 const auto& eta_three = parameters.eta_three;
452 SumcheckArrayOfValuesOverSubrelations expected_values;
457 auto memory_record_check = w_3 * eta_three;
458 memory_record_check += w_2 * eta_two;
459 memory_record_check += w_1 * eta;
460 memory_record_check += q_c;
461 auto partial_record_check = memory_record_check;
462 memory_record_check = memory_record_check - w_4;
467 auto index_delta = w_1_shift - w_1;
468 auto record_delta = w_4_shift - w_4;
470 auto index_is_monotonically_increasing = index_delta * index_delta - index_delta;
473 auto adjacent_values_match_if_adjacent_indices_match = (index_delta *
FF(-1) +
FF(1)) * record_delta;
475 expected_values[1] = adjacent_values_match_if_adjacent_indices_match * (q_1 * q_2);
476 expected_values[2] = index_is_monotonically_increasing * (q_1 * q_2);
477 auto ROM_consistency_check_identity = memory_record_check * (q_1 * q_2);
482 auto access_type = (w_4 - partial_record_check);
483 auto access_check = access_type * access_type - access_type;
485 auto next_gate_access_type = w_3_shift * eta_three;
486 next_gate_access_type += w_2_shift * eta_two;
487 next_gate_access_type += w_1_shift * eta;
488 next_gate_access_type = w_4_shift - next_gate_access_type;
490 auto value_delta = w_3_shift - w_3;
491 auto adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =
492 (index_delta *
FF(-1) +
FF(1)) * value_delta * (next_gate_access_type *
FF(-1) +
FF(1));
498 auto next_gate_access_type_is_boolean = next_gate_access_type * next_gate_access_type - next_gate_access_type;
502 adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation * (q_3);
503 expected_values[4] = index_is_monotonically_increasing * (q_3);
504 expected_values[5] = next_gate_access_type_is_boolean * (q_3);
505 auto RAM_consistency_check_identity = access_check * (q_3);
510 memory_record_check *= (q_1 * q_m);
515 auto timestamp_delta = w_2_shift - w_2;
516 auto RAM_timestamp_check_identity = (index_delta *
FF(-1) +
FF(1)) * timestamp_delta - w_3;
517 RAM_timestamp_check_identity *= (q_1 * q_4);
522 auto memory_identity = ROM_consistency_check_identity;
523 memory_identity += RAM_timestamp_check_identity;
524 memory_identity += memory_record_check;
525 memory_identity += RAM_consistency_check_identity;
527 expected_values[0] = memory_identity;
528 expected_values[0] *= q_memory;
529 expected_values[1] *= q_memory;
530 expected_values[2] *= q_memory;
531 expected_values[3] *= q_memory;
532 expected_values[4] *= q_memory;
533 expected_values[5] *= q_memory;
535 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
543 const auto run_test = []([[maybe_unused]]
bool random_inputs) {
546 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
548 const auto& w_1 = input_elements.
w_l;
549 const auto& w_2 = input_elements.
w_r;
550 const auto& w_3 = input_elements.
w_o;
551 const auto& w_4 = input_elements.
w_4;
552 const auto& w_1_shift = input_elements.
w_l_shift;
553 const auto& w_2_shift = input_elements.
w_r_shift;
554 const auto& w_3_shift = input_elements.
w_o_shift;
555 const auto& w_4_shift = input_elements.
w_4_shift;
556 const auto& q_1 = input_elements.
q_l;
557 const auto& q_2 = input_elements.
q_r;
558 const auto& q_3 = input_elements.
q_o;
559 const auto& q_4 = input_elements.
q_4;
561 SumcheckArrayOfValuesOverSubrelations expected_values;
601 expected_values[0] = q_poseidon2_external * (v1 - w_1_shift);
602 expected_values[1] = q_poseidon2_external * (v2 - w_2_shift);
603 expected_values[2] = q_poseidon2_external * (v3 - w_3_shift);
604 expected_values[3] = q_poseidon2_external * (v4 - w_4_shift);
607 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
617 const auto run_test = []([[maybe_unused]]
bool random_inputs) {
620 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
622 const auto& w_1 = input_elements.
w_l;
623 const auto& w_2 = input_elements.
w_r;
624 const auto& w_3 = input_elements.
w_o;
625 const auto& w_4 = input_elements.
w_4;
626 const auto& w_1_shift = input_elements.
w_l_shift;
627 const auto& w_2_shift = input_elements.
w_r_shift;
628 const auto& w_3_shift = input_elements.
w_o_shift;
629 const auto& w_4_shift = input_elements.
w_4_shift;
630 const auto& q_1 = input_elements.
q_l;
632 SumcheckArrayOfValuesOverSubrelations expected_values;
643 auto sum = u1 + w_2 + w_3 + w_4;
653 expected_values[0] = q_poseidon2_internal * (t0 - w_1_shift);
654 expected_values[1] = q_poseidon2_internal * (t1 - w_2_shift);
655 expected_values[2] = q_poseidon2_internal * (t2 - w_3_shift);
656 expected_values[3] = q_poseidon2_internal * (t3 - w_4_shift);
659 validate_relation_execution<Relation>(expected_values, input_elements, parameters);