44 const AllEntities& in,
46 const FF& scaling_factor)
49 using View =
typename Accumulator::View;
51 auto scalar_sum = View(in.precompute_scalar_sum);
52 auto scalar_sum_new = View(in.precompute_scalar_sum_shift);
53 auto q_transition = View(in.precompute_point_transition);
54 auto round = View(in.precompute_round);
55 auto round_shift = View(in.precompute_round_shift);
56 auto pc = View(in.precompute_pc);
57 auto pc_shift = View(in.precompute_pc_shift);
60 auto precompute_select = View(in.precompute_select);
61 auto precompute_select_shift = View(in.precompute_select_shift);
63 const auto& precompute_skew = View(in.precompute_skew);
66 View(in.precompute_s1hi), View(in.precompute_s1lo), View(in.precompute_s2hi), View(in.precompute_s2lo),
67 View(in.precompute_s3hi), View(in.precompute_s3lo), View(in.precompute_s4hi), View(in.precompute_s4lo),
70 const auto range_constraint_slice_to_2_bits = [&scaling_factor](
const View& s,
auto& acc) {
71 acc += ((s - 1).sqr() - 1) * ((s - 2).sqr() - 1) * scaling_factor;
74 const auto convert_to_wnaf = [](
const View& s0,
const View& s1) {
78 auto naf = t + t - 15;
82 const auto scaled_transition = q_transition * scaling_factor;
83 const auto scaled_transition_is_zero = -scaled_transition + scaling_factor;
89 range_constraint_slice_to_2_bits(slices[0],
std::get<0>(accumulator));
90 range_constraint_slice_to_2_bits(slices[1],
std::get<1>(accumulator));
91 range_constraint_slice_to_2_bits(slices[2],
std::get<2>(accumulator));
92 range_constraint_slice_to_2_bits(slices[3],
std::get<3>(accumulator));
93 range_constraint_slice_to_2_bits(slices[4],
std::get<4>(accumulator));
94 range_constraint_slice_to_2_bits(slices[5],
std::get<5>(accumulator));
95 range_constraint_slice_to_2_bits(slices[6],
std::get<6>(accumulator));
96 range_constraint_slice_to_2_bits(slices[7],
std::get<7>(accumulator));
106 const auto s1_shift = View(in.precompute_s1hi_shift);
107 const auto s1_shift_msb_set = (s1_shift - 2) * (s1_shift - 3);
108 std::get<20>(accumulator) += scaled_transition * precompute_select_shift * s1_shift_msb_set;
116 const auto w0 = convert_to_wnaf(slices[0], slices[1]);
117 const auto w1 = convert_to_wnaf(slices[2], slices[3]);
118 const auto w2 = convert_to_wnaf(slices[4], slices[5]);
119 const auto w3 = convert_to_wnaf(slices[6], slices[7]);
131 row_slice += row_slice;
132 row_slice += row_slice;
133 row_slice += row_slice;
134 row_slice += row_slice;
136 row_slice += row_slice;
137 row_slice += row_slice;
138 row_slice += row_slice;
139 row_slice += row_slice;
141 row_slice += row_slice;
142 row_slice += row_slice;
143 row_slice += row_slice;
144 row_slice += row_slice;
146 auto sum_delta = scalar_sum *
FF(1ULL << 16) + row_slice;
147 const auto check_sum = scalar_sum_new - sum_delta;
148 std::get<8>(accumulator) += precompute_select * check_sum * scaled_transition_is_zero;
175 const auto round_check = round_shift - round - 1;
176 std::get<9>(accumulator) += precompute_select * scaled_transition * ((round - round_check - 7) + round_check);
177 std::get<10>(accumulator) += precompute_select * scaled_transition * round_shift;
186 std::get<11>(accumulator) += precompute_select * scalar_sum_new * scaled_transition;
189 const auto pc_delta = pc_shift - pc;
191 precompute_select * (scaled_transition * ((-pc_delta - pc_delta - 1)) + pc_delta * scaling_factor);
202 std::get<13>(accumulator) += precompute_select * (precompute_skew * (precompute_skew - 7)) * scaling_factor;
204 const auto precompute_select_zero = (-precompute_select + 1) * scaling_factor;
205 std::get<14>(accumulator) += precompute_select_zero * (w0 + 15);
206 std::get<15>(accumulator) += precompute_select_zero * (w1 + 15);
207 std::get<16>(accumulator) += precompute_select_zero * (w2 + 15);
208 std::get<17>(accumulator) += precompute_select_zero * (w3 + 15);
210 std::get<18>(accumulator) += precompute_select_zero * round;
211 std::get<19>(accumulator) += precompute_select_zero * pc;