49 const AllEntities& in,
51 const FF& scaling_factor)
54 using View =
typename Accumulator::View;
56 const auto& x1 = View(in.msm_x1);
57 const auto& y1 = View(in.msm_y1);
58 const auto& x2 = View(in.msm_x2);
59 const auto& y2 = View(in.msm_y2);
60 const auto& x3 = View(in.msm_x3);
61 const auto& y3 = View(in.msm_y3);
62 const auto& x4 = View(in.msm_x4);
63 const auto& y4 = View(in.msm_y4);
64 const auto& collision_inverse1 = View(in.msm_collision_x1);
65 const auto& collision_inverse2 = View(in.msm_collision_x2);
66 const auto& collision_inverse3 = View(in.msm_collision_x3);
67 const auto& collision_inverse4 = View(in.msm_collision_x4);
68 const auto& lambda1 = View(in.msm_lambda1);
69 const auto& lambda2 = View(in.msm_lambda2);
70 const auto& lambda3 = View(in.msm_lambda3);
71 const auto& lambda4 = View(in.msm_lambda4);
72 const auto& lagrange_first = View(in.lagrange_first);
73 const auto& add1 = View(in.msm_add1);
74 const auto& add1_shift = View(in.msm_add1_shift);
75 const auto& add2 = View(in.msm_add2);
76 const auto& add3 = View(in.msm_add3);
77 const auto& add4 = View(in.msm_add4);
78 const auto& acc_x = View(in.msm_accumulator_x);
79 const auto& acc_y = View(in.msm_accumulator_y);
80 const auto& acc_x_shift = View(in.msm_accumulator_x_shift);
81 const auto& acc_y_shift = View(in.msm_accumulator_y_shift);
82 const auto& slice1 = View(in.msm_slice1);
83 const auto& slice2 = View(in.msm_slice2);
84 const auto& slice3 = View(in.msm_slice3);
85 const auto& slice4 = View(in.msm_slice4);
86 const auto& msm_transition = View(in.msm_transition);
87 const auto& msm_transition_shift = View(in.msm_transition_shift);
88 const auto& round = View(in.msm_round);
89 const auto& round_shift = View(in.msm_round_shift);
90 const auto& q_add = View(in.msm_add);
91 const auto& q_add_shift = View(in.msm_add_shift);
92 const auto& q_skew = View(in.msm_skew);
93 const auto& q_skew_shift = View(in.msm_skew_shift);
94 const auto& q_double = View(in.msm_double);
95 const auto& q_double_shift = View(in.msm_double_shift);
96 const auto& msm_size = View(in.msm_size_of_msm);
97 const auto& pc = View(in.msm_pc);
98 const auto& pc_shift = View(in.msm_pc_shift);
99 const auto& count = View(in.msm_count);
100 const auto& count_shift = View(in.msm_count_shift);
101 auto is_not_first_row = (-lagrange_first + 1);
275 auto add = [&](
auto& xb,
auto& yb,
auto& xa,
auto& ya,
auto& lambda,
auto& selector,
auto& collision_relation) {
279 auto slope_relation = selector * (lambda * (xb - xa - 1) - (yb - ya)) + lambda;
280 collision_relation += selector * (xb - xa);
284 auto x_out = lambda.sqr() + (-xb - xa - xa) * selector + xa;
288 auto y_out = lambda * (xa - x_out) + (-ya - ya) * selector + ya;
325 [&](
auto& xb,
auto& yb,
auto& xa,
auto& ya,
auto& lambda,
auto& selector,
auto& collision_relation) {
329 constexpr uint256_t oxu = offset_generator.x;
330 constexpr uint256_t oyu = offset_generator.y;
331 const Accumulator xo(oxu);
332 const Accumulator yo(oyu);
334 auto x = xo * selector + xb * (-selector + 1);
335 auto y = yo * selector + yb * (-selector + 1);
336 auto slope_relation = lambda * (x - xa) - (y - ya);
337 collision_relation += (xa - x);
338 auto x_out = lambda * lambda + (-x - xa);
339 auto y_out = lambda * (xa - x_out) - ya;
344 Accumulator x1_collision_relation(0);
345 Accumulator x2_collision_relation(0);
346 Accumulator x3_collision_relation(0);
347 Accumulator x4_collision_relation(0);
350 auto [x_t1, y_t1, add_slope_relation1] =
351 first_add(acc_x, acc_y, x1, y1, lambda1, msm_transition, x1_collision_relation);
352 auto [x_t2, y_t2, add_slope_relation2] =
353 add(x2, y2, x_t1, y_t1, lambda2, add2, x2_collision_relation);
354 auto [x_t3, y_t3, add_slope_relation3] =
355 add(x3, y3, x_t2, y_t2, lambda3, add3, x3_collision_relation);
356 auto [x_t4, y_t4, add_slope_relation4] =
357 add(x4, y4, x_t3, y_t3, lambda4, add4, x4_collision_relation);
360 std::get<0>(accumulator) += q_add * (acc_x_shift - x_t4) * scaling_factor;
361 std::get<1>(accumulator) += q_add * (acc_y_shift - y_t4) * scaling_factor;
363 std::get<2>(accumulator) += q_add * add_slope_relation1 * scaling_factor;
364 std::get<36>(accumulator) += q_add * add_slope_relation2 * scaling_factor;
365 std::get<37>(accumulator) += q_add * add_slope_relation3 * scaling_factor;
366 std::get<38>(accumulator) += q_add * add_slope_relation4 * scaling_factor;
375 auto dbl = [&](
auto& x,
auto& y,
auto& lambda) {
377 auto slope_relation = lambda * (y + y) - (two_x + x) * x;
378 auto x_out = lambda.sqr() - two_x;
379 auto y_out = lambda * (x - x_out) - y;
398 auto [x_d1, y_d1, double_slope_relation1] = dbl(acc_x, acc_y, lambda1);
399 auto [x_d2, y_d2, double_slope_relation2] = dbl(x_d1, y_d1, lambda2);
400 auto [x_d3, y_d3, double_slope_relation3] = dbl(x_d2, y_d2, lambda3);
401 auto [x_d4, y_d4, double_slope_relation4] = dbl(x_d3, y_d3, lambda4);
402 std::get<10>(accumulator) += q_double * (acc_x_shift - x_d4) * scaling_factor;
403 std::get<11>(accumulator) += q_double * (acc_y_shift - y_d4) * scaling_factor;
405 std::get<12>(accumulator) += q_double * double_slope_relation1 * scaling_factor;
406 std::get<39>(accumulator) += q_double * double_slope_relation2 * scaling_factor;
407 std::get<40>(accumulator) += q_double * double_slope_relation3 * scaling_factor;
408 std::get<41>(accumulator) += q_double * double_slope_relation4 * scaling_factor;
424 auto skew1_select = slice1 * inverse_seven;
425 auto skew2_select = slice2 * inverse_seven;
426 auto skew3_select = slice3 * inverse_seven;
427 auto skew4_select = slice4 * inverse_seven;
428 Accumulator x1_skew_collision_relation(0);
429 Accumulator x2_skew_collision_relation(0);
430 Accumulator x3_skew_collision_relation(0);
431 Accumulator x4_skew_collision_relation(0);
437 auto [x_s1, y_s1, skew_slope_relation1] =
438 add(x1, y1, acc_x, acc_y, lambda1, skew1_select, x1_skew_collision_relation);
439 auto [x_s2, y_s2, skew_slope_relation2] =
440 add(x2, y2, x_s1, y_s1, lambda2, skew2_select, x2_skew_collision_relation);
441 auto [x_s3, y_s3, skew_slope_relation3] =
442 add(x3, y3, x_s2, y_s2, lambda3, skew3_select, x3_skew_collision_relation);
443 auto [x_s4, y_s4, skew_slope_relation4] =
444 add(x4, y4, x_s3, y_s3, lambda4, skew4_select, x4_skew_collision_relation);
447 std::get<3>(accumulator) += q_skew * (acc_x_shift - x_s4) * scaling_factor;
448 std::get<4>(accumulator) += q_skew * (acc_y_shift - y_s4) * scaling_factor;
450 std::get<5>(accumulator) += q_skew * skew_slope_relation1 * scaling_factor;
451 std::get<42>(accumulator) += q_skew * skew_slope_relation2 * scaling_factor;
452 std::get<43>(accumulator) += q_skew * skew_slope_relation3 * scaling_factor;
453 std::get<44>(accumulator) += q_skew * skew_slope_relation4 * scaling_factor;
458 const auto add_first_point = add1 * q_add + q_skew * skew1_select;
459 const auto add_second_point = add2 * q_add + q_skew * skew2_select;
460 const auto add_third_point = add3 * q_add + q_skew * skew3_select;
461 const auto add_fourth_point = add4 * q_add + q_skew * skew4_select;
464 const auto x1_delta = x1_skew_collision_relation * q_skew + x1_collision_relation * q_add;
465 const auto x2_delta = x2_skew_collision_relation * q_skew + x2_collision_relation * q_add;
466 const auto x3_delta = x3_skew_collision_relation * q_skew + x3_collision_relation * q_add;
467 const auto x4_delta = x4_skew_collision_relation * q_skew + x4_collision_relation * q_add;
469 std::get<6>(accumulator) += (x1_delta * collision_inverse1 - add_first_point) * scaling_factor;
470 std::get<7>(accumulator) += (x2_delta * collision_inverse2 - add_second_point) * scaling_factor;
471 std::get<8>(accumulator) += (x3_delta * collision_inverse3 - add_third_point) * scaling_factor;
472 std::get<9>(accumulator) += (x4_delta * collision_inverse4 - add_fourth_point) * scaling_factor;
475 std::get<13>(accumulator) += (-add1 + 1) * slice1 * scaling_factor;
476 std::get<14>(accumulator) += (-add2 + 1) * slice2 * scaling_factor;
477 std::get<15>(accumulator) += (-add3 + 1) * slice3 * scaling_factor;
478 std::get<16>(accumulator) += (-add4 + 1) * slice4 * scaling_factor;
483 std::get<17>(accumulator) += (q_add * q_double + q_add * q_skew + q_double * q_skew) * scaling_factor;
499 auto no_op_selector =
500 (-q_add + 1) * (-q_double + 1) * (-q_skew + 1) * (-msm_transition + 1) * (-lagrange_first + 1);
501 std::get<45>(accumulator) += no_op_selector * (acc_x_shift - acc_x) * scaling_factor;
502 std::get<46>(accumulator) += no_op_selector * (acc_y_shift - acc_y) * scaling_factor;
506 std::get<32>(accumulator) += (add1 - q_add - q_skew) * scaling_factor;
512 const auto round_delta = round_shift - round;
521 const auto round_transition = round_delta * (-msm_transition_shift + 1);
522 std::get<18>(accumulator) += round_transition * (round_delta - 1) * scaling_factor;
537 std::get<19>(accumulator) += round_transition * q_skew_shift * (round - 31) * scaling_factor;
538 std::get<20>(accumulator) += round_transition * (q_skew_shift + q_double_shift - 1) * scaling_factor;
539 std::get<35>(accumulator) += (-round_delta + 1) * q_double_shift * scaling_factor;
542 std::get<21>(accumulator) += round_transition * (-q_double_shift + 1) * (-q_skew_shift + 1) * scaling_factor;
549 std::get<22>(accumulator) += q_double * (-q_add_shift + 1) * scaling_factor;
559 std::get<33>(accumulator) += (-msm_transition_shift + 1) * q_skew * (-q_skew_shift + 1) * scaling_factor;
562 std::get<34>(accumulator) += q_skew * (-round + 32) * scaling_factor;
568 std::get<23>(accumulator) += round_delta * count_shift * scaling_factor;
571 std::get<24>(accumulator) += (-msm_transition_shift + 1) * (-round_delta + 1) *
572 (count_shift - count - add1 - add2 - add3 - add4) * scaling_factor;
580 is_not_first_row * (-msm_transition_shift + 1) * round_delta * count_shift * scaling_factor;
583 std::get<26>(accumulator) += msm_transition * round * scaling_factor;
587 std::get<27>(accumulator) += is_not_first_row * msm_transition_shift * (msm_size + pc_shift - pc) * scaling_factor;
597 std::get<28>(accumulator) += add2 * (-add1 + 1) * scaling_factor;
598 std::get<29>(accumulator) += add3 * (-add2 + 1) * scaling_factor;
599 std::get<30>(accumulator) += add4 * (-add3 + 1) * scaling_factor;
609 (q_add * q_add_shift + q_skew * q_skew_shift) * (-add4 + 1) * add1_shift * scaling_factor;