Skip to content

Commit dfaf685

Browse files
authored
feat(avm)!: Remove is_infinite flag from AVM (PIL and EC points only) (#22795)
This branch includes the changes to remove the `is_infinite` flag from our point representation and conceptually treating a point as infinite iff its coordinates are `(0, 0)`. It only contains logic changes within the AVM for the above and does not touch the opcode - this is in a lower PR - so the **CI will probably fail**. Will close [Foundation AVM Issue 18](https://linear.app/aztec-foundation/issue/AVM-18/remove-is-inf-flag-from-resulting-ec-points-in-avm-circuits) --- Stack: - #22745 - #22564 - #22921 - `mw/avm-explore-remove-is-inf` <-- here - #22945 - #23031
1 parent 4cd7f3d commit dfaf685

25 files changed

Lines changed: 275 additions & 415 deletions

barretenberg/cpp/pil/vm2/bytecode/address_derivation.pil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,11 +311,11 @@ namespace address_derivation;
311311
sel {
312312
preaddress_public_key_x, preaddress_public_key_y, precomputed.zero,
313313
incoming_viewing_key_x, incoming_viewing_key_y, precomputed.zero,
314-
address, address_y, precomputed.zero
314+
address, address_y
315315
} in ecc.sel {
316316
ecc.p_x, ecc.p_y, ecc.p_is_inf,
317317
ecc.q_x, ecc.q_y, ecc.q_is_inf,
318-
ecc.r_x, ecc.r_y, ecc.r_is_inf
318+
ecc.r_x, ecc.r_y
319319
};
320320

321321
// Note: We can safely assume the address point is not infinity since that would imply either

barretenberg/cpp/pil/vm2/ecc.pil

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,32 @@
22
/**
33
* This subtrace supports point addition over the Grumpkin curve.
44
* Given two points, P & Q, this trace computes R = P + Q.
5-
* PRECONDITIONS: The only assumption here is that the inputs P & Q are points on the Grumpkin curve (note that the Point at Infinity = (0, 0) is considered on the curve):
6-
* Grumpkin Curve Eqn in SW form: Y^2 = X^3 − 17.
5+
* PRECONDITIONS: This trace assumes that the inputs P & Q are points on the Grumpkin curve and infinity points are correctly
6+
* flagged with p_is_inf and/or q_is_inf (note that the Point at Infinity = (0, 0) is considered on the curve):
7+
* Grumpkin Curve Eqn in SW form: Y^2 = X^3 − 17.
78
* Note: Grumpkin forms a 2-cycle with BN254, i.e the base field of one is the scalar field of the other and vice-versa.
89
*
9-
* Note that once TODO(#AVM-266) is complete, is_inf will no longer be part of our point representation and we must either:
10-
* - continue to rely on the 'calling' trace to inject a constrained is_inf, or
11-
* - derive is_inf (<==> (X, Y) == (INFINITY_X, INFINITY_Y)) within this trace.
12-
*
1310
* USAGE: This is a non-memory aware subtrace used to constrain point addition as defined above. Each point can be looked up
1411
* by coordinates (lookup as defined in ecc_mem.pil):
1512
* #[INPUT_OUTPUT_ECC_ADD]
1613
* sel_should_exec {
17-
* p_x_n, p_y_n, p_is_inf, // Point P
18-
* q_x_n, q_y_n, q_is_inf, // Point Q
19-
* res_x, res_y, res_is_inf // Point R
14+
* p_x_n, p_y_n, // Point P
15+
* p_is_inf, // P == O
16+
* q_x_n, q_y_n, // Point Q
17+
* q_is_inf, // Q == O
18+
* res_x, res_y // Point R
2019
* } in ecc.sel {
21-
* ecc.p_x, ecc.p_y, ecc.p_is_inf, // Point P
22-
* ecc.q_x, ecc.q_y, ecc.q_is_inf, // Point Q
23-
* ecc.r_x, ecc.r_y, ecc.r_is_inf // Point R
20+
* ecc.p_x, ecc.p_y, // Point P
21+
* ecc.p_is_inf, // P == O
22+
* ecc.q_x, ecc.q_y,, // Point Q
23+
* ecc.q_is_inf, // Q == O
24+
* ecc.r_x, ecc.r_y // Point R
2425
* };
2526
*
27+
* NOTE: For now, the calling trace MUST constrain that p_is_inf, q_is_inf above are correct. This is so if we have a calling
28+
* trace in which we know inf would never be an input we can simply use precomputed.zero and avoid wasting gates on deriving is_inf.
29+
* This follows the same logic for points being on the curve.
30+
*
2631
* TRACE SHAPE: 1 single row per computation (P + Q = R).
2732
*
2833
* INTERACTIONS: This subtrace is looked up by:
@@ -41,11 +46,11 @@ namespace ecc;
4146
// We perform point addition over our Short Weierstrass (SW) curve with 3 cases outlined in the last section ('Assign Result').
4247
// The notation will be as follows:
4348
// P + Q = R where:
44-
// P = (p_x, p_y, p_is_inf), Q = (q_x, q_y, q_is_inf), R = (r_x, r_y, r_is_inf),
49+
// P = (p_x, p_y), Q = (q_x, q_y), R = (r_x, r_y),
4550
// where the coordinates satisfy:
4651
// y^2 = x^3 - 17 (unless is_inf is true).
4752
// The point at infinity, O, does not have valid coordinates (a property of SW curves). We represent it as:
48-
// O = (0, 0, true).
53+
// O = (0, 0).
4954
// Note: this is NOT enforced here for inputs, see ecc_mem.pil for example of constraining.
5055
//
5156

@@ -74,20 +79,20 @@ namespace ecc;
7479
// Point P in affine form
7580
pol commit p_x;
7681
pol commit p_y;
82+
// Must be constrained by the calling trace:
7783
pol commit p_is_inf; // @boolean
7884
p_is_inf * (1 - p_is_inf) = 0;
7985

8086
// Point Q in affine form
8187
pol commit q_x;
8288
pol commit q_y;
89+
// Must be constrained by the calling trace:
8390
pol commit q_is_inf; // @boolean
8491
q_is_inf * (1 - q_is_inf) = 0;
8592

8693
// Resulting Point R in affine form
8794
pol commit r_x;
8895
pol commit r_y;
89-
pol commit r_is_inf; // @boolean
90-
r_is_inf * (1 - r_is_inf) = 0;
9196

9297
// Check x coordinates, i.e. p_x == q_x
9398
pol commit x_match; // @boolean
@@ -151,9 +156,9 @@ namespace ecc;
151156
// If P != Q where x_match, this implies p_y == -q_y <==> P == -Q (INVERSE_PRED == true):
152157
// R := O
153158
// If P == O:
154-
// R := Q (r_x := q_x, r_y := q_y, r_is_inf = q_is_inf)
159+
// R := Q (r_x := q_x, r_y := q_y)
155160
// Vice versa, if Q == O:
156-
// R := P (r_x := p_x, r_y := p_y, r_is_inf = p_is_inf)
161+
// R := P (r_x := p_x, r_y := p_y)
157162
//
158163

159164
pol INVERSE_PRED = x_match * (1 - y_match);
@@ -186,6 +191,4 @@ namespace ecc;
186191
sel * (r_x - (EITHER_INF * (p_is_inf * q_x + q_is_inf * p_x)) - result_infinity * INFINITY_X - use_computed_result * COMPUTED_R_X) = 0;
187192
#[OUTPUT_Y_COORD]
188193
sel * (r_y - (EITHER_INF * (p_is_inf * q_y + q_is_inf * p_y)) - result_infinity * INFINITY_Y - use_computed_result * COMPUTED_R_Y) = 0;
189-
#[OUTPUT_INF_FLAG]
190-
sel * (r_is_inf - result_infinity) = 0;
191194

barretenberg/cpp/pil/vm2/ecc_mem.pil

Lines changed: 32 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -9,65 +9,52 @@ include "precomputed.pil";
99
* Given two points, P & Q, this trace constrains that both exist on the Grumpkin curve
1010
* and the claimed result point, R = P + Q, is written to memory addresses within range.
1111
* A point exists on the curve if it satisfies the curve equation (SW form: Y^2 = X^3 − 17)
12-
* or is the point at infinity, represented by (X, Y) = (0, 0).
12+
* or is the point at infinity, represented by (X, Y) = (INFINITY_X, INFINITY_Y) = (0, 0).
1313
* The reads of P and Q are handled by the registers in the execution trace. The correctness
1414
* of point addition is handled by the ECC subtrace.
1515
*
1616
* This trace writes the resulting embedded curve point to the addresses {dst,
17-
* dst + 1, and dst + 2 }. Embedded curve points consist of the tuple of types
18-
* {x: FF, y: FF, is_inf: U1 }.
17+
* dst + 1 }. Embedded curve points consist of the tuple of types {x: FF, y: FF }.
1918
*
20-
* PRECONDITIONS: Input point coordinates have tag checked FF coordinates and U1 is_inf
21-
* flag (see Memory I/O below for details).
19+
* PRECONDITIONS: Input point coordinates have tag checked FF coordinates (see Memory I/O
20+
* below for details).
2221
*
2322
* USAGE: Dispatching lookup defined in execution.pil:
2423
* #[DISPATCH_TO_ECC_ADD]
2524
* sel_exec_dispatch_ecc_add {
2625
* 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
26+
* register[0], register[1], // Point P
27+
* register[2], register[3], // Point Q
28+
* rop[4], // Dst address
3029
* sel_opcode_error // Error
3130
* } is ecc_add_mem.sel {
3231
* 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
32+
* ecc_add_mem.p_x, ecc_add_mem.p_y, // Point P
33+
* ecc_add_mem.q_x, ecc_add_mem.q_y, // Point Q
3534
* ecc_add_mem.dst_addr[0], // Dst address
3635
* ecc_add_mem.err // Error
3736
* };
3837
*
3938
* Opcode operands (relevant in EXECUTION when interacting with this gadget):
4039
* - rop[0]: p_x_addr
4140
* - 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.
41+
* - rop[2]: q_x_addr
42+
* - rop[3]: q_y_addr
43+
* - rop[4]: dst_addr
5144
*
5245
* Memory I/O:
5346
* - register[0]: M[p_x_addr] aka p_x (x coordinate of point P - read from memory by EXECUTION)
5447
* - p_x is tagged-checked by execution/registers to be FF based on instruction spec.
5548
* - register[1]: M[p_y_addr] aka p_y (y coordinate of point P - read from memory by EXECUTION)
5649
* - 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)
50+
* - register[2]: M[q_x_addr] aka q_x (x coordinate of point Q - read from memory by EXECUTION)
6051
* - 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)
52+
* - register[3]: M[q_y_addr] aka q_y (y coordinate of point Q - read from memory by EXECUTION)
6253
* - 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)
54+
* - M[rop[4]]: M[dst_addr] aka res_x (x coordinate of the resulting point RES - written by this gadget)
6655
* - 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)
56+
* - M[rop[4]+1]: M[dst_offset+1] aka res_y (y coordinate of the resulting point RES - written by this gadget)
6857
* - 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.
7158
*
7259
* ERROR HANDLING:
7360
* Two errors need to be handled as part of this trace,
@@ -84,30 +71,24 @@ include "precomputed.pil";
8471
* --> gt.pil
8572
* This subtrace is looked up by:
8673
* - 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).
74+
* reads (register[0] to register[3]), the initial write address (rop[4]), and error flag (sel_opcode_error).
8875
*
8976
* 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).
77+
* - memory.pil: To write the output point values (res_x, res_y) to memory with standard write permutations
78+
* (#[WRITE_MEM_i] for i = 0, 1).
9279
* - ecc.pil: To retrieve the output point R as the result of adding the points P and Q read from memory
9380
* (#[INPUT_OUTPUT_ECC_ADD]). See below for details on infinity points.
9481
* - gt.pil: To constrain that the maximum written memory address is within range (#[CHECK_DST_ADDR_IN_RANGE]).
9582
*
9683
* This subtrace is connected to the ECC subtrace via a lookup. ECC is used by other subtraces internally
9784
* (e.g. address derivation). Now that the is_inf flag has been removed from noir (noir-lang/noir/#11926/) we consider
98-
* a point to be infinity iff its coordinates are (0, 0); the noir standard representation.
85+
* a point to be infinity iff its coordinates are (0, 0); the noir standard representation (see relations #[P/Q_INF_X/Y_CHECK]).
9986
*
10087
* Note that the point at infinity, O, does not have valid coordinates (a property of SW curves like Grumpkin). We represent it
10188
* as (0, 0) but any (ecc.INFINITY_X, ecc.INFINITY_Y) not satisfying the curve equation will be correctly handled in this trace.
10289
*
103-
* For now, we simply ignore any is_inf flags coming from memory (assigning and not reading the placeholder is_inf_), but
104-
* will eventually remove it from the operands TODO(#AVM-266).
105-
*
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-
*
109-
* Until #AVM-266, the ECC subtrace still requires a correctly constrained is_inf flag for each point. We derive it within
110-
* this circuit by enforcing (0, 0) <==> is_inf for input points P and Q:
90+
* The ECC subtrace requires a correctly constrained is_inf flag for each point. We derive it within this circuit by enforcing
91+
* (0, 0) <==> is_inf for input points P and Q:
11192
* - (0, 0) ==> is_inf by #[P/Q_ON_CURVE_CHECK] (zero coordinates will fail this relation unless is_inf is set correctly).
11293
* - is_inf ==> (0, 0) by #[P/Q_INF_X/Y_CHECK].
11394
* Resulting infinity points are guaranteed to be (0, 0) by the ECC subtrace (see #[OUTPUT_X_COORD] and #[OUTPUT_Y_COORD]).
@@ -123,18 +104,15 @@ namespace ecc_add_mem;
123104

124105
pol commit execution_clk;
125106
pol commit space_id;
126-
pol commit dst_addr[3];
107+
pol commit dst_addr[2];
127108

128109
// dst_addr[0] constrained by the permutation to execution
129110
#[WRITE_INCR_DST_ADDR]
130111
dst_addr[1] = sel * (dst_addr[0] + 1);
131-
dst_addr[2] = sel * (dst_addr[0] + 2);
132112

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_;
113+
pol commit p_x, p_y;
114+
pol commit q_x, q_y;
136115

137-
// TODO(#AVM-266): Remove p_is_inf, q_is_inf entirely.
138116
// Needs to be committed columns as they are used in the lookups
139117
pol commit p_is_inf, q_is_inf; // constrained to be @boolean in the ecc subtrace (see #[INPUT_OUTPUT_ECC_ADD])
140118

@@ -145,15 +123,15 @@ namespace ecc_add_mem;
145123

146124
// Use the comparison gadget to check that the max addresses are within range
147125
// The comparison gadget provides the ability to test GreaterThan so we check
148-
// dst_addr[2] > max_mem_addr
126+
// dst_addr[1] > max_mem_addr
149127
pol commit max_mem_addr; // Column needed until we support constants in lookups
150128
sel * (max_mem_addr - constants.AVM_HIGHEST_MEM_ADDRESS) = 0;
151129

152130
// 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.
131+
// `dst_addr[1]` = dst_addr[0] + 1 where dst_addr[0] is an address (< 2^32), so dst_addr[1] < 2^33.
154132
// `max_mem_addr` = AVM_HIGHEST_MEM_ADDRESS which is < 2^32.
155133
#[CHECK_DST_ADDR_IN_RANGE]
156-
sel { dst_addr[2], max_mem_addr, sel_dst_out_of_range_err }
134+
sel { dst_addr[1], max_mem_addr, sel_dst_out_of_range_err }
157135
in
158136
gt.sel_others { gt.input_a, gt.input_b, gt.res };
159137

@@ -196,13 +174,11 @@ namespace ecc_add_mem;
196174
///////////////////////////////////////////////////////////////////////
197175
// Dispatch inputs to ecc add and retrieve outputs
198176
///////////////////////////////////////////////////////////////////////
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])
177+
pol commit res_x, res_y;
200178
pol commit sel_should_exec; // @boolean (by definition)
201179
sel_should_exec = sel * (1 - err);
202180

203-
// TODO(#AVM-266): Remove p_is_inf, q_is_inf entirely. For now, we ensure that the flag being set means that the coordinates
204-
// are set to our infinity representation: (INFINITY_X, INFINITY_Y) = (0, 0). The reverse ((INFINITY_X, INFINITY_Y) ==> is_inf)
205-
// is constrained by #[P/Q_ON_CURVE_CHECK]. Output infinities are already constrained to be (0, 0) in the subtrace.
181+
// Constrains that the infinity flags required for the ecc trace have been set correctly:
206182
#[P_INF_X_CHECK]
207183
sel * p_is_inf * (p_x - ecc.INFINITY_X) = 0;
208184
#[P_INF_Y_CHECK]
@@ -217,12 +193,12 @@ namespace ecc_add_mem;
217193
sel_should_exec {
218194
p_x, p_y, p_is_inf,
219195
q_x, q_y, q_is_inf,
220-
res_x, res_y, res_is_inf
196+
res_x, res_y
221197
} in
222198
ecc.sel {
223199
ecc.p_x, ecc.p_y, ecc.p_is_inf,
224200
ecc.q_x, ecc.q_y, ecc.q_is_inf,
225-
ecc.r_x, ecc.r_y, ecc.r_is_inf
201+
ecc.r_x, ecc.r_y
226202
};
227203

228204
////////////////////////////////////////////////
@@ -243,12 +219,3 @@ namespace ecc_add_mem;
243219
memory.sel_ecc_write[1] {
244220
memory.clk, memory.space_id, memory.address, memory.value, memory.tag, memory.rw
245221
};
246-
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-
};
254-

barretenberg/cpp/pil/vm2/execution.pil

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,11 +1277,10 @@ sel_exec_dispatch_keccakf1600 {
12771277
};
12781278

12791279
// ECADD DISPATCHING
1280-
// Each input point uses 3 registers:
1281-
// P = [x, y, is_inf] -> register[0..2], Q = [x, y, is_inf] -> register[3..5]
1282-
// TODO(#AVM-266): Remove is_inf and use 2 registers per point (for now, the 3rd register is read but ignored).
1280+
// Each input point uses 2 registers:
1281+
// P = [x, y] -> register[0..1], Q = [x, y] -> register[2..3]
12831282
// The output point is written to memory internally inside the ecc_add_mem (ecc_mem.pil) trace, starting at:
1284-
// dst_addr[0] -> rop[6]
1283+
// dst_addr[0] -> rop[4]
12851284
// Outputs (#[WRITE_MEM_x]) and memory write checks (#[CHECK_DST_ADDR_IN_RANGE]) are hence handled by the trace.
12861285

12871286
#[DISPATCH_TO_ECC_ADD]
@@ -1291,13 +1290,11 @@ sel_exec_dispatch_ecc_add {
12911290
// Point P
12921291
register[0],
12931292
register[1],
1294-
register[2],
12951293
// Point Q
1294+
register[2],
12961295
register[3],
1297-
register[4],
1298-
register[5],
12991296
// Dst address
1300-
rop[6],
1297+
rop[4],
13011298
// Error
13021299
sel_opcode_error
13031300
} is ecc_add_mem.sel {
@@ -1306,11 +1303,9 @@ sel_exec_dispatch_ecc_add {
13061303
// Point P
13071304
ecc_add_mem.p_x,
13081305
ecc_add_mem.p_y,
1309-
ecc_add_mem.p_is_inf_,
13101306
// Point Q
13111307
ecc_add_mem.q_x,
13121308
ecc_add_mem.q_y,
1313-
ecc_add_mem.q_is_inf_,
13141309
// Dst address
13151310
ecc_add_mem.dst_addr[0],
13161311
// Error

barretenberg/cpp/pil/vm2/memory.pil

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,9 @@ sel_sha256_op[6] * (1 - sel_sha256_op[6]) = 0;
175175
sel_sha256_op[7] * (1 - sel_sha256_op[7]) = 0;
176176

177177
// Permutation selectors (ecc_mem.pil).
178-
pol commit sel_ecc_write[3]; // @boolean
178+
pol commit sel_ecc_write[2]; // @boolean
179179
sel_ecc_write[0] * (1 - sel_ecc_write[0]) = 0;
180180
sel_ecc_write[1] * (1 - sel_ecc_write[1]) = 0;
181-
sel_ecc_write[2] * (1 - sel_ecc_write[2]) = 0;
182181

183182
// Permutation selectors (to_radix_mem.pil).
184183
pol commit sel_to_radix_write; // @boolean
@@ -212,7 +211,7 @@ sel = // Addressing.
212211
+ sel_sha256_op[0] + sel_sha256_op[1] + sel_sha256_op[2] + sel_sha256_op[3]
213212
+ sel_sha256_op[4] + sel_sha256_op[5] + sel_sha256_op[6] + sel_sha256_op[7]
214213
// ECC.
215-
+ sel_ecc_write[0] + sel_ecc_write[1] + sel_ecc_write[2]
214+
+ sel_ecc_write[0] + sel_ecc_write[1]
216215
// To Radix.
217216
+ sel_to_radix_write;
218217

0 commit comments

Comments
 (0)