136 const uint32_t total_number_of_muls)
138 const size_t num_vm_entries = vm_operations.size();
140 const size_t transcript_size = num_vm_entries + 2;
146 std::vector<FF> inverse_trace_x(num_vm_entries);
147 std::vector<FF> inverse_trace_y(num_vm_entries);
148 std::vector<FF> transcript_msm_x_inverse_trace(num_vm_entries);
149 std::vector<FF> add_lambda_denominator(num_vm_entries);
150 std::vector<FF> add_lambda_numerator(num_vm_entries);
151 std::vector<FF> msm_count_at_transition_inverse_trace(num_vm_entries);
161 .
pc = total_number_of_muls,
165 .is_accumulator_empty =
true,
185 hiding_row.
pc = state.pc;
188 accumulator_trace[0] = state.accumulator;
189 msm_accumulator_trace[0] = Element::infinity();
190 intermediate_accumulator_trace[0] = Element::infinity();
191 msm_count_at_transition_inverse_trace[0] = 0;
197 for (
size_t i = 1; i < num_vm_entries; i++) {
201 updated_state = state;
205 const bool z1_zero = is_mul ? entry.
z1 == 0 :
true;
206 const bool z2_zero = is_mul ? entry.
z2 == 0 :
true;
208 const bool base_point_infinity = entry.
base_point.is_point_at_infinity();
209 uint32_t num_muls = 0;
212 num_muls =
static_cast<uint32_t
>(!z1_zero) +
static_cast<uint32_t
>(!z2_zero);
213 if (base_point_infinity) {
217 updated_state.
pc = state.pc - num_muls;
227 const bool last_row = (i == (num_vm_entries - 1));
229 const bool next_not_msm = last_row || !vm_operations[i + 1].op_code.mul;
235 const bool msm_transition = is_mul && next_not_msm && (state.count + num_muls > 0);
238 const bool current_ongoing_msm = is_mul && !next_not_msm;
240 updated_state.
count = current_ongoing_msm ? state.count + num_muls : 0;
249 if (msm_transition) {
260 msm_count_at_transition_inverse_trace[i] = ((state.count + num_muls) == 0) ? 0 :
FF(state.count + num_muls);
264 accumulator_trace[i] = state.accumulator;
265 msm_accumulator_trace[i] = msm_transition ? updated_state.
msm_accumulator : Element::infinity();
266 intermediate_accumulator_trace[i] =
269 state = updated_state;
271 if (is_mul && next_not_msm) {
280 transcript_state, accumulator_trace, msm_accumulator_trace, intermediate_accumulator_trace);
284 for (
size_t i = 0; i < accumulator_trace.size(); ++i) {
291 if (msm_transition || is_add) {
295 intermediate_accumulator_trace[i],
296 transcript_msm_x_inverse_trace[i],
297 msm_accumulator_trace[i],
298 accumulator_trace[i],
305 intermediate_accumulator_trace[i],
306 accumulator_trace[i],
307 add_lambda_numerator[i],
308 add_lambda_denominator[i]);
312 add_lambda_numerator[i] = 0;
313 add_lambda_denominator[i] = 0;
314 inverse_trace_x[i] = 0;
315 inverse_trace_y[i] = 0;
316 transcript_msm_x_inverse_trace[i] = 0;
317 msm_count_at_transition_inverse_trace[i] = 0;
326 FF::batch_invert(&msm_count_at_transition_inverse_trace[0], num_vm_entries);
329 for (
size_t i = 0; i < num_vm_entries; ++i) {
341 return transcript_state;
594 const Element& intermediate_accumulator,
596 FF& add_lambda_numerator,
597 FF& add_lambda_denominator)
601 const bool vm_infinity = vm_point.is_point_at_infinity();
602 const bool accumulator_infinity = accumulator.is_point_at_infinity();
605 const FF vm_x = vm_infinity ? 0 : vm_point.x;
606 const FF vm_y = vm_infinity ? 0 : vm_point.y;
609 const FF accumulator_x = accumulator_infinity ? 0 : accumulator.x;
610 const FF accumulator_y = accumulator_infinity ? 0 : accumulator.y;
616 if ((accumulator_x == vm_x) && (accumulator_y == vm_y) && !vm_infinity && !accumulator_infinity) {
618 add_lambda_denominator = vm_y + vm_y;
619 add_lambda_numerator = vm_x * vm_x * 3;
620 }
else if ((accumulator_x != vm_x) && !vm_infinity && !accumulator_infinity) {
622 add_lambda_denominator = accumulator_x - vm_x;
623 add_lambda_numerator = accumulator_y - vm_y;