@@ -24,50 +24,38 @@ include "precomputed.pil";
2424 * #[DISPATCH_TO_ECC_ADD]
2525 * sel_exec_dispatch_ecc_add {
2626 * clk, context_id,
27- * register[0], register[1], register[2], // Point P
28- * register[3 ], register[4], register[5 ], // Point Q
29- * rop[6 ], // Dst address
27+ * register[0], register[1], // Point P
28+ * register[2 ], register[3 ], // Point Q
29+ * rop[4 ], // Dst address
3030 * sel_opcode_error // Error
3131 * } is ecc_add_mem.sel {
3232 * ecc_add_mem.execution_clk, ecc_add_mem.space_id,
33- * ecc_add_mem.p_x, ecc_add_mem.p_y, ecc_add_mem.p_is_inf, // Point P
34- * ecc_add_mem.q_x, ecc_add_mem.q_y, ecc_add_mem.q_is_inf, // Point Q
33+ * ecc_add_mem.p_x, ecc_add_mem.p_y, // Point P
34+ * ecc_add_mem.q_x, ecc_add_mem.q_y, // Point Q
3535 * ecc_add_mem.dst_addr[0], // Dst address
3636 * ecc_add_mem.err // Error
3737 * };
3838 *
3939 * Opcode operands (relevant in EXECUTION when interacting with this gadget):
4040 * - rop[0]: p_x_addr
4141 * - rop[1]: p_y_addr
42- * - rop[2]: p_is_inf_addr (ignored)
43- * - rop[3]: q_x_addr
44- * - rop[4]: q_y_addr
45- * - rop[5]: q_is_inf_addr (ignored)
46- * - rop[6]: dst_addr
47- *
48- * Note: The values at p_is_inf_addr, q_is_inf_addr are ignored by this circuit and will be removed
49- * in TODO(#AVM-266). We instead derive whether the point is infinity by checking its coordinates
50- * for our standard representation of (0, 0). See below for details on infinity points.
42+ * - rop[2]: q_x_addr
43+ * - rop[3]: q_y_addr
44+ * - rop[4]: dst_addr
5145 *
5246 * Memory I/O:
5347 * - register[0]: M[p_x_addr] aka p_x (x coordinate of point P - read from memory by EXECUTION)
5448 * - p_x is tagged-checked by execution/registers to be FF based on instruction spec.
5549 * - register[1]: M[p_y_addr] aka p_y (y coordinate of point P - read from memory by EXECUTION)
5650 * - p_y is tagged-checked by execution/registers to be FF based on instruction spec.
57- * - register[2]: M[p_is_inf_addr] aka p_is_inf (boolean flag if P is the point at infinity - read from memory by EXECUTION)
58- * - Note: ignored by this circuit and will be removed in TODO(#AVM-266).
59- * - register[3]: M[q_x_addr] aka q_x (x coordinate of point Q - read from memory by EXECUTION)
51+ * - register[2]: M[q_x_addr] aka q_x (x coordinate of point Q - read from memory by EXECUTION)
6052 * - q_x is tagged-checked by execution/registers to be FF based on instruction spec.
61- * - register[4 ]: M[q_y_addr] aka q_y (y coordinate of point Q - read from memory by EXECUTION)
53+ * - register[3 ]: M[q_y_addr] aka q_y (y coordinate of point Q - read from memory by EXECUTION)
6254 * - q_y is tagged-checked by execution/registers to be FF based on instruction spec.
63- * - register[5]: M[q_is_inf_addr] aka q_is_inf (boolean flag if Q is the point at infinity - read from memory by EXECUTION)
64- * - Note: ignored by this circuit and will be removed in TODO(#AVM-266).
65- * - M[rop[6]]: M[dst_addr] aka res_x (x coordinate of the resulting point RES - written by this gadget)
55+ * - M[rop[4]]: M[dst_addr] aka res_x (x coordinate of the resulting point RES - written by this gadget)
6656 * - guaranteed by this gadget to be FF.
67- * - M[rop[6 ]+1]: M[dst_offset+1] aka res_y (y coordinate of the resulting point RES - written by this gadget)
57+ * - M[rop[4 ]+1]: M[dst_offset+1] aka res_y (y coordinate of the resulting point RES - written by this gadget)
6858 * - guaranteed by this gadget to be FF.
69- * - M[rop[6]+2]: M[dst_offset+2] aka res_is_inf (boolean flag if RES is the point at infinity - written by this gadget)
70- * - guaranteed by this gadget to be U1.
7159 *
7260 * ERROR HANDLING:
7361 * Two errors need to be handled as part of this trace,
@@ -84,11 +72,11 @@ include "precomputed.pil";
8472 * --> gt.pil
8573 * This subtrace is looked up by:
8674 * - execution.pil: To constrain the dispatch permutation for the ECADD opcode (#[DISPATCH_TO_ECC_ADD]). Includes memory
87- * reads (register[0] to register[5 ]), the initial write address (rop[6 ]), and error flag (sel_opcode_error).
75+ * reads (register[0] to register[3 ]), the initial write address (rop[4 ]), and error flag (sel_opcode_error).
8876 *
8977 * This subtrace looks up:
90- * - memory.pil: To write the output point values (res_x, res_y, res_is_inf ) to memory with standard write permutations
91- * (#[WRITE_MEM_i] for i = 0, 1, 2 ).
78+ * - memory.pil: To write the output point values (res_x, res_y) to memory with standard write permutations
79+ * (#[WRITE_MEM_i] for i = 0, 1).
9280 * - ecc.pil: To retrieve the output point R as the result of adding the points P and Q read from memory
9381 * (#[INPUT_OUTPUT_ECC_ADD]). See below for details on infinity points.
9482 * - gt.pil: To constrain that the maximum written memory address is within range (#[CHECK_DST_ADDR_IN_RANGE]).
@@ -103,9 +91,7 @@ include "precomputed.pil";
10391 * For now, we simply ignore any is_inf flags coming from memory (assigning and not reading the placeholder is_inf_), but
10492 * will eventually remove it from the operands TODO(#AVM-266).
10593 *
106- * TODO(MW): Is ignoring i.e. leaving a memory operand unconstrained safe? Execution still reads them but will remove
107- * p/q_is_inf_ if so.
108- *
94+ * MW NOTE: Still using p_is_inf, q_is_inf just as flags to tell ecc.pil how to treat the points.
10995 * Until #AVM-266, the ECC subtrace still requires a correctly constrained is_inf flag for each point. We derive it within
11096 * this circuit by enforcing (0, 0) <==> is_inf for input points P and Q:
11197 * - (0, 0) ==> is_inf by #[P/Q_ON_CURVE_CHECK] (zero coordinates will fail this relation unless is_inf is set correctly).
@@ -123,17 +109,16 @@ namespace ecc_add_mem;
123109
124110 pol commit execution_clk;
125111 pol commit space_id;
126- pol commit dst_addr[3 ];
112+ pol commit dst_addr[2 ];
127113
128114 // dst_addr[0] constrained by the permutation to execution
129115 #[WRITE_INCR_DST_ADDR]
130116 dst_addr[1] = sel * (dst_addr[0] + 1);
131- dst_addr[2] = sel * (dst_addr[0] + 2);
132117
133- // TODO(#AVM-266): Remove p_is_inf_, q_is_inf_ (currently placeholders for #[DISPATCH_TO_ECC_ADD]).
134- pol commit p_x, p_y, p_is_inf_;
135- pol commit q_x, q_y, q_is_inf_;
118+ pol commit p_x, p_y;
119+ pol commit q_x, q_y;
136120
121+ // MW NOTE: Still using p_is_inf, q_is_inf just as flags to tell ecc.pil how to treat the points.
137122 // TODO(#AVM-266): Remove p_is_inf, q_is_inf entirely.
138123 // Needs to be committed columns as they are used in the lookups
139124 pol commit p_is_inf, q_is_inf; // constrained to be @boolean in the ecc subtrace (see #[INPUT_OUTPUT_ECC_ADD])
@@ -145,15 +130,15 @@ namespace ecc_add_mem;
145130
146131 // Use the comparison gadget to check that the max addresses are within range
147132 // The comparison gadget provides the ability to test GreaterThan so we check
148- // dst_addr[2 ] > max_mem_addr
133+ // dst_addr[1 ] > max_mem_addr
149134 pol commit max_mem_addr; // Column needed until we support constants in lookups
150135 sel * (max_mem_addr - constants.AVM_HIGHEST_MEM_ADDRESS) = 0;
151136
152137 // Preconditions to `gt` gadget require both inputs to be bounded by 2^128.
153- // `dst_addr[2 ]` = dst_addr[0] + 2 where dst_addr[0] is an address (< 2^32), so dst_addr[2 ] < 2^33.
138+ // `dst_addr[1 ]` = dst_addr[0] + 1 where dst_addr[0] is an address (< 2^32), so dst_addr[1 ] < 2^33.
154139 // `max_mem_addr` = AVM_HIGHEST_MEM_ADDRESS which is < 2^32.
155140 #[CHECK_DST_ADDR_IN_RANGE]
156- sel { dst_addr[2 ], max_mem_addr, sel_dst_out_of_range_err }
141+ sel { dst_addr[1 ], max_mem_addr, sel_dst_out_of_range_err }
157142 in
158143 gt.sel_others { gt.input_a, gt.input_b, gt.res };
159144
@@ -196,10 +181,14 @@ namespace ecc_add_mem;
196181 ///////////////////////////////////////////////////////////////////////
197182 // Dispatch inputs to ecc add and retrieve outputs
198183 ///////////////////////////////////////////////////////////////////////
199- pol commit res_x, res_y, res_is_inf; // res_is_inf is constrained to be @boolean in the ecc subtrace (see #[INPUT_OUTPUT_ECC_ADD])
184+ pol commit res_x, res_y;
200185 pol commit sel_should_exec; // @boolean (by definition)
201186 sel_should_exec = sel * (1 - err);
202187
188+ // MW NOTE: Still using p_is_inf, q_is_inf just as flags to tell ecc.pil how to treat the points.
189+ // MW NOTE: Output inifinities - in ecc.pil, if result_infinity, then r_x = INFINITY_X = 0, r_y = INFINITY_Y = 0.
190+ // Sufficient to just lookup res_x, res_y here?
191+
203192 // TODO(#AVM-266): Remove p_is_inf, q_is_inf entirely. For now, we ensure that the flag being set means that the coordinates
204193 // are set to our infinity representation: (INFINITY_X, INFINITY_Y) = (0, 0). The reverse ((INFINITY_X, INFINITY_Y) ==> is_inf)
205194 // is constrained by #[P/Q_ON_CURVE_CHECK]. Output infinities are already constrained to be (0, 0) in the subtrace.
@@ -217,12 +206,12 @@ namespace ecc_add_mem;
217206 sel_should_exec {
218207 p_x, p_y, p_is_inf,
219208 q_x, q_y, q_is_inf,
220- res_x, res_y, res_is_inf
209+ res_x, res_y
221210 } in
222211 ecc.sel {
223212 ecc.p_x, ecc.p_y, ecc.p_is_inf,
224213 ecc.q_x, ecc.q_y, ecc.q_is_inf,
225- ecc.r_x, ecc.r_y, ecc.r_is_inf
214+ ecc.r_x, ecc.r_y
226215 };
227216
228217 ////////////////////////////////////////////////
@@ -244,11 +233,11 @@ namespace ecc_add_mem;
244233 memory.clk, memory.space_id, memory.address, memory.value, memory.tag, memory.rw
245234 };
246235
247- #[WRITE_MEM_2]
248- sel_should_exec {
249- execution_clk, space_id, dst_addr[2], res_is_inf, /*U1_mem_tag=1*/ sel_should_exec, /*rw=1*/ sel_should_exec
250- } is
251- memory.sel_ecc_write[2] {
252- memory.clk, memory.space_id, memory.address, memory.value, memory.tag, memory.rw
253- };
236+ // #[WRITE_MEM_2]
237+ // sel_should_exec {
238+ // execution_clk, space_id, dst_addr[2], res_is_inf, /*U1_mem_tag=1*/ sel_should_exec, /*rw=1*/ sel_should_exec
239+ // } is
240+ // memory.sel_ecc_write[2] {
241+ // memory.clk, memory.space_id, memory.address, memory.value, memory.tag, memory.rw
242+ // };
254243
0 commit comments