39 const Fq& previous_accumulator,
40 const Fq& batching_challenge_v,
41 const Fq& evaluation_input_x)
46 constexpr size_t TOP_QUOTIENT_MICROLIMB_BITS =
56 auto uint512_t_to_limbs = [](
const uint512_t& original) {
67 auto split_wide_limb_into_2_limbs = [](
const Fr& wide_limb) {
75 auto split_standard_limb_into_micro_limbs = [](
const Fr& limb) {
93 auto split_top_limb_into_micro_limbs = [](
const Fr& limb,
const size_t last_limb_bits) {
109 auto split_top_z_limb_into_micro_limbs = [](
const Fr& limb,
const size_t last_limb_bits) {
125 auto split_relation_limb_into_micro_limbs = [](
const Fr& limb) {
152 auto uint_previous_accumulator =
uint512_t(previous_accumulator);
160 auto uint_v_squared =
uint512_t(v_squared);
162 auto uint_v_quarted =
uint512_t(v_quarted);
172 auto [p_x_0, p_x_1] = split_wide_limb_into_2_limbs(ultra_op.
x_lo);
173 auto [p_x_2, p_x_3] = split_wide_limb_into_2_limbs(ultra_op.
x_hi);
175 auto [p_y_0, p_y_1] = split_wide_limb_into_2_limbs(ultra_op.
y_lo);
176 auto [p_y_2, p_y_3] = split_wide_limb_into_2_limbs(ultra_op.
y_hi);
180 auto z_1_limbs = split_wide_limb_into_2_limbs(ultra_op.
z_1);
181 auto z_2_limbs = split_wide_limb_into_2_limbs(ultra_op.
z_2);
186 const Fq remainder = previous_accumulator *
evaluation_input_x + base_z_2 * v_quarted + base_z_1 * v_cubed +
190 uint512_t quotient_by_modulus = uint_previous_accumulator * uint_x + uint_z2 * uint_v_quarted +
191 uint_z1 * uint_v_cubed + uint_p_y * uint_v_squared + uint_p_x * uint_v + uint_op -
204 Fr low_wide_relation_limb_part_1 = previous_accumulator_limbs[0] * x_witnesses[0] + op_code +
205 v_witnesses[0] * p_x_limbs[0] + v_squared_witnesses[0] * p_y_limbs[0] +
206 v_cubed_witnesses[0] * z_1_limbs[0] + v_quarted_witnesses[0] * z_2_limbs[0] +
210 Fr low_wide_relation_limb =
211 low_wide_relation_limb_part_1 +
212 (previous_accumulator_limbs[1] * x_witnesses[0] + previous_accumulator_limbs[0] * x_witnesses[1] +
213 v_witnesses[1] * p_x_limbs[0] + p_x_limbs[1] * v_witnesses[0] + v_squared_witnesses[1] * p_y_limbs[0] +
214 v_squared_witnesses[0] * p_y_limbs[1] + v_cubed_witnesses[1] * z_1_limbs[0] +
215 z_1_limbs[1] * v_cubed_witnesses[0] + v_quarted_witnesses[1] * z_2_limbs[0] +
228 Fr high_wide_relation_limb =
229 low_wide_relation_limb_divided + previous_accumulator_limbs[2] * x_witnesses[0] +
230 previous_accumulator_limbs[1] * x_witnesses[1] + previous_accumulator_limbs[0] * x_witnesses[2] +
231 v_witnesses[2] * p_x_limbs[0] + v_witnesses[1] * p_x_limbs[1] + v_witnesses[0] * p_x_limbs[2] +
232 v_squared_witnesses[2] * p_y_limbs[0] + v_squared_witnesses[1] * p_y_limbs[1] +
233 v_squared_witnesses[0] * p_y_limbs[2] + v_cubed_witnesses[2] * z_1_limbs[0] +
234 v_cubed_witnesses[1] * z_1_limbs[1] + v_quarted_witnesses[2] * z_2_limbs[0] +
238 (previous_accumulator_limbs[3] * x_witnesses[0] + previous_accumulator_limbs[2] * x_witnesses[1] +
239 previous_accumulator_limbs[1] * x_witnesses[2] + previous_accumulator_limbs[0] * x_witnesses[3] +
240 v_witnesses[3] * p_x_limbs[0] + v_witnesses[2] * p_x_limbs[1] + v_witnesses[1] * p_x_limbs[2] +
241 v_witnesses[0] * p_x_limbs[3] + v_squared_witnesses[3] * p_y_limbs[0] + v_squared_witnesses[2] * p_y_limbs[1] +
242 v_squared_witnesses[1] * p_y_limbs[2] + v_squared_witnesses[0] * p_y_limbs[3] +
243 v_cubed_witnesses[3] * z_1_limbs[0] + v_cubed_witnesses[2] * z_1_limbs[1] +
244 v_quarted_witnesses[3] * z_2_limbs[0] + v_quarted_witnesses[2] * z_2_limbs[1] +
247 remainder_limbs[3]) *
254 auto high_wide_relation_limb_divided = high_wide_relation_limb *
SHIFT_2_INVERSE;
265 for (
size_t i = 0; i < last_limb_index; i++) {
266 P_x_microlimbs[i] = split_standard_limb_into_micro_limbs(p_x_limbs[i]);
268 P_x_microlimbs[last_limb_index] =
269 split_top_limb_into_micro_limbs(p_x_limbs[last_limb_index], TOP_STANDARD_MICROLIMB_BITS);
272 for (
size_t i = 0; i < last_limb_index; i++) {
273 P_y_microlimbs[i] = split_standard_limb_into_micro_limbs(p_y_limbs[i]);
275 P_y_microlimbs[last_limb_index] =
276 split_top_limb_into_micro_limbs(p_y_limbs[last_limb_index], TOP_STANDARD_MICROLIMB_BITS);
280 z_1_microlimbs[i] = split_standard_limb_into_micro_limbs(z_1_limbs[i]);
281 z_2_microlimbs[i] = split_standard_limb_into_micro_limbs(z_2_limbs[i]);
284 split_top_z_limb_into_micro_limbs(z_1_limbs[
NUM_Z_LIMBS - 1], TOP_Z_MICROLIMB_BITS);
286 split_top_z_limb_into_micro_limbs(z_2_limbs[
NUM_Z_LIMBS - 1], TOP_Z_MICROLIMB_BITS);
289 for (
size_t i = 0; i < last_limb_index; i++) {
290 current_accumulator_microlimbs[i] = split_standard_limb_into_micro_limbs(remainder_limbs[i]);
292 current_accumulator_microlimbs[last_limb_index] =
293 split_top_limb_into_micro_limbs(remainder_limbs[last_limb_index], TOP_STANDARD_MICROLIMB_BITS);
296 for (
size_t i = 0; i < last_limb_index; i++) {
297 quotient_microlimbs[i] = split_standard_limb_into_micro_limbs(quotient_limbs[i]);
299 quotient_microlimbs[last_limb_index] =
300 split_top_limb_into_micro_limbs(quotient_limbs[last_limb_index], TOP_QUOTIENT_MICROLIMB_BITS);
305 .P_x_limbs = p_x_limbs,
306 .P_x_microlimbs = P_x_microlimbs,
307 .P_y_limbs = p_y_limbs,
308 .P_y_microlimbs = P_y_microlimbs,
309 .z_1_limbs = z_1_limbs,
310 .z_1_microlimbs = z_1_microlimbs,
311 .z_2_limbs = z_2_limbs,
312 .z_2_microlimbs = z_2_microlimbs,
313 .previous_accumulator = previous_accumulator_limbs,
314 .current_accumulator = remainder_limbs,
315 .current_accumulator_microlimbs = current_accumulator_microlimbs,
316 .quotient_binary_limbs = quotient_limbs,
317 .quotient_microlimbs = quotient_microlimbs,
318 .relation_wide_limbs = { low_wide_relation_limb_divided, high_wide_relation_limb_divided },
319 .relation_wide_microlimbs = { split_relation_limb_into_micro_limbs(low_wide_relation_limb_divided),
320 split_relation_limb_into_micro_limbs(high_wide_relation_limb_divided) },
478 size_t wire_index = starting_wire;
479 for (
auto element : input) {