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
9namespace {
10
11class InternalEccException : public std::runtime_error {
12 public:
13 using std::runtime_error::runtime_error; // Inherit the constructor.
14};
15
16} // namespace
17
18// This function assumes that the points p and q are on the curve. You should only
19// use this function internally if you can guarantee this. Otherwise it is called
20// via the opcode ECADD, see the overloaded function Ecc::add (which performs the curve check)
22{
23 // Check if points are on the curve. These will throw an unexpected exception if they fail.
24 BB_ASSERT(p.on_curve(), "Point p is not on the curve");
25 BB_ASSERT(q.on_curve(), "Point q is not on the curve");
26
27 EmbeddedCurvePoint result = p + q;
28 add_events.emit({ .p = p, .q = q, .result = result });
29 return result;
30}
31
32// This function assumes that the point is on the curve. As this should only be used internally,
33// it is treated as a catastrophic failure if the point is not on the curve.
35{
36 // This is bad - the scalar mul circuit assumes that the point is on the curve.
37 // This will throw an unexpected exception if it fails.
38 BB_ASSERT(point.on_curve(), "Point must be on the curve for scalar multiplication");
39
40 auto intermediate_states = std::vector<ScalarMulIntermediateState>(254);
41 auto bits = to_radix.to_le_bits(scalar, 254).first;
42
43 // First iteration does conditional assignment instead of addition
44 EmbeddedCurvePoint temp = point;
45 bool bit = bits[0];
46
48 intermediate_states[0] = { result, temp, bit };
49
50 for (size_t i = 1; i < 254; i++) {
51 bit = bits[i];
52 temp = add(temp, temp);
53
54 if (bit) {
55 result = add(result, temp);
56 }
57 intermediate_states[i] = { result, temp, bit };
58 }
60 { .point = point, .scalar = scalar, .intermediate_states = std::move(intermediate_states), .result = result });
61 return result;
62}
63
65 const EmbeddedCurvePoint& p,
66 const EmbeddedCurvePoint& q,
68{
69 uint32_t execution_clk = execution_id_manager.get_execution_id();
70 uint16_t space_id = memory.get_space_id();
71
72 try {
73 // The resulting EmbeddedCurvePoint is a triple of (x, y, is_infinity).
74 // The x and y coordinates are stored at dst_address and dst_address + 1 respectively,
75 // and the is_infinity flag is stored at dst_address + 2.
76 // Therefore, the maximum address that needs to be written to is dst_address + 2.
77 uint64_t max_write_address = static_cast<uint64_t>(dst_address) + 2;
78 if (gt.gt(max_write_address, AVM_HIGHEST_MEM_ADDRESS)) {
79 throw InternalEccException("dst address out of range");
80 }
81
82 if (!p.on_curve() || !q.on_curve()) {
83 throw InternalEccException("One of the points is not on the curve");
84 }
85
86 EmbeddedCurvePoint result = add(p, q); // Cannot throw.
87
88 memory.set(dst_address, MemoryValue::from<FF>(result.x()));
89 memory.set(dst_address + 1, MemoryValue::from<FF>(result.y()));
90 memory.set(dst_address + 2, MemoryValue::from<uint1_t>(result.is_infinity() ? 1 : 0));
91
92 add_memory_events.emit({ .execution_clk = execution_clk,
93 .space_id = space_id,
94 .p = p,
95 .q = q,
96 .result = result,
97 .dst_address = dst_address });
98 } catch (const InternalEccException& e) {
99 // Note this point is not on the curve, but corresponds
100 // to default values the circuit will assign.
101 EmbeddedCurvePoint res = EmbeddedCurvePoint(0, 0, false);
102 add_memory_events.emit({ .execution_clk = execution_clk,
103 .space_id = space_id,
104 .p = p,
105 .q = q,
106 .result = res,
107 .dst_address = dst_address });
108 throw EccException("Add failed: " + std::string(e.what()));
109 }
110}
111
112} // namespace bb::avm2::simulation
#define BB_ASSERT(expression,...)
Definition assert.hpp:80
#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:40
EmbeddedCurvePoint add(const EmbeddedCurvePoint &p, const EmbeddedCurvePoint &q) override
Definition ecc.cpp:21
EmbeddedCurvePoint scalar_mul(const EmbeddedCurvePoint &point, const FF &scalar) override
Definition ecc.cpp:34
EventEmitterInterface< EccAddMemoryEvent > & add_memory_events
Definition ecc.hpp:41
ExecutionIdManagerInterface & execution_id_manager
Definition ecc.hpp:44
EventEmitterInterface< EccAddEvent > & add_events
Definition ecc.hpp:39
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