113 const auto run_test = [](
bool random_inputs) {
117 const 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;
130 const auto& q_arith = input_elements.
q_arith;
132 SumcheckArrayOfValuesOverSubrelations expected_values;
136 auto contribution_1 = (q_arith - 3) * (q_m * w_2 * w_1) * neg_half;
137 contribution_1 += (q_l * w_1) + (q_r * w_2) + (q_o * w_3) + (q_4 * w_4) + q_c;
138 contribution_1 += (q_arith - 1) * w_4_shift;
139 contribution_1 *= q_arith;
140 expected_values[0] = contribution_1;
143 auto contribution_2 = (w_1 + w_4 - w_1_shift + q_m);
144 contribution_2 *= (q_arith - 2) * (q_arith - 1) * q_arith;
145 expected_values[1] = contribution_2;
149 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
157 const auto run_test = [](
bool random_inputs) {
161 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
162 const auto& w_1 = input_elements.
w_l;
163 const auto& w_2 = input_elements.
w_r;
164 const auto& w_3 = input_elements.
w_o;
165 const auto& w_4 = input_elements.
w_4;
166 const auto& sigma_1 = input_elements.
sigma_1;
167 const auto& sigma_2 = input_elements.
sigma_2;
168 const auto& sigma_3 = input_elements.
sigma_3;
169 const auto& sigma_4 = input_elements.
sigma_4;
170 const auto& id_1 = input_elements.
id_1;
171 const auto& id_2 = input_elements.
id_2;
172 const auto& id_3 = input_elements.
id_3;
173 const auto& id_4 = input_elements.
id_4;
174 const auto& z_perm = input_elements.
z_perm;
179 SumcheckArrayOfValuesOverSubrelations expected_values;
182 const auto& beta = parameters.beta;
183 const auto& gamma = parameters.gamma;
184 const auto& public_input_delta = parameters.public_input_delta;
187 auto contribution_1 = (z_perm + lagrange_first) * (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) *
188 (w_3 + id_3 * beta + gamma) * (w_4 + id_4 * beta + gamma) -
189 (z_perm_shift + lagrange_last * public_input_delta) * (w_1 + sigma_1 * beta + gamma) *
190 (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma) *
191 (w_4 + sigma_4 * beta + gamma);
192 expected_values[0] = contribution_1;
195 auto contribution_2 = z_perm_shift * lagrange_last;
196 expected_values[1] = contribution_2;
198 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
206 const auto run_test = [](
bool random_inputs) {
210 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
211 const auto& w_1 = input_elements.
w_l;
212 const auto& w_2 = input_elements.
w_r;
213 const auto& w_3 = input_elements.
w_o;
214 const auto& w_4 = input_elements.
w_4;
215 const auto& w_1_shift = input_elements.
w_l_shift;
218 auto delta_1 = w_2 - w_1;
219 auto delta_2 = w_3 - w_2;
220 auto delta_3 = w_4 - w_3;
221 auto delta_4 = w_1_shift - w_4;
223 auto contribution_1 = delta_1 * (delta_1 - 1) * (delta_1 - 2) * (delta_1 - 3);
224 auto contribution_2 = delta_2 * (delta_2 - 1) * (delta_2 - 2) * (delta_2 - 3);
225 auto contribution_3 = delta_3 * (delta_3 - 1) * (delta_3 - 2) * (delta_3 - 3);
226 auto contribution_4 = delta_4 * (delta_4 - 1) * (delta_4 - 2) * (delta_4 - 3);
228 SumcheckArrayOfValuesOverSubrelations expected_values;
230 expected_values[0] = contribution_1 * q_delta_range;
231 expected_values[1] = contribution_2 * q_delta_range;
232 expected_values[2] = contribution_3 * q_delta_range;
233 expected_values[3] = contribution_4 * q_delta_range;
237 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
245 const auto run_test = [](
bool random_inputs) {
249 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
250 const auto& x_1 = input_elements.
w_r;
251 const auto& y_1 = input_elements.
w_o;
253 const auto& x_2 = input_elements.
w_l_shift;
254 const auto& y_2 = input_elements.
w_4_shift;
255 const auto& x_3 = input_elements.
w_r_shift;
256 const auto& y_3 = input_elements.
w_o_shift;
258 const auto& q_sign = input_elements.
q_l;
259 const auto& q_elliptic = input_elements.
q_elliptic;
260 const auto& q_is_double = input_elements.
q_m;
262 SumcheckArrayOfValuesOverSubrelations expected_values;
268 auto x_diff = (x_2 - x_1);
269 auto y2_sqr = (y_2 * y_2);
270 auto y1_sqr = (y_1 * y_1);
271 auto y1y2 = y_1 * y_2 * q_sign;
272 auto x_add_identity = (x_3 + x_2 + x_1) * x_diff * x_diff - y2_sqr - y1_sqr + y1y2 + y1y2;
276 auto y1_plus_y3 = y_1 + y_3;
277 auto y_diff = y_2 * q_sign - y_1;
278 auto y_add_identity = y1_plus_y3 * x_diff + (x_3 - x_1) * y_diff;
284 auto x_pow_4 = (y1_sqr - curve_b) * x_1;
285 auto y1_sqr_mul_4 = y1_sqr + y1_sqr;
286 y1_sqr_mul_4 += y1_sqr_mul_4;
287 auto x1_pow_4_mul_9 = x_pow_4 * 9;
288 auto x_double_identity = (x_3 + x_1 + x_1) * y1_sqr_mul_4 - x1_pow_4_mul_9;
292 auto x1_sqr_mul_3 = (x_1 + x_1 + x_1) * x_1;
293 auto y_double_identity = x1_sqr_mul_3 * (x_1 - x_3) - (y_1 + y_1) * (y_1 + y_3);
294 expected_values[0] = (x_add_identity * (-q_is_double + 1) + (x_double_identity * q_is_double)) * q_elliptic;
295 expected_values[1] = (y_add_identity * (-q_is_double + 1) + (y_double_identity * q_is_double)) * q_elliptic;
300 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
308 const auto run_test = [](
bool random_inputs) {
312 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
313 const auto& w_1 = input_elements.
w_l;
314 const auto& w_2 = input_elements.
w_r;
315 const auto& w_3 = input_elements.
w_o;
316 const auto& w_4 = input_elements.
w_4;
317 const auto& w_1_shift = input_elements.
w_l_shift;
318 const auto& w_2_shift = input_elements.
w_r_shift;
319 const auto& w_3_shift = input_elements.
w_o_shift;
320 const auto& w_4_shift = input_elements.
w_4_shift;
322 const auto& q_2 = input_elements.
q_r;
323 const auto& q_3 = input_elements.
q_o;
324 const auto& q_4 = input_elements.
q_4;
325 const auto& q_m = input_elements.
q_m;
326 const auto& q_nnf = input_elements.
q_nnf;
330 constexpr FF SUBLIMB_SHIFT_2(SUBLIMB_SHIFT * SUBLIMB_SHIFT);
331 constexpr FF SUBLIMB_SHIFT_3(SUBLIMB_SHIFT_2 * SUBLIMB_SHIFT);
332 constexpr FF SUBLIMB_SHIFT_4(SUBLIMB_SHIFT_3 * SUBLIMB_SHIFT);
334 SumcheckArrayOfValuesOverSubrelations expected_values;
337 auto nnf_gate_1 = (w_1 * w_2_shift + w_1_shift * w_2) * LIMB_SIZE;
338 nnf_gate_1 += (w_1_shift * w_2_shift);
339 nnf_gate_1 -= (w_3 + w_4);
342 auto nnf_gate_2 = (w_1 * w_4 + w_2 * w_3 - w_3_shift) * LIMB_SIZE;
343 nnf_gate_2 -= w_4_shift;
344 nnf_gate_2 += w_1 * w_2_shift + w_1_shift * w_2;
347 auto nnf_gate_3 = (w_1 * w_2_shift + w_1_shift * w_2) * LIMB_SIZE;
348 nnf_gate_3 += (w_1_shift * w_2_shift);
350 nnf_gate_3 -= (w_3_shift + w_4_shift);
352 auto limb_accumulator_1 = w_1 + w_2 * SUBLIMB_SHIFT + w_3 * SUBLIMB_SHIFT_2 + w_1_shift * SUBLIMB_SHIFT_3 +
353 w_2_shift * SUBLIMB_SHIFT_4 - w_4;
355 auto limb_accumulator_2 = w_3 + w_4 * SUBLIMB_SHIFT + w_1_shift * SUBLIMB_SHIFT_2 +
356 w_2_shift * SUBLIMB_SHIFT_3 + w_3_shift * SUBLIMB_SHIFT_4 - w_4_shift;
359 nnf_gate_1 *= (q_2 * q_3);
360 nnf_gate_2 *= (q_2 * q_4);
361 nnf_gate_3 *= (q_2 * q_m);
362 limb_accumulator_1 *= (q_3 * q_4);
363 limb_accumulator_2 *= (q_3 * q_m);
365 auto non_native_field_identity = nnf_gate_1 + nnf_gate_2 + nnf_gate_3;
366 auto limb_accumulator_identity = limb_accumulator_1 + limb_accumulator_2;
368 expected_values[0] = non_native_field_identity + limb_accumulator_identity;
369 expected_values[0] *= q_nnf;
373 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
381 const auto run_test = [](
bool random_inputs) {
385 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
386 const auto& w_1 = input_elements.
w_l;
387 const auto& w_2 = input_elements.
w_r;
388 const auto& w_3 = input_elements.
w_o;
389 const auto& w_4 = input_elements.
w_4;
390 const auto& w_1_shift = input_elements.
w_l_shift;
391 const auto& w_2_shift = input_elements.
w_r_shift;
392 const auto& w_3_shift = input_elements.
w_o_shift;
393 const auto& w_4_shift = input_elements.
w_4_shift;
395 const auto& q_1 = input_elements.
q_l;
396 const auto& q_2 = input_elements.
q_r;
397 const auto& q_3 = input_elements.
q_o;
398 const auto& q_4 = input_elements.
q_4;
399 const auto& q_m = input_elements.
q_m;
400 const auto& q_c = input_elements.
q_c;
401 const auto& q_memory = input_elements.
q_memory;
404 const auto& eta = parameters.eta;
405 const auto& eta_two = parameters.eta_two;
406 const auto& eta_three = parameters.eta_three;
408 SumcheckArrayOfValuesOverSubrelations expected_values;
413 auto memory_record_check = w_3 * eta_three;
414 memory_record_check += w_2 * eta_two;
415 memory_record_check += w_1 * eta;
416 memory_record_check += q_c;
417 auto partial_record_check = memory_record_check;
418 memory_record_check = memory_record_check - w_4;
423 auto index_delta = w_1_shift - w_1;
424 auto record_delta = w_4_shift - w_4;
426 auto index_is_monotonically_increasing = index_delta * index_delta - index_delta;
429 auto adjacent_values_match_if_adjacent_indices_match = (index_delta *
FF(-1) +
FF(1)) * record_delta;
431 expected_values[1] = adjacent_values_match_if_adjacent_indices_match * (q_1 * q_2);
432 expected_values[2] = index_is_monotonically_increasing * (q_1 * q_2);
433 auto ROM_consistency_check_identity = memory_record_check * (q_1 * q_2);
438 auto access_type = (w_4 - partial_record_check);
439 auto access_check = access_type * access_type - access_type;
441 auto next_gate_access_type = w_3_shift * eta_three;
442 next_gate_access_type += w_2_shift * eta_two;
443 next_gate_access_type += w_1_shift * eta;
444 next_gate_access_type = w_4_shift - next_gate_access_type;
446 auto value_delta = w_3_shift - w_3;
447 auto adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation =
448 (index_delta *
FF(-1) +
FF(1)) * value_delta * (next_gate_access_type *
FF(-1) +
FF(1));
454 auto next_gate_access_type_is_boolean = next_gate_access_type * next_gate_access_type - next_gate_access_type;
458 adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation * (q_3);
459 expected_values[4] = index_is_monotonically_increasing * (q_3);
460 expected_values[5] = next_gate_access_type_is_boolean * (q_3);
461 auto RAM_consistency_check_identity = access_check * (q_3);
466 memory_record_check *= (q_1 * q_m);
471 auto timestamp_delta = w_2_shift - w_2;
472 auto RAM_timestamp_check_identity = (index_delta *
FF(-1) +
FF(1)) * timestamp_delta - w_3;
473 RAM_timestamp_check_identity *= (q_1 * q_4);
478 auto memory_identity = ROM_consistency_check_identity;
479 memory_identity += RAM_timestamp_check_identity;
480 memory_identity += memory_record_check;
481 memory_identity += RAM_consistency_check_identity;
483 expected_values[0] = memory_identity;
484 expected_values[0] *= q_memory;
485 expected_values[1] *= q_memory;
486 expected_values[2] *= q_memory;
487 expected_values[3] *= q_memory;
488 expected_values[4] *= q_memory;
489 expected_values[5] *= q_memory;
491 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
499 const auto run_test = []([[maybe_unused]]
bool random_inputs) {
502 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
504 const auto& w_1 = input_elements.
w_l;
505 const auto& w_2 = input_elements.
w_r;
506 const auto& w_3 = input_elements.
w_o;
507 const auto& w_4 = input_elements.
w_4;
508 const auto& w_1_shift = input_elements.
w_l_shift;
509 const auto& w_2_shift = input_elements.
w_r_shift;
510 const auto& w_3_shift = input_elements.
w_o_shift;
511 const auto& w_4_shift = input_elements.
w_4_shift;
512 const auto& q_1 = input_elements.
q_l;
513 const auto& q_2 = input_elements.
q_r;
514 const auto& q_3 = input_elements.
q_o;
515 const auto& q_4 = input_elements.
q_4;
517 SumcheckArrayOfValuesOverSubrelations expected_values;
557 expected_values[0] = q_poseidon2_external * (v1 - w_1_shift);
558 expected_values[1] = q_poseidon2_external * (v2 - w_2_shift);
559 expected_values[2] = q_poseidon2_external * (v3 - w_3_shift);
560 expected_values[3] = q_poseidon2_external * (v4 - w_4_shift);
563 validate_relation_execution<Relation>(expected_values, input_elements, parameters);
573 const auto run_test = []([[maybe_unused]]
bool random_inputs) {
576 const InputElements input_elements = random_inputs ? InputElements::get_random() : InputElements::get_special();
578 const auto& w_1 = input_elements.
w_l;
579 const auto& w_2 = input_elements.
w_r;
580 const auto& w_3 = input_elements.
w_o;
581 const auto& w_4 = input_elements.
w_4;
582 const auto& w_1_shift = input_elements.
w_l_shift;
583 const auto& w_2_shift = input_elements.
w_r_shift;
584 const auto& w_3_shift = input_elements.
w_o_shift;
585 const auto& w_4_shift = input_elements.
w_4_shift;
586 const auto& q_1 = input_elements.
q_l;
588 SumcheckArrayOfValuesOverSubrelations expected_values;
599 auto sum = u1 + w_2 + w_3 + w_4;
609 expected_values[0] = q_poseidon2_internal * (t0 - w_1_shift);
610 expected_values[1] = q_poseidon2_internal * (t1 - w_2_shift);
611 expected_values[2] = q_poseidon2_internal * (t2 - w_3_shift);
612 expected_values[3] = q_poseidon2_internal * (t3 - w_4_shift);
615 validate_relation_execution<Relation>(expected_values, input_elements, parameters);