Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ecc.cpp
Go to the documentation of this file.
6
7namespace bb::avm2::simulation {
8
9// This function assumes that the points p and q are on the curve. You should only
10// use this function internally if you can guarantee this. Otherwise it is called
11// via the opcode ECADD, see the overloaded function Ecc::add (which performs the curve check)
13{
14 // Check if points are on the curve.
15 assert(p.on_curve() && "Point p is not on the curve");
16 assert(q.on_curve() && "Point q is not on the curve");
17
18 EmbeddedCurvePoint result = p + q;
19 add_events.emit({ .p = p, .q = q, .result = result });
20 return result;
21}
22
23// This function assumes that the point is on the curve. As this should only be used internally,
24// it is treated as a catastrophic failure if the point is not on the curve.
26{
27 // This is bad - the scalar mul circuit assumes that the point is on the curve.
28 assert(point.on_curve() && "Point must be on the curve for scalar multiplication");
29
30 auto intermediate_states = std::vector<ScalarMulIntermediateState>(254);
31 auto bits = to_radix.to_le_bits(scalar, 254);
32
33 // First iteration does conditional assignment instead of addition
34 EmbeddedCurvePoint temp = point;
35 bool bit = bits[0];
36
38 intermediate_states[0] = { result, temp, bit };
39
40 for (size_t i = 1; i < 254; i++) {
41 bit = bits[i];
42 temp = add(temp, temp);
43
44 if (bit) {
45 result = add(result, temp);
46 }
47 intermediate_states[i] = { result, temp, bit };
48 }
50 { .point = point, .scalar = scalar, .intermediate_states = std::move(intermediate_states), .result = result });
51 return result;
52}
53
55 const EmbeddedCurvePoint& p,
56 const EmbeddedCurvePoint& q,
57 MemoryAddress dst_address)
58{
59 uint32_t execution_clk = execution_id_manager.get_execution_id();
60 uint32_t space_id = memory.get_space_id();
61
62 try {
63 // The resulting EmbeddedCurvePoint is a triple of (x, y, is_infinity).
64 // The x and y coordinates are stored at dst_address and dst_address + 1 respectively,
65 // and the is_infinity flag is stored at dst_address + 2.
66 // Therefore, the maximum address that needs to be written to is dst_address + 2.
67 uint64_t max_write_address = static_cast<uint64_t>(dst_address) + 2;
68 if (gt.gt(max_write_address, AVM_HIGHEST_MEM_ADDRESS)) {
69 throw std::runtime_error("dst address out of range");
70 }
71
72 if (!p.on_curve() || !q.on_curve()) {
73 throw std::runtime_error("One of the points is not on the curve");
74 }
75
76 EmbeddedCurvePoint result = add(p, q);
77 memory.set(dst_address, MemoryValue::from<FF>(result.x()));
78 memory.set(dst_address + 1, MemoryValue::from<FF>(result.y()));
79 memory.set(dst_address + 2, MemoryValue::from<uint1_t>(result.is_infinity() ? 1 : 0));
80
81 add_memory_events.emit({ .execution_clk = execution_clk,
82 .space_id = space_id,
83 .p = p,
84 .q = q,
85 .result = result,
86 .dst_address = dst_address });
87 } catch (const std::exception& e) {
88 // Note this point is not on the curve, but corresponds
89 // to default values the circuit will assign.
90 EmbeddedCurvePoint res = EmbeddedCurvePoint(0, 0, false);
91 add_memory_events.emit({ .execution_clk = execution_clk,
92 .space_id = space_id,
93 .p = p,
94 .q = q,
95 .result = res,
96 .dst_address = dst_address });
97 throw EccException("Add failed: " + std::string(e.what()));
98 }
99}
100
101} // namespace bb::avm2::simulation
#define AVM_HIGHEST_MEM_ADDRESS
constexpr bool is_infinity() const noexcept
constexpr const BaseField & x() const noexcept
constexpr const BaseField & y() const noexcept
constexpr bool on_curve() const noexcept
EventEmitterInterface< ScalarMulEvent > & scalar_mul_events
Definition ecc.hpp:50
EmbeddedCurvePoint add(const EmbeddedCurvePoint &p, const EmbeddedCurvePoint &q) override
Definition ecc.cpp:12
EmbeddedCurvePoint scalar_mul(const EmbeddedCurvePoint &point, const FF &scalar) override
Definition ecc.cpp:25
EventEmitterInterface< EccAddMemoryEvent > & add_memory_events
Definition ecc.hpp:51
ExecutionIdManagerInterface & execution_id_manager
Definition ecc.hpp:54
EventEmitterInterface< EccAddEvent > & add_events
Definition ecc.hpp:49
virtual uint32_t get_execution_id() const =0
StandardAffinePoint< AvmFlavorSettings::EmbeddedCurve::AffineElement > EmbeddedCurvePoint
Definition field.hpp:12
uint32_t MemoryAddress
AvmFlavorSettings::FF FF
Definition field.hpp:10
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13