57 for (
const auto&
event : events) {
62 bool x_match = p.
x() == q.
x();
63 bool y_match = p.
y() == q.
y();
65 bool double_predicate = (x_match && y_match);
66 bool add_predicate = (!x_match && !y_match);
68 bool infinity_predicate = (x_match && !y_match);
77 assert(result_is_infinity == result.
is_infinity() &&
"Inconsistent infinity result assumption");
79 FF lambda = compute_lambda(double_predicate, add_predicate, result_is_infinity, p, q);
85 { C::ecc_p_x, p.
x() },
86 { C::ecc_p_y, p.
y() },
89 { C::ecc_q_x, q.
x() },
90 { C::ecc_q_y, q.
y() },
93 { C::ecc_r_x, result.
x() },
94 { C::ecc_r_y, result.
y() },
98 { C::ecc_use_computed_result, use_computed_result },
101 { C::ecc_x_match, x_match },
102 { C::ecc_inv_x_diff, x_match ?
FF::zero() : (q.
x() - p.
x()).invert() },
103 { C::ecc_y_match, y_match },
104 { C::ecc_inv_y_diff, y_match ?
FF::zero() : (q.
y() - p.
y()).invert() },
107 { C::ecc_double_op, double_predicate },
108 { C::ecc_inv_2_p_y, !result_is_infinity && double_predicate ? (p.
y() * 2).invert() :
FF::zero() },
111 { C::ecc_add_op, add_predicate },
114 { C::ecc_result_infinity, result_is_infinity },
116 { C::ecc_lambda, lambda },
129 for (
const auto&
event : events) {
130 size_t num_intermediate_states =
event.intermediate_states.size();
133 for (
size_t i = 0; i < num_intermediate_states; ++i) {
135 size_t intermediate_state_idx = num_intermediate_states - i - 1;
138 bool is_start = i == 0;
140 bool is_end = intermediate_state_idx == 0;
149 bool bit = state.
bit;
152 { { { C::scalar_mul_sel, 1 },
153 { C::scalar_mul_scalar,
event.scalar },
154 { C::scalar_mul_point_x, point.
x() },
155 { C::scalar_mul_point_y, point.
y() },
157 { C::scalar_mul_res_x, res.
x() },
158 { C::scalar_mul_res_y, res.
y() },
160 { C::scalar_mul_start, is_start },
161 { C::scalar_mul_end, is_end },
162 { C::scalar_mul_not_end, !is_end },
163 { C::scalar_mul_bit, bit },
164 { C::scalar_mul_bit_idx, intermediate_state_idx },
165 { C::scalar_mul_temp_x, temp.
x() },
166 { C::scalar_mul_temp_y, temp.
y() },
169 C::scalar_mul_should_add,
172 { C::scalar_mul_bit_radix, 2 } } });
185 for (
const auto&
event : events) {
186 uint64_t
dst_addr =
static_cast<uint64_t
>(
event.dst_address);
193 bool p_is_on_curve =
event.p.on_curve();
194 FF p_is_on_curve_eqn = compute_curve_eqn_diff(
event.p);
195 FF p_is_on_curve_eqn_inv = p_is_on_curve ?
FF::zero() : p_is_on_curve_eqn.invert();
197 bool q_is_on_curve =
event.q.on_curve();
198 FF q_is_on_curve_eqn = compute_curve_eqn_diff(
event.q);
199 FF q_is_on_curve_eqn_inv = q_is_on_curve ?
FF::zero() : q_is_on_curve_eqn.invert();
201 bool error = dst_out_of_range_err || !p_is_on_curve || !q_is_on_curve;
205 { C::ecc_add_mem_sel, 1 },
206 { C::ecc_add_mem_execution_clk,
event.execution_clk },
207 { C::ecc_add_mem_space_id,
event.space_id },
210 { C::ecc_add_mem_sel_dst_out_of_range_err, dst_out_of_range_err ? 1 : 0 },
212 { C::ecc_add_mem_sel_p_not_on_curve_err, !p_is_on_curve ? 1 : 0 },
213 { C::ecc_add_mem_p_is_on_curve_eqn, p_is_on_curve_eqn },
214 { C::ecc_add_mem_p_is_on_curve_eqn_inv, p_is_on_curve_eqn_inv },
216 { C::ecc_add_mem_sel_q_not_on_curve_err, !q_is_on_curve ? 1 : 0 },
217 { C::ecc_add_mem_q_is_on_curve_eqn, q_is_on_curve_eqn },
218 { C::ecc_add_mem_q_is_on_curve_eqn_inv, q_is_on_curve_eqn_inv },
220 { C::ecc_add_mem_err, error ? 1 : 0 },
222 { C::ecc_add_mem_dst_addr_0_,
dst_addr },
223 { C::ecc_add_mem_dst_addr_1_,
dst_addr + 1 },
224 { C::ecc_add_mem_dst_addr_2_,
dst_addr + 2 },
226 { C::ecc_add_mem_p_x,
event.p.x() },
227 { C::ecc_add_mem_p_y,
event.p.y() },
228 { C::ecc_add_mem_p_is_inf,
event.p.is_infinity() ? 1 : 0 },
230 { C::ecc_add_mem_q_x,
event.q.x() },
231 { C::ecc_add_mem_q_y,
event.q.y() },
232 { C::ecc_add_mem_q_is_inf,
event.q.is_infinity() ? 1 : 0 },
234 { C::ecc_add_mem_sel_should_exec, error ? 0 : 1 },
235 { C::ecc_add_mem_res_x,
event.result.x() },
236 { C::ecc_add_mem_res_y,
event.result.y() },
237 { C::ecc_add_mem_res_is_inf,
event.result.is_infinity() },