Skip to content

Commit 8f3f2d6

Browse files
committed
feat: derive inf from coordinates in sim/tracegen
1 parent 1d85eb3 commit 8f3f2d6

4 files changed

Lines changed: 29 additions & 29 deletions

File tree

barretenberg/cpp/src/barretenberg/vm2/constraining/relations/ecc.test.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1382,7 +1382,11 @@ TEST(EccAddMemoryConstrainingTest, InfinityRepresentations)
13821382
EXPECT_THROW_WITH_MESSAGE(ecc_simulator.add(inf, inf_alt), "normalized");
13831383

13841384
// The circuit correctly assigns double_op = true when doubling inf:
1385-
ecc_simulator.add(memory, inf, inf_bb, dst_address);
1385+
ecc_simulator.add(memory, inf, inf, dst_address);
1386+
1387+
// TODO(#AVM-266): As part of Noir's removal of is_infinite (#AVM-248) we assume any input infinities
1388+
// follow (0, 0) <==> is_inf.
1389+
EXPECT_THROW_WITH_MESSAGE(ecc_simulator.add(inf, inf_bb), "normalized");
13861390

13871391
builder.process_add(ecc_add_event_emitter.dump_events(), trace);
13881392
check_relation<ecc>(trace);

barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/ecc.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,21 +136,15 @@ void Ecc::add(MemoryInterface& memory,
136136
throw InternalEccException("dst address out of range");
137137
}
138138

139+
// TODO(#AVM-266): Note: bb infinity points (is_inf=true with x=(P+1)/2, y=0) pass on_curve() without
140+
// throwing here, but would throw in the circuit. We assume here input points follow the Noir convention
141+
// of (x=0, y=0) <==> is_infinity.
139142
if (!p.on_curve() || !q.on_curve()) {
140-
// TODO(#AVM-266): Note: We now use this to enforce (X, Y) == (0, 0) ==> is_inf
141-
// until is_inf is removed. This means a bb inf point (!= (0, 0)) will
142-
// not throw here but would throw in the circuit. Since we remap such points to
143-
// (0, 0) below, it shouldn't reach the circuit at all.
144143
throw InternalEccException("One of the points is not on the curve");
145144
}
146145

147-
// Normalize input infinity points.
148-
EmbeddedCurvePoint p_input = p.is_infinity() ? EmbeddedCurvePoint::infinity() : p;
149-
EmbeddedCurvePoint q_input = q.is_infinity() ? EmbeddedCurvePoint::infinity() : q;
150-
151146
// Emits EccAddEvent, see #[INPUT_OUTPUT_ECC_ADD] in ecc_mem.pil.
152-
EmbeddedCurvePoint result =
153-
add(p_input, q_input); // Cannot throw since we have checked on_curve() and normalized.
147+
EmbeddedCurvePoint result = add(p, q); // Cannot throw since we have checked on_curve().
154148

155149
// Emits MemoryEvents, see #[WRITE_MEM_i] for i = 0, 1, 2, in ecc_mem.pil.
156150
memory.set(dst_address, MemoryValue::from<FF>(result.x()));

barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/execution.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,19 +1504,26 @@ void Execution::ecc_add(ContextInterface& context,
15041504
// Read the points from memory.
15051505
const auto& p_x = memory.get(p_x_addr);
15061506
const auto& p_y = memory.get(p_y_addr);
1507+
// TODO(#AVM-266): Remove infinity flags from point representation, the below is currently ignored in-circuit.
15071508
const auto& p_inf = memory.get(p_inf_addr);
15081509

15091510
const auto& q_x = memory.get(q_x_addr);
15101511
const auto& q_y = memory.get(q_y_addr);
1512+
// TODO(#AVM-266): Remove infinity flags from point representation, the below is currently ignored in-circuit.
15111513
const auto& q_inf = memory.get(q_inf_addr);
15121514

15131515
set_and_validate_inputs(opcode, { p_x, p_y, p_inf, q_x, q_y, q_inf });
15141516
get_gas_tracker().consume_gas();
15151517

15161518
// Once inputs are tag checked the conversion to EmbeddedCurvePoint is safe, on curve checks are done in the add
1517-
// method.
1518-
EmbeddedCurvePoint p = EmbeddedCurvePoint(p_x.as_ff(), p_y.as_ff(), p_inf == MemoryValue::from<uint1_t>(1));
1519-
EmbeddedCurvePoint q = EmbeddedCurvePoint(q_x.as_ff(), q_y.as_ff(), q_inf == MemoryValue::from<uint1_t>(1));
1519+
// method. TODO(#AVM-266): We derive is_infinity from coordinates using the Noir convention of (x=0, y=0) <==>
1520+
// is_infinity. The flag will be removed in future.
1521+
const FF p_x_ff = p_x.as_ff();
1522+
const FF p_y_ff = p_y.as_ff();
1523+
EmbeddedCurvePoint p = EmbeddedCurvePoint(p_x_ff, p_y_ff, (p_x_ff == FF::zero()) && (p_y_ff == FF::zero()));
1524+
const FF q_x_ff = q_x.as_ff();
1525+
const FF q_y_ff = q_y.as_ff();
1526+
EmbeddedCurvePoint q = EmbeddedCurvePoint(q_x_ff, q_y_ff, (q_x_ff == FF::zero()) && (q_y_ff == FF::zero()));
15201527

15211528
try {
15221529
embedded_curve.add(memory, p, q, dst_addr);

barretenberg/cpp/src/barretenberg/vm2/tracegen/ecc_trace.cpp

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -299,13 +299,10 @@ void EccTraceBuilder::process_add_with_memory(
299299

300300
bool error = dst_out_of_range_err || !p_is_on_curve || !q_is_on_curve;
301301

302-
// TODO(#AVM-266): Remove is_infinity flag from point representation. For now, we derive is_inf by
303-
// checking coordinates in-circuit and ignoring the flag read from memory. Below, we do the 'reverse'
304-
// and set derive coordinates as (0, 0) if is_inf is true. This allows us to handle bb inf points until
305-
// the flag is removed.
306-
// Normalized points, ensures that input infinity points are represented by (0, 0) in the ecc subtrace.
307-
EmbeddedCurvePoint p_n = event.p.is_infinity() ? EmbeddedCurvePoint::infinity() : event.p;
308-
EmbeddedCurvePoint q_n = event.q.is_infinity() ? EmbeddedCurvePoint::infinity() : event.q;
302+
// TODO(#AVM-266): is_inf is (for now) derived from coordinates in-circuit (#[P/Q_INF_X/Y_CHECK]), but will be
303+
// removed.
304+
bool p_is_inf = (event.p.x() == FF::zero()) && (event.p.y() == FF::zero());
305+
bool q_is_inf = (event.q.x() == FF::zero()) && (event.q.y() == FF::zero());
309306

310307
trace.set(
311308
row,
@@ -331,16 +328,14 @@ void EccTraceBuilder::process_add_with_memory(
331328
{ C::ecc_add_mem_dst_addr_1_, dst_addr + 1 },
332329
{ C::ecc_add_mem_dst_addr_2_, dst_addr + 2 },
333330
// Input - Point P
334-
{ C::ecc_add_mem_p_x, p_n.x() },
335-
{ C::ecc_add_mem_p_y, p_n.y() },
336-
{ C::ecc_add_mem_p_is_inf,
337-
event.p.is_infinity() ? 1 : 0 }, // TODO(#AVM-266): If committed, Will be p.x() == 0 && p.y() == 0
331+
{ C::ecc_add_mem_p_x, event.p.x() },
332+
{ C::ecc_add_mem_p_y, event.p.y() },
333+
{ C::ecc_add_mem_p_is_inf, p_is_inf ? 1 : 0 },
338334
{ C::ecc_add_mem_p_is_inf_, event.p.is_infinity() ? 1 : 0 }, // TODO(#AVM-266): Remove is_infinity flag
339335
// Input - Point Q
340-
{ C::ecc_add_mem_q_x, q_n.x() },
341-
{ C::ecc_add_mem_q_y, q_n.y() },
342-
{ C::ecc_add_mem_q_is_inf,
343-
event.q.is_infinity() ? 1 : 0 }, // TODO(#AVM-266): If committed, Will be q.x() == 0 && q.y() == 0
336+
{ C::ecc_add_mem_q_x, event.q.x() },
337+
{ C::ecc_add_mem_q_y, event.q.y() },
338+
{ C::ecc_add_mem_q_is_inf, q_is_inf ? 1 : 0 },
344339
{ C::ecc_add_mem_q_is_inf_, event.q.is_infinity() ? 1 : 0 }, // TODO(#AVM-266): Remove is_infinity flag
345340
// Output
346341
{ C::ecc_add_mem_sel_should_exec, error ? 0 : 1 },

0 commit comments

Comments
 (0)