73 using View =
typename Accumulator::View;
75 const auto& precompute_round = View(in.precompute_round);
76 const auto precompute_round2 = precompute_round + precompute_round;
77 const auto precompute_round4 = precompute_round2 + precompute_round2;
79 const auto& gamma = params.gamma;
80 const auto& beta = params.beta;
81 const auto& beta_sqr = params.beta_sqr;
82 const auto& beta_cube = params.beta_cube;
83 const auto& beta_quartic = params.beta_quartic;
84 const auto& precompute_pc = View(in.precompute_pc);
85 const auto& precompute_select = View(in.precompute_select);
88 const auto first_term_tag = beta_quartic * FIRST_TERM_TAG;
89 const auto second_term_tag = beta_quartic * SECOND_TERM_TAG;
90 const auto third_term_tag = beta_quartic * THIRD_TERM_TAG;
106 Accumulator numerator(1);
108 const auto& s0 = View(in.precompute_s1hi);
109 const auto& s1 = View(in.precompute_s1lo);
111 auto wnaf_slice = s0 + s0;
112 wnaf_slice += wnaf_slice;
115 const auto wnaf_slice_input0 =
116 wnaf_slice + gamma + precompute_pc * beta + precompute_round4 * beta_sqr + first_term_tag;
117 numerator *= wnaf_slice_input0;
120 const auto& s0 = View(in.precompute_s2hi);
121 const auto& s1 = View(in.precompute_s2lo);
123 auto wnaf_slice = s0 + s0;
124 wnaf_slice += wnaf_slice;
127 const auto wnaf_slice_input1 =
128 wnaf_slice + gamma + precompute_pc * beta + (precompute_round4 + 1) * beta_sqr + first_term_tag;
129 numerator *= wnaf_slice_input1;
132 const auto& s0 = View(in.precompute_s3hi);
133 const auto& s1 = View(in.precompute_s3lo);
135 auto wnaf_slice = s0 + s0;
136 wnaf_slice += wnaf_slice;
139 const auto wnaf_slice_input2 =
140 wnaf_slice + gamma + precompute_pc * beta + (precompute_round4 + 2) * beta_sqr + first_term_tag;
141 numerator *= wnaf_slice_input2;
144 const auto& s0 = View(in.precompute_s4hi);
145 const auto& s1 = View(in.precompute_s4lo);
147 auto wnaf_slice = s0 + s0;
148 wnaf_slice += wnaf_slice;
150 const auto wnaf_slice_input3 =
151 wnaf_slice + gamma + precompute_pc * beta + (precompute_round4 + 3) * beta_sqr + first_term_tag;
152 numerator *= wnaf_slice_input3;
156 const auto& skew = View(in.precompute_skew);
157 const auto& precompute_point_transition = View(in.precompute_point_transition);
158 const auto skew_input = precompute_point_transition * (skew + gamma + precompute_pc * beta +
159 (precompute_round4 + 4) * beta_sqr + first_term_tag) +
160 (-precompute_point_transition + 1);
161 numerator *= skew_input;
166 const auto& eccvm_set_permutation_delta = params.eccvm_set_permutation_delta;
170 numerator *= precompute_select * (-eccvm_set_permutation_delta + 1) + eccvm_set_permutation_delta;
187 const auto& table_x = View(in.precompute_tx);
188 const auto& table_y = View(in.precompute_ty);
190 const auto& precompute_skew = View(in.precompute_skew);
191 const auto negative_inverse_seven = []() {
193 static constexpr FF negative_inverse_seven =
FF(-7).
invert();
194 return negative_inverse_seven;
197 return negative_inverse_seven;
201 precompute_skew * negative_inverse_seven();
203 const auto& wnaf_scalar_sum = View(in.precompute_scalar_sum);
204 const auto w0 = convert_to_wnaf<Accumulator>(View(in.precompute_s1hi), View(in.precompute_s1lo));
205 const auto w1 = convert_to_wnaf<Accumulator>(View(in.precompute_s2hi), View(in.precompute_s2lo));
206 const auto w2 = convert_to_wnaf<Accumulator>(View(in.precompute_s3hi), View(in.precompute_s3lo));
207 const auto w3 = convert_to_wnaf<Accumulator>(View(in.precompute_s4hi), View(in.precompute_s4lo));
210 row_slice += row_slice;
211 row_slice += row_slice;
212 row_slice += row_slice;
213 row_slice += row_slice;
215 row_slice += row_slice;
216 row_slice += row_slice;
217 row_slice += row_slice;
218 row_slice += row_slice;
220 row_slice += row_slice;
221 row_slice += row_slice;
222 row_slice += row_slice;
223 row_slice += row_slice;
226 auto scalar_sum_full = wnaf_scalar_sum + wnaf_scalar_sum;
227 scalar_sum_full += scalar_sum_full;
228 scalar_sum_full += scalar_sum_full;
229 scalar_sum_full += scalar_sum_full;
230 scalar_sum_full += scalar_sum_full;
231 scalar_sum_full += scalar_sum_full;
232 scalar_sum_full += scalar_sum_full;
233 scalar_sum_full += scalar_sum_full;
234 scalar_sum_full += scalar_sum_full;
235 scalar_sum_full += scalar_sum_full;
236 scalar_sum_full += scalar_sum_full;
237 scalar_sum_full += scalar_sum_full;
238 scalar_sum_full += scalar_sum_full;
239 scalar_sum_full += scalar_sum_full;
240 scalar_sum_full += scalar_sum_full;
241 scalar_sum_full += scalar_sum_full;
243 row_slice + adjusted_skew;
245 auto precompute_point_transition = View(in.precompute_point_transition);
247 auto point_table_init_read =
248 (precompute_pc + table_x * beta + table_y * beta_sqr + scalar_sum_full * beta_cube + second_term_tag);
249 point_table_init_read =
250 precompute_point_transition * (point_table_init_read + gamma) + (-precompute_point_transition + 1);
252 numerator *= point_table_init_read;
272 const auto& lagrange_first = View(in.lagrange_first);
273 const auto& partial_msm_transition_shift = View(in.msm_transition_shift);
274 const auto msm_transition_shift = (-lagrange_first + 1) * partial_msm_transition_shift;
275 const auto& msm_pc_shift = View(in.msm_pc_shift);
277 const auto& msm_x_shift = View(in.msm_accumulator_x_shift);
278 const auto& msm_y_shift = View(in.msm_accumulator_y_shift);
279 const auto& msm_size = View(in.msm_size_of_msm);
293 auto msm_result_write =
294 msm_pc_shift + msm_x_shift * beta + msm_y_shift * beta_sqr + msm_size * beta_cube + third_term_tag;
297 msm_result_write = msm_transition_shift * (msm_result_write + gamma) + (-msm_transition_shift + 1);
298 numerator *= msm_result_write;
307 using View =
typename Accumulator::View;
311 const auto& gamma = params.gamma;
312 const auto& beta = params.beta;
313 const auto& beta_sqr = params.beta_sqr;
314 const auto& beta_cube = params.beta_cube;
315 const auto& beta_quartic = params.beta_quartic;
316 const auto& msm_pc = View(in.msm_pc);
317 const auto& msm_count = View(in.msm_count);
318 const auto& msm_round = View(in.msm_round);
321 const auto first_term_tag = beta_quartic * FIRST_TERM_TAG;
322 const auto second_term_tag = beta_quartic * SECOND_TERM_TAG;
323 const auto third_term_tag = beta_quartic * THIRD_TERM_TAG;
330 Accumulator denominator(1);
332 const auto& add1 = View(in.msm_add1);
333 const auto& msm_slice1 = View(in.msm_slice1);
335 auto wnaf_slice_output1 =
336 add1 * (msm_slice1 + gamma + (msm_pc - msm_count) * beta + msm_round * beta_sqr + first_term_tag) +
338 denominator *= wnaf_slice_output1;
341 const auto& add2 = View(in.msm_add2);
342 const auto& msm_slice2 = View(in.msm_slice2);
344 auto wnaf_slice_output2 =
345 add2 * (msm_slice2 + gamma + (msm_pc - msm_count - 1) * beta + msm_round * beta_sqr + first_term_tag) +
347 denominator *= wnaf_slice_output2;
350 const auto& add3 = View(in.msm_add3);
351 const auto& msm_slice3 = View(in.msm_slice3);
353 auto wnaf_slice_output3 =
354 add3 * (msm_slice3 + gamma + (msm_pc - msm_count - 2) * beta + msm_round * beta_sqr + first_term_tag) +
356 denominator *= wnaf_slice_output3;
359 const auto& add4 = View(in.msm_add4);
360 const auto& msm_slice4 = View(in.msm_slice4);
361 auto wnaf_slice_output4 =
362 add4 * (msm_slice4 + gamma + (msm_pc - msm_count - 3) * beta + msm_round * beta_sqr + first_term_tag) +
364 denominator *= wnaf_slice_output4;
378 const auto& transcript_pc = View(in.transcript_pc);
380 const auto& transcript_Px = View(in.transcript_Px);
381 const auto& transcript_Py = View(in.transcript_Py);
382 const auto& z1 = View(in.transcript_z1);
383 const auto& z2 = View(in.transcript_z2);
384 const auto& z1_zero = View(in.transcript_z1zero);
385 const auto& z2_zero = View(in.transcript_z2zero);
386 const auto& base_infinity = View(in.transcript_base_infinity);
387 const auto& transcript_mul = View(in.transcript_mul);
389 const auto& lookup_first = (-z1_zero + 1);
390 const auto& lookup_second = (-z2_zero + 1);
393 auto transcript_input1 = transcript_pc + transcript_Px * beta + transcript_Py * beta_sqr + z1 * beta_cube +
395 auto transcript_input2 = (transcript_pc - lookup_first) + transcript_Px * cube_root_unity * beta -
396 transcript_Py * beta_sqr + z2 * beta_cube + second_term_tag;
414 transcript_input1 = (transcript_input1 + gamma) * lookup_first + (-lookup_first + 1);
415 transcript_input2 = (transcript_input2 + gamma) * lookup_second + (-lookup_second + 1);
418 auto transcript_product = (transcript_input1 * transcript_input2) * (-base_infinity + 1) + base_infinity;
421 auto point_table_init_write = transcript_mul * transcript_product + (-transcript_mul + 1);
422 denominator *= point_table_init_write;
440 const auto& transcript_pc_shift = View(in.transcript_pc_shift);
441 const auto& transcript_msm_x = View(in.transcript_msm_x);
442 const auto& transcript_msm_y = View(in.transcript_msm_y);
443 const auto& transcript_msm_transition = View(in.transcript_msm_transition);
444 const auto& transcript_msm_count = View(in.transcript_msm_count);
445 const auto& z1_zero = View(in.transcript_z1zero);
446 const auto& z2_zero = View(in.transcript_z2zero);
447 const auto& transcript_mul = View(in.transcript_mul);
448 const auto& base_infinity = View(in.transcript_base_infinity);
451 auto full_msm_count =
452 transcript_msm_count + transcript_mul * ((-z1_zero + 1) + (-z2_zero + 1)) * (-base_infinity + 1);
454 auto msm_result_read = transcript_pc_shift + transcript_msm_x * beta + transcript_msm_y * beta_sqr +
455 full_msm_count * beta_cube + third_term_tag;
456 msm_result_read = transcript_msm_transition * (msm_result_read + gamma) + (-transcript_msm_transition + 1);
457 denominator *= msm_result_read;