Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ecc.test.cpp
Go to the documentation of this file.
2
3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
5
13
14using ::testing::AllOf;
15using ::testing::ElementsAre;
16using ::testing::Return;
17using ::testing::SizeIs;
18using ::testing::StrictMock;
19
20namespace bb::avm2::simulation {
21namespace {
22
23TEST(AvmSimulationEccTest, Add)
24{
25 EventEmitter<EccAddEvent> ecc_event_emitter;
26 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
27 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
28
29 StrictMock<MockExecutionIdManager> execution_id_manager;
30 StrictMock<MockGreaterThan> gt;
31 StrictMock<MockToRadix> to_radix;
32
33 Ecc ecc(
34 execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter);
35
36 FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
37 FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
38 EmbeddedCurvePoint p(p_x, p_y, false);
39
40 FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7");
41 FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3");
42 EmbeddedCurvePoint q(q_x, q_y, false);
43
44 EmbeddedCurvePoint result = ecc.add(p, q);
45
46 FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6");
47 FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
48
49 EXPECT_EQ(result.x(), r_x);
50 EXPECT_EQ(result.y(), r_y);
51 EXPECT_EQ(result.is_infinity(), 0);
52
53 auto events = ecc_event_emitter.dump_events();
54 EXPECT_EQ(events.size(), 1);
55 EXPECT_EQ(events[0].p, p);
56 EXPECT_EQ(events[0].q, q);
57 EXPECT_EQ(events[0].result, result);
58}
59
60TEST(AvmSimulationEccTest, ScalarMul)
61{
62 EventEmitter<EccAddEvent> ecc_event_emitter;
63 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
64 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
65
66 StrictMock<MockExecutionIdManager> execution_id_manager;
67 StrictMock<MockGreaterThan> gt;
68 StrictMock<MockToRadix> to_radix;
69
70 Ecc ecc(
71 execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter);
72
73 FF scalar("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7");
74 uint256_t scalar_num = scalar;
75 std::vector<bool> bits(254, false);
76 for (size_t i = 0; i < 254; ++i) {
77 bits[i] = scalar_num.get_bit(i);
78 }
79
80 EXPECT_CALL(to_radix, to_le_bits(scalar, 254)).WillOnce(Return(bits));
81
82 FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
83 FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
84 EmbeddedCurvePoint p(p_x, p_y, false);
85
86 EmbeddedCurvePoint result = ecc.scalar_mul(p, scalar);
87
89
90 EXPECT_EQ(result, expected_result);
91
93 intermediate_states.reserve(254);
94
96 EmbeddedCurvePoint temp = p;
97 uint256_t scalar_value = scalar;
98
99 for (size_t i = 0; i < 254; ++i) {
100 bool bit = scalar_value.get_bit(i);
101 if (bit) {
102 res = res + temp;
103 }
104 intermediate_states.push_back({ res, temp, bit });
105 temp = temp + temp;
106 }
107
108 auto events = scalar_mul_event_emitter.dump_events();
109 EXPECT_THAT(events, AllOf(ElementsAre(ScalarMulEvent{ p, scalar, intermediate_states, result }), SizeIs(1)));
110}
111
112// This is a death test, should be run in single-threaded context
113TEST(AvmSimulationEccDeathTest, ScalarMulNotOnCurve)
114{
115 EventEmitter<EccAddEvent> ecc_event_emitter;
116 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
117 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
118
119 StrictMock<MockExecutionIdManager> execution_id_manager;
120 StrictMock<MockGreaterThan> gt;
121 StrictMock<MockToRadix> to_radix;
122
123 Ecc ecc(
124 execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter);
125
126 // Point P is not on the curve
127 FF p_x("0x0000000000063d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
128 FF p_y("0x00000000000c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
129 EmbeddedCurvePoint p(p_x, p_y, false);
130
131 FF scalar("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7");
132
133 ASSERT_DEATH(ecc.scalar_mul(p, scalar), "Point must be on the curve for scalar multiplication");
134}
135
136TEST(AvmSimulationEccTest, AddWithMemory)
137{
138 EventEmitter<EccAddEvent> ecc_event_emitter;
139 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
140 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
141
142 StrictMock<MockExecutionIdManager> execution_id_manager;
143 StrictMock<MockGreaterThan> gt;
144 StrictMock<MockToRadix> to_radix;
145 MemoryStore memory;
146
147 EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0));
148 EXPECT_CALL(gt, gt(0x1000 + 2, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false));
149
150 Ecc ecc(
151 execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter);
152
153 FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
154 FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
155 EmbeddedCurvePoint p(p_x, p_y, false);
156
157 FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7");
158 FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3");
159 EmbeddedCurvePoint q(q_x, q_y, false);
160
161 FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6");
162 FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
163 EmbeddedCurvePoint expected_result(r_x, r_y, false);
164
165 uint32_t dst_address = 0x1000;
166 ecc.add(memory, p, q, dst_address);
167
168 EmbeddedCurvePoint result = { memory.get(dst_address).as_ff(),
169 memory.get(dst_address + 1).as_ff(),
170 static_cast<bool>(memory.get(dst_address + 2).as_ff()) };
171 EXPECT_EQ(result, expected_result);
172}
173
174TEST(AvmSimulationEccTest, AddNotOnCurve)
175{
176 EventEmitter<EccAddEvent> ecc_event_emitter;
177 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
178 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
179
180 StrictMock<MockExecutionIdManager> execution_id_manager;
181 StrictMock<MockGreaterThan> gt;
182 StrictMock<MockToRadix> to_radix;
183 MemoryStore memory;
184
185 EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0));
186 EXPECT_CALL(gt, gt(0x1000 + 2, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false));
187
188 Ecc ecc(
189 execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter);
190
191 // Point P is not on the curve
192 FF p_x("0x0000000000063d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
193 FF p_y("0x00000000000c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
194 EmbeddedCurvePoint p(p_x, p_y, false);
195
196 // Point Q is on the curve
197 FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7");
198 FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3");
199 EmbeddedCurvePoint q(q_x, q_y, false);
200
201 uint32_t dst_address = 0x1000;
202 EXPECT_THROW(ecc.add(memory, p, q, dst_address), EccException);
203}
204
205TEST(AvmSimulationEccTest, InfinityOnCurve)
206{
207 EventEmitter<EccAddEvent> ecc_event_emitter;
208 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
209 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
210
211 StrictMock<MockExecutionIdManager> execution_id_manager;
212 StrictMock<MockGreaterThan> gt;
213 StrictMock<MockToRadix> to_radix;
214 MemoryStore memory;
215
216 EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0));
217 EXPECT_CALL(gt, gt(0x1000 + 2, AVM_HIGHEST_MEM_ADDRESS)).WillOnce(Return(false));
218
219 Ecc ecc(
220 execution_id_manager, gt, to_radix, ecc_event_emitter, scalar_mul_event_emitter, ecc_add_memory_event_emitter);
221
222 // Point P is not on the curve
224
225 // Point Q is on the curve
226 FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7");
227 FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3");
228 EmbeddedCurvePoint q(q_x, q_y, false);
229
230 uint32_t dst_address = 0x1000;
231 ecc.add(memory, p, q, dst_address);
232
233 EmbeddedCurvePoint result = { memory.get(dst_address).as_ff(),
234 memory.get(dst_address + 1).as_ff(),
235 static_cast<bool>(memory.get(dst_address + 2).as_ff()) };
236 // INF + Q = Q
237 EXPECT_EQ(result, q);
238}
239
240} // namespace
241} // namespace bb::avm2::simulation
#define AVM_HIGHEST_MEM_ADDRESS
const MemoryValue & get(MemoryAddress index) const override
Definition memory.hpp:92
constexpr bool get_bit(uint64_t bit_index) const
ExecutionIdManager execution_id_manager
GreaterThan gt
bool expected_result
TEST(EmitUnencryptedLogTest, Basic)
StandardAffinePoint< AvmFlavorSettings::EmbeddedCurve::AffineElement > EmbeddedCurvePoint
Definition field.hpp:12
AvmFlavorSettings::G1::Fq Fq
Definition field.hpp:11
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
MemoryStore memory