77 for (
const auto&
event : events) {
83 bool x_match = p.
x() == q.
x();
84 bool y_match = p.
y() == q.
y();
89 bool double_predicate = (x_match && y_match);
93 bool add_predicate = !x_match;
96 bool inverse_predicate = (x_match && !y_match);
118 FF lambda = compute_lambda(double_predicate, add_predicate, result_is_infinity, p, q);
124 { C::ecc_p_x, p.
x() },
125 { C::ecc_p_y, p.
y() },
128 { C::ecc_q_x, q.
x() },
129 { C::ecc_q_y, q.
y() },
132 { C::ecc_r_x, result.
x() },
133 { C::ecc_r_y, result.
y() },
136 { C::ecc_use_computed_result, use_computed_result },
139 { C::ecc_x_match, x_match },
140 { C::ecc_inv_x_diff, q.
x() - p.
x() },
141 { C::ecc_y_match, y_match },
142 { C::ecc_inv_y_diff, q.
y() - p.
y() },
145 { C::ecc_double_op, double_predicate },
147 !result_is_infinity && double_predicate ? (p.
y() * 2)
151 { C::ecc_add_op, add_predicate },
153 { C::ecc_result_infinity, result_is_infinity },
155 { C::ecc_lambda, lambda },
167 trace.invert_columns({ { C::ecc_inv_x_diff, C::ecc_inv_y_diff, C::ecc_inv_2_p_y } });
190 for (
const auto&
event : events) {
192 size_t num_intermediate_states =
event.intermediate_states.size();
196 for (
size_t i = 0; i < num_intermediate_states; ++i) {
198 size_t intermediate_state_idx = num_intermediate_states - i - 1;
202 bool is_end = intermediate_state_idx == 0;
204 bool is_start = i == 0;
211 bool bit = state.
bit;
214 { { { C::scalar_mul_sel, 1 },
217 { C::scalar_mul_scalar,
event.scalar },
219 { C::scalar_mul_point_x, point.
x() },
220 { C::scalar_mul_point_y, point.
y() },
221 { C::scalar_mul_point_inf, point.
is_infinity() ? 1 : 0 },
223 { C::scalar_mul_const_two, 2 },
226 { C::scalar_mul_res_x, res.
x() },
227 { C::scalar_mul_res_y, res.
y() },
228 { C::scalar_mul_res_inf, res.
is_infinity() ? 1 : 0 },
230 { C::scalar_mul_start, is_start },
231 { C::scalar_mul_end, is_end },
232 { C::scalar_mul_sel_not_end, !is_end },
234 { C::scalar_mul_bit, bit },
235 { C::scalar_mul_bit_idx, intermediate_state_idx },
237 { C::scalar_mul_temp_x, temp.
x() },
238 { C::scalar_mul_temp_y, temp.
y() },
239 { C::scalar_mul_temp_inf, temp.
is_infinity() ? 1 : 0 },
242 C::scalar_mul_should_add,
278 for (
const auto&
event : events) {
280 uint64_t
dst_addr =
static_cast<uint64_t
>(
event.dst_address);
288 bool p_is_on_curve =
event.p.on_curve();
289 FF p_is_on_curve_eqn = compute_curve_eqn_diff(
event.p);
290 FF p_is_on_curve_eqn_inv = p_is_on_curve ?
FF::zero() : p_is_on_curve_eqn.invert();
292 bool q_is_on_curve =
event.q.on_curve();
293 FF q_is_on_curve_eqn = compute_curve_eqn_diff(
event.q);
294 FF q_is_on_curve_eqn_inv = q_is_on_curve ?
FF::zero() : q_is_on_curve_eqn.invert();
296 bool error = dst_out_of_range_err || !p_is_on_curve || !q_is_on_curve;
300 { C::ecc_add_mem_sel, 1 },
301 { C::ecc_add_mem_execution_clk,
event.execution_clk },
302 { C::ecc_add_mem_space_id,
event.space_id },
305 { C::ecc_add_mem_sel_dst_out_of_range_err, dst_out_of_range_err ? 1 : 0 },
307 { C::ecc_add_mem_sel_p_not_on_curve_err, !p_is_on_curve ? 1 : 0 },
308 { C::ecc_add_mem_p_is_on_curve_eqn, p_is_on_curve_eqn },
309 { C::ecc_add_mem_p_is_on_curve_eqn_inv, p_is_on_curve_eqn_inv },
311 { C::ecc_add_mem_sel_q_not_on_curve_err, !q_is_on_curve ? 1 : 0 },
312 { C::ecc_add_mem_q_is_on_curve_eqn, q_is_on_curve_eqn },
313 { C::ecc_add_mem_q_is_on_curve_eqn_inv, q_is_on_curve_eqn_inv },
315 { C::ecc_add_mem_err, error ? 1 : 0 },
317 { C::ecc_add_mem_dst_addr_0_,
dst_addr },
318 { C::ecc_add_mem_dst_addr_1_,
dst_addr + 1 },
320 { C::ecc_add_mem_p_x,
event.p.x() },
321 { C::ecc_add_mem_p_y,
event.p.y() },
323 { C::ecc_add_mem_q_x,
event.q.x() },
324 { C::ecc_add_mem_q_y,
event.q.y() },
326 { C::ecc_add_mem_p_is_inf,
event.p.is_infinity() ? 1 : 0 },
327 { C::ecc_add_mem_q_is_inf,
event.q.is_infinity() ? 1 : 0 },
329 { C::ecc_add_mem_sel_should_exec, error ? 0 : 1 },
330 { C::ecc_add_mem_res_x,
event.result.x() },
331 { C::ecc_add_mem_res_y,
event.result.y() },