56 for (
const auto&
event : events) {
61 bool x_match = p.
x() == q.
x();
62 bool y_match = p.
y() == q.
y();
64 bool double_predicate = (x_match && y_match);
68 bool add_predicate = !x_match;
70 bool infinity_predicate = (x_match && !y_match);
81 FF lambda = compute_lambda(double_predicate, add_predicate, result_is_infinity, p, q);
87 { C::ecc_p_x, p.
x() },
88 { C::ecc_p_y, p.
y() },
91 { C::ecc_q_x, q.
x() },
92 { C::ecc_q_y, q.
y() },
95 { C::ecc_r_x, result.
x() },
96 { C::ecc_r_y, result.
y() },
100 { C::ecc_use_computed_result, use_computed_result },
103 { C::ecc_x_match, x_match },
104 { C::ecc_inv_x_diff, q.
x() - p.
x() },
105 { C::ecc_y_match, y_match },
106 { C::ecc_inv_y_diff, q.
y() - p.
y() },
109 { C::ecc_double_op, double_predicate },
111 !result_is_infinity && double_predicate ? (p.
y() * 2)
115 { C::ecc_add_op, add_predicate },
118 { C::ecc_result_infinity, result_is_infinity },
120 { C::ecc_lambda, lambda },
127 trace.invert_columns({ { C::ecc_inv_x_diff, C::ecc_inv_y_diff, C::ecc_inv_2_p_y } });
136 for (
const auto&
event : events) {
137 size_t num_intermediate_states =
event.intermediate_states.size();
140 for (
size_t i = 0; i < num_intermediate_states; ++i) {
142 size_t intermediate_state_idx = num_intermediate_states - i - 1;
145 bool is_start = i == 0;
147 bool is_end = intermediate_state_idx == 0;
156 bool bit = state.
bit;
159 { { { C::scalar_mul_sel, 1 },
160 { C::scalar_mul_scalar,
event.scalar },
161 { C::scalar_mul_point_x, point.
x() },
162 { C::scalar_mul_point_y, point.
y() },
164 { C::scalar_mul_res_x, res.
x() },
165 { C::scalar_mul_res_y, res.
y() },
167 { C::scalar_mul_start, is_start },
168 { C::scalar_mul_end, is_end },
169 { C::scalar_mul_not_end, !is_end },
170 { C::scalar_mul_bit, bit },
171 { C::scalar_mul_bit_idx, intermediate_state_idx },
172 { C::scalar_mul_temp_x, temp.
x() },
173 { C::scalar_mul_temp_y, temp.
y() },
176 C::scalar_mul_should_add,
179 { C::scalar_mul_bit_radix, 2 } } });
192 for (
const auto&
event : events) {
193 uint64_t
dst_addr =
static_cast<uint64_t
>(
event.dst_address);
201 bool p_is_on_curve =
event.p.on_curve();
202 FF p_is_on_curve_eqn = compute_curve_eqn_diff(
event.p);
203 FF p_is_on_curve_eqn_inv = p_is_on_curve ?
FF::zero() : p_is_on_curve_eqn.invert();
205 bool q_is_on_curve =
event.q.on_curve();
206 FF q_is_on_curve_eqn = compute_curve_eqn_diff(
event.q);
207 FF q_is_on_curve_eqn_inv = q_is_on_curve ?
FF::zero() : q_is_on_curve_eqn.invert();
209 bool error = dst_out_of_range_err || !p_is_on_curve || !q_is_on_curve;
217 { C::ecc_add_mem_sel, 1 },
218 { C::ecc_add_mem_execution_clk,
event.execution_clk },
219 { C::ecc_add_mem_space_id,
event.space_id },
222 { C::ecc_add_mem_sel_dst_out_of_range_err, dst_out_of_range_err ? 1 : 0 },
224 { C::ecc_add_mem_sel_p_not_on_curve_err, !p_is_on_curve ? 1 : 0 },
225 { C::ecc_add_mem_p_is_on_curve_eqn, p_is_on_curve_eqn },
226 { C::ecc_add_mem_p_is_on_curve_eqn_inv, p_is_on_curve_eqn_inv },
228 { C::ecc_add_mem_sel_q_not_on_curve_err, !q_is_on_curve ? 1 : 0 },
229 { C::ecc_add_mem_q_is_on_curve_eqn, q_is_on_curve_eqn },
230 { C::ecc_add_mem_q_is_on_curve_eqn_inv, q_is_on_curve_eqn_inv },
232 { C::ecc_add_mem_err, error ? 1 : 0 },
234 { C::ecc_add_mem_dst_addr_0_,
dst_addr },
235 { C::ecc_add_mem_dst_addr_1_,
dst_addr + 1 },
236 { C::ecc_add_mem_dst_addr_2_,
dst_addr + 2 },
238 { C::ecc_add_mem_p_x,
event.p.x() },
239 { C::ecc_add_mem_p_y,
event.p.y() },
240 { C::ecc_add_mem_p_is_inf,
event.p.is_infinity() ? 1 : 0 },
242 { C::ecc_add_mem_q_x,
event.q.x() },
243 { C::ecc_add_mem_q_y,
event.q.y() },
244 { C::ecc_add_mem_q_is_inf,
event.q.is_infinity() ? 1 : 0 },
246 { C::ecc_add_mem_p_x_n, p_n.
x() },
247 { C::ecc_add_mem_p_y_n, p_n.
y() },
249 { C::ecc_add_mem_q_x_n, q_n.
x() },
250 { C::ecc_add_mem_q_y_n, q_n.
y() },
252 { C::ecc_add_mem_sel_should_exec, error ? 0 : 1 },
253 { C::ecc_add_mem_res_x,
event.result.x() },
254 { C::ecc_add_mem_res_y,
event.result.y() },
255 { C::ecc_add_mem_res_is_inf,
event.result.is_infinity() },