47 const AllEntities& in,
49 const FF& scaling_factor)
52 using View =
typename Accumulator::View;
54 auto scalar_sum = View(in.precompute_scalar_sum);
55 auto scalar_sum_shift = View(in.precompute_scalar_sum_shift);
56 auto q_transition = View(in.precompute_point_transition);
57 auto round = View(in.precompute_round);
58 auto round_shift = View(in.precompute_round_shift);
59 auto pc = View(in.precompute_pc);
60 auto pc_shift = View(in.precompute_pc_shift);
63 auto precompute_select = View(in.precompute_select);
64 auto precompute_select_shift = View(in.precompute_select_shift);
66 const auto& precompute_skew = View(in.precompute_skew);
69 View(in.precompute_s1hi), View(in.precompute_s1lo), View(in.precompute_s2hi), View(in.precompute_s2lo),
70 View(in.precompute_s3hi), View(in.precompute_s3lo), View(in.precompute_s4hi), View(in.precompute_s4lo),
73 const auto range_constraint_slice_to_2_bits = [&scaling_factor](
const View& s,
auto& acc) {
74 acc += ((s - 1).sqr() - 1) * ((s - 2).sqr() - 1) * scaling_factor;
80 const auto convert_to_wnaf = [](
const View& s0,
const View& s1) {
84 auto naf = t + t - 15;
88 const auto scaled_transition = q_transition * scaling_factor;
89 const auto scaled_transition_is_zero =
90 -scaled_transition + scaling_factor;
97 range_constraint_slice_to_2_bits(slices[0],
std::get<0>(accumulator));
98 range_constraint_slice_to_2_bits(slices[1],
std::get<1>(accumulator));
99 range_constraint_slice_to_2_bits(slices[2],
std::get<2>(accumulator));
100 range_constraint_slice_to_2_bits(slices[3],
std::get<3>(accumulator));
101 range_constraint_slice_to_2_bits(slices[4],
std::get<4>(accumulator));
102 range_constraint_slice_to_2_bits(slices[5],
std::get<5>(accumulator));
103 range_constraint_slice_to_2_bits(slices[6],
std::get<6>(accumulator));
104 range_constraint_slice_to_2_bits(slices[7],
std::get<7>(accumulator));
114 const auto s1_shift = View(in.precompute_s1hi_shift);
115 const auto s1_shift_msb_set = (s1_shift - 2) * (s1_shift - 3);
116 std::get<20>(accumulator) += scaled_transition * precompute_select_shift * s1_shift_msb_set;
124 const auto w0 = convert_to_wnaf(slices[0], slices[1]);
125 const auto w1 = convert_to_wnaf(slices[2], slices[3]);
126 const auto w2 = convert_to_wnaf(slices[4], slices[5]);
127 const auto w3 = convert_to_wnaf(slices[6], slices[7]);
141 row_slice += row_slice;
142 row_slice += row_slice;
143 row_slice += row_slice;
144 row_slice += row_slice;
146 row_slice += row_slice;
147 row_slice += row_slice;
148 row_slice += row_slice;
149 row_slice += row_slice;
151 row_slice += row_slice;
152 row_slice += row_slice;
153 row_slice += row_slice;
154 row_slice += row_slice;
156 auto sum_delta = scalar_sum *
FF(1ULL << 16) + row_slice;
157 const auto check_sum = scalar_sum_shift - sum_delta;
158 std::get<8>(accumulator) += precompute_select * check_sum * scaled_transition_is_zero;
207 const auto round_check = round_shift - round - 1;
209 precompute_select * (scaled_transition * (round - round_check - 7) + scaling_factor * round_check);
211 precompute_select * scaled_transition * round_shift;
220 std::get<11>(accumulator) += precompute_select * scaled_transition * scalar_sum_shift;
223 const auto pc_delta = pc_shift - pc;
225 precompute_select * (scaled_transition * ((-pc_delta - pc_delta - 1)) + pc_delta * scaling_factor);
236 std::get<13>(accumulator) += precompute_select * (precompute_skew * (precompute_skew - 7)) * scaling_factor;
240 const auto precompute_select_zero = (-precompute_select + 1) * scaling_factor;
241 std::get<14>(accumulator) += precompute_select_zero * (w0 + 15);
242 std::get<15>(accumulator) += precompute_select_zero * (w1 + 15);
243 std::get<16>(accumulator) += precompute_select_zero * (w2 + 15);
244 std::get<17>(accumulator) += precompute_select_zero * (w3 + 15);
246 std::get<18>(accumulator) += precompute_select_zero * round;
247 std::get<19>(accumulator) += precompute_select_zero * pc;