78 InputElements input_elements = random_inputs ? get_random_inputs() : get_special_inputs();
79 const auto& w_1 = input_elements.w_l();
80 const auto& w_1_shift = input_elements.w_l_shift();
81 const auto& w_2 = input_elements.w_r();
82 const auto& w_3 = input_elements.w_o();
83 const auto& w_4 = input_elements.w_4();
84 const auto& w_4_shift = input_elements.w_4_shift();
85 const auto& q_m = input_elements.q_m();
86 const auto& q_l = input_elements.q_l();
87 const auto& q_r = input_elements.q_r();
88 const auto& q_o = input_elements.q_o();
89 const auto& q_4 = input_elements.q_4();
90 const auto& q_c = input_elements.q_c();
94 const auto& q_arith = input_elements.q_arith();
96 SumcheckArrayOfValuesOverSubrelations expected_values;
99 FF contribution_1 =
FF(0);
100 FF contribution_2 =
FF(0);
101 if (q_arith ==
FF(1)) {
103 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;
106 }
else if (q_arith ==
FF(2)) {
108 contribution_1 = (q_m * w_2 * w_1);
109 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);
112 }
else if (q_arith ==
FF(3)) {
114 contribution_1 = (q_l * w_1) + (q_r * w_2) + (q_o * w_3) + (q_4 * w_4) + q_c;
115 contribution_1 += w_4_shift *
FF(2);
116 contribution_1 *=
FF(3);
119 contribution_2 = (w_1 + w_4 - w_1_shift + q_m) *
FF(6);
122 contribution_1 = (q_arith - 3) * (q_m * w_2 * w_1) * neg_half;
123 contribution_1 += (q_l * w_1) + (q_r * w_2) + (q_o * w_3) + (q_4 * w_4) + q_c;
124 contribution_1 += (q_arith - 1) * w_4_shift;
125 contribution_1 *= q_arith;
128 contribution_2 = (w_1 + w_4 - w_1_shift + q_m);
129 contribution_2 *= (q_arith - 2) * (q_arith - 1) * q_arith;
132 expected_values[0] = contribution_1;
133 expected_values[1] = contribution_2;
137 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
141 run_test(
true,
FF(1));
142 run_test(
true,
FF(2));
143 run_test(
true,
FF(3));
148 const auto run_test = [](
bool random_inputs) {
152 const InputElements input_elements = random_inputs ? get_random_inputs() : get_special_inputs();
153 const auto& w_1 = input_elements.w_l();
154 const auto& w_2 = input_elements.w_r();
155 const auto& w_3 = input_elements.w_o();
156 const auto& w_4 = input_elements.w_4();
157 const auto& sigma_1 = input_elements.sigma_1();
158 const auto& sigma_2 = input_elements.sigma_2();
159 const auto& sigma_3 = input_elements.sigma_3();
160 const auto& sigma_4 = input_elements.sigma_4();
161 const auto& id_1 = input_elements.id_1();
162 const auto& id_2 = input_elements.id_2();
163 const auto& id_3 = input_elements.id_3();
164 const auto& id_4 = input_elements.id_4();
165 const auto& z_perm = input_elements.z_perm();
166 const auto& z_perm_shift = input_elements.z_perm_shift();
167 const auto& lagrange_first = input_elements.lagrange_first();
168 const auto& lagrange_last = input_elements.lagrange_last();
170 SumcheckArrayOfValuesOverSubrelations expected_values;
173 const auto& beta = parameters.beta;
174 const auto& gamma = parameters.gamma;
175 const auto& public_input_delta = parameters.public_input_delta;
178 auto contribution_1 = (z_perm + lagrange_first) * (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) *
179 (w_3 + id_3 * beta + gamma) * (w_4 + id_4 * beta + gamma) -
180 (z_perm_shift + lagrange_last * public_input_delta) * (w_1 + sigma_1 * beta + gamma) *
181 (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma) *
182 (w_4 + sigma_4 * beta + gamma);
183 expected_values[0] = contribution_1;
186 auto contribution_2 = z_perm_shift * lagrange_last;
187 expected_values[1] = contribution_2;
190 auto contribution_3 = lagrange_first * z_perm;
191 expected_values[2] = contribution_3;
193 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
201 const auto run_test = [](
bool random_inputs) {
205 const InputElements input_elements = random_inputs ? get_random_inputs() : get_special_inputs();
206 const auto& w_1 = input_elements.w_l();
207 const auto& w_2 = input_elements.w_r();
208 const auto& w_3 = input_elements.w_o();
209 const auto& w_4 = input_elements.w_4();
210 const auto& w_1_shift = input_elements.w_l_shift();
211 const auto& q_delta_range = input_elements.q_delta_range();
213 auto delta_1 = w_2 - w_1;
214 auto delta_2 = w_3 - w_2;
215 auto delta_3 = w_4 - w_3;
216 auto delta_4 = w_1_shift - w_4;
218 auto contribution_1 = delta_1 * (delta_1 - 1) * (delta_1 - 2) * (delta_1 - 3);
219 auto contribution_2 = delta_2 * (delta_2 - 1) * (delta_2 - 2) * (delta_2 - 3);
220 auto contribution_3 = delta_3 * (delta_3 - 1) * (delta_3 - 2) * (delta_3 - 3);
221 auto contribution_4 = delta_4 * (delta_4 - 1) * (delta_4 - 2) * (delta_4 - 3);
223 SumcheckArrayOfValuesOverSubrelations expected_values;
225 expected_values[0] = contribution_1 * q_delta_range;
226 expected_values[1] = contribution_2 * q_delta_range;
227 expected_values[2] = contribution_3 * q_delta_range;
228 expected_values[3] = contribution_4 * q_delta_range;
232 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
240 const auto run_test = [](
bool random_inputs) {
245 InputElements input_elements = random_inputs ? get_random_inputs() : get_special_inputs();
247 const auto& x_1 = input_elements.w_r();
248 const auto& y_1 = input_elements.w_o();
250 const auto& x_2 = input_elements.w_l_shift();
251 const auto& y_2 = input_elements.w_4_shift();
252 const auto& x_3 = input_elements.w_r_shift();
253 const auto& y_3 = input_elements.w_o_shift();
259 const auto& q_sign = input_elements.q_l();
260 const auto& q_elliptic = input_elements.q_elliptic();
261 const auto& q_is_double = input_elements.q_m();
263 SumcheckArrayOfValuesOverSubrelations expected_values;
266 auto y_diff = (q_sign * y_2 - y_1);
267 auto x_diff = (x_2 - x_1);
268 auto x_diff_sqr = x_diff * x_diff;
269 auto lambda = y_diff / x_diff;
270 auto lambda_sqr = lambda * lambda;
276 auto x_add_identity = (x_3 - lambda_sqr + (x_1 + x_2)) * x_diff_sqr;
281 auto y_add_identity = (y_3 - lambda * (x_1 - x_3) + y_1) * x_diff;
286 auto y1_sqr = (y_1 * y_1);
287 auto x_pow_4 = (y1_sqr - curve_b) * x_1;
288 lambda_sqr = x_pow_4 * 9 / (y1_sqr * 4);
289 lambda = (x_1 * x_1 * 3) / (y_1 * 2);
295 auto x_double_identity = (x_3 - lambda_sqr + x_1 * 2) * (y1_sqr * 4);
301 auto y_double_identity = (y_3 - lambda * (x_1 - x_3) + y_1) * (y_1 * 2) *
FF(-1);
304 expected_values[0] = (x_add_identity * (-q_is_double + 1) + (x_double_identity * q_is_double)) * q_elliptic;
305 expected_values[1] = (y_add_identity * (-q_is_double + 1) + (y_double_identity * q_is_double)) * q_elliptic;
310 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
318 const auto run_test = [](
bool random_inputs) {
322 const InputElements input_elements = random_inputs ? get_random_inputs() : get_special_inputs();
323 const auto& w_1 = input_elements.w_l();
324 const auto& w_2 = input_elements.w_r();
325 const auto& w_3 = input_elements.w_o();
326 const auto& w_4 = input_elements.w_4();
327 const auto& w_1_shift = input_elements.w_l_shift();
328 const auto& w_2_shift = input_elements.w_r_shift();
329 const auto& w_3_shift = input_elements.w_o_shift();
330 const auto& w_4_shift = input_elements.w_4_shift();
332 const auto& q_2 = input_elements.q_r();
333 const auto& q_3 = input_elements.q_o();
334 const auto& q_4 = input_elements.q_4();
335 const auto& q_m = input_elements.q_m();
336 const auto& q_nnf = input_elements.q_nnf();
340 constexpr FF SUBLIMB_SHIFT_2(SUBLIMB_SHIFT * SUBLIMB_SHIFT);
341 constexpr FF SUBLIMB_SHIFT_3(SUBLIMB_SHIFT_2 * SUBLIMB_SHIFT);
342 constexpr FF SUBLIMB_SHIFT_4(SUBLIMB_SHIFT_3 * SUBLIMB_SHIFT);
344 SumcheckArrayOfValuesOverSubrelations expected_values;
347 auto nnf_gate_1 = (w_1 * w_2_shift + w_1_shift * w_2) * LIMB_SIZE;
348 nnf_gate_1 += (w_1_shift * w_2_shift);
349 nnf_gate_1 -= (w_3 + w_4);
352 auto nnf_gate_2 = (w_1 * w_4 + w_2 * w_3 - w_3_shift) * LIMB_SIZE;
353 nnf_gate_2 -= w_4_shift;
354 nnf_gate_2 += w_1 * w_2_shift + w_1_shift * w_2;
357 auto nnf_gate_3 = (w_1 * w_2_shift + w_1_shift * w_2) * LIMB_SIZE;
358 nnf_gate_3 += (w_1_shift * w_2_shift);
360 nnf_gate_3 -= (w_3_shift + w_4_shift);
362 auto limb_accumulator_1 = w_1 + w_2 * SUBLIMB_SHIFT + w_3 * SUBLIMB_SHIFT_2 + w_1_shift * SUBLIMB_SHIFT_3 +
363 w_2_shift * SUBLIMB_SHIFT_4 - w_4;
365 auto limb_accumulator_2 = w_3 + w_4 * SUBLIMB_SHIFT + w_1_shift * SUBLIMB_SHIFT_2 +
366 w_2_shift * SUBLIMB_SHIFT_3 + w_3_shift * SUBLIMB_SHIFT_4 - w_4_shift;
369 nnf_gate_1 *= (q_2 * q_3);
370 nnf_gate_2 *= (q_2 * q_4);
371 nnf_gate_3 *= (q_2 * q_m);
372 limb_accumulator_1 *= (q_3 * q_4);
373 limb_accumulator_2 *= (q_3 * q_m);
375 auto non_native_field_identity = nnf_gate_1 + nnf_gate_2 + nnf_gate_3;
376 auto limb_accumulator_identity = limb_accumulator_1 + limb_accumulator_2;
378 expected_values[0] = non_native_field_identity + limb_accumulator_identity;
379 expected_values[0] *= q_nnf;
383 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
391 const auto run_test = [](
bool random_inputs) {
395 const InputElements input_elements = random_inputs ? get_random_inputs() : get_special_inputs();
396 const auto& w_1 = input_elements.w_l();
397 const auto& w_2 = input_elements.w_r();
398 const auto& w_3 = input_elements.w_o();
399 const auto& w_4 = input_elements.w_4();
400 const auto& w_1_shift = input_elements.w_l_shift();
401 const auto& w_2_shift = input_elements.w_r_shift();
402 const auto& w_3_shift = input_elements.w_o_shift();
403 const auto& w_4_shift = input_elements.w_4_shift();
405 const auto& q_1 = input_elements.q_l();
406 const auto& q_2 = input_elements.q_r();
407 const auto& q_3 = input_elements.q_o();
408 const auto& q_4 = input_elements.q_4();
409 const auto& q_m = input_elements.q_m();
410 const auto& q_c = input_elements.q_c();
411 const auto& q_memory = input_elements.q_memory();
414 const auto& eta = parameters.eta;
415 const auto& eta_two = parameters.eta_two;
416 const auto& eta_three = parameters.eta_three;
417 const auto& rom_logup_gamma = parameters.rom_logup_gamma;
419 SumcheckArrayOfValuesOverSubrelations expected_values;
424 auto memory_record_check = w_3 * eta_three;
425 memory_record_check += w_2 * eta_two;
426 memory_record_check += w_1 * eta;
427 memory_record_check += q_c;
428 auto partial_record_check = memory_record_check;
429 memory_record_check = memory_record_check - w_4;
434 auto index_delta = w_1_shift - w_1;
435 auto record_delta = w_4_shift - w_4;
437 auto index_is_monotonically_increasing = index_delta * index_delta - index_delta;
440 auto adjacent_values_match_if_adjacent_indices_match = (index_delta *
FF(-1) +
FF(1)) * record_delta;
442 expected_values[1] = adjacent_values_match_if_adjacent_indices_match * (q_1 * q_2);
443 expected_values[2] = index_is_monotonically_increasing * (q_1 * q_2);
444 auto ROM_consistency_check_identity = memory_record_check * (q_1 * q_2);
449 auto access_type = (w_4 - partial_record_check);
450 auto access_check = access_type * access_type - access_type;
452 auto next_gate_access_type = w_3_shift * eta_three;
453 next_gate_access_type += w_2_shift * eta_two;
454 next_gate_access_type += w_1_shift * eta;
455 next_gate_access_type = w_4_shift - next_gate_access_type;
457 auto value_delta = w_3_shift - w_3;
458 auto adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =
459 (index_delta *
FF(-1) +
FF(1)) * value_delta * (next_gate_access_type *
FF(-1) +
FF(1));
465 auto next_gate_access_type_is_boolean = next_gate_access_type * next_gate_access_type - next_gate_access_type;
469 adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation * (q_3);
470 expected_values[4] = index_is_monotonically_increasing * (q_3);
471 expected_values[5] = next_gate_access_type_is_boolean * (q_3);
472 auto RAM_consistency_check_identity = access_check * (q_3);
477 memory_record_check *= (q_1 * q_m);
482 auto timestamp_delta = w_2_shift - w_2;
483 auto RAM_timestamp_check_identity = (index_delta *
FF(-1) +
FF(1)) * timestamp_delta - w_3;
484 RAM_timestamp_check_identity *= (q_1 * q_4);
489 auto memory_identity = ROM_consistency_check_identity;
490 memory_identity += RAM_timestamp_check_identity;
491 memory_identity += memory_record_check;
492 memory_identity += RAM_consistency_check_identity;
494 expected_values[0] = memory_identity;
495 expected_values[0] *= q_memory;
496 expected_values[1] *= q_memory;
497 expected_values[2] *= q_memory;
498 expected_values[3] *= q_memory;
499 expected_values[4] *= q_memory;
500 expected_values[5] *= q_memory;
505 auto q_logup_table = q_2 * (q_1 *
FF(-1) +
FF(1));
506 auto q_logup_read = q_4 * (q_1 *
FF(-1) +
FF(1));
507 auto denom = rom_logup_gamma + w_1 + w_2 * eta + q_c * eta_two;
509 expected_values[6] = q_memory * (q_logup_table + q_logup_read) * (w_4 * denom -
FF(1));
511 expected_values[7] = q_memory * (q_logup_read - q_logup_table * w_3) * w_4;
513 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
521 const auto run_test = []([[maybe_unused]]
bool random_inputs) {
524 const InputElements input_elements = random_inputs ? get_random_inputs() : get_special_inputs();
526 const auto& w_1 = input_elements.w_l();
527 const auto& w_2 = input_elements.w_r();
528 const auto& w_3 = input_elements.w_o();
529 const auto& w_4 = input_elements.w_4();
530 const auto& w_1_shift = input_elements.w_l_shift();
531 const auto& w_2_shift = input_elements.w_r_shift();
532 const auto& w_3_shift = input_elements.w_o_shift();
533 const auto& w_4_shift = input_elements.w_4_shift();
534 const auto& q_1 = input_elements.q_l();
535 const auto& q_2 = input_elements.q_r();
536 const auto& q_3 = input_elements.q_o();
537 const auto& q_4 = input_elements.q_4();
538 const auto& q_poseidon2_external = input_elements.q_poseidon2_external();
539 SumcheckArrayOfValuesOverSubrelations expected_values;
579 expected_values[0] = q_poseidon2_external * (v1 - w_1_shift);
580 expected_values[1] = q_poseidon2_external * (v2 - w_2_shift);
581 expected_values[2] = q_poseidon2_external * (v3 - w_3_shift);
582 expected_values[3] = q_poseidon2_external * (v4 - w_4_shift);
585 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
595 const auto run_test = []([[maybe_unused]]
bool random_inputs) {
598 const InputElements input_elements = random_inputs ? get_random_inputs() : get_special_inputs();
600 const auto& w_1 = input_elements.w_l();
601 const auto& w_2 = input_elements.w_r();
602 const auto& w_3 = input_elements.w_o();
603 const auto& w_4 = input_elements.w_4();
604 const auto& w_1_shift = input_elements.w_l_shift();
605 const auto& w_2_shift = input_elements.w_r_shift();
606 const auto& w_3_shift = input_elements.w_o_shift();
607 const auto& w_4_shift = input_elements.w_4_shift();
608 const auto& q_1 = input_elements.q_l();
609 const auto& q_poseidon2_internal = input_elements.q_poseidon2_internal();
610 SumcheckArrayOfValuesOverSubrelations expected_values;
622 auto sum = u1 + w_2 + w_3 + w_4;
632 expected_values[0] = q_poseidon2_internal * (t0 - w_1_shift);
633 expected_values[1] = q_poseidon2_internal * (t1 - w_2_shift);
634 expected_values[2] = q_poseidon2_internal * (t2 - w_3_shift);
635 expected_values[3] = q_poseidon2_internal * (t3 - w_4_shift);
638 validate_relation_execution<Relation>(expected_values, input_elements, parameters);