Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
to_radix.test.cpp
Go to the documentation of this file.
2
3#include <cstdint>
4#include <gmock/gmock.h>
5#include <gtest/gtest.h>
6
16
17using ::testing::AllOf;
18using ::testing::ElementsAre;
19using ::testing::Field;
20using ::testing::Return;
21using ::testing::SizeIs;
22using ::testing::StrictMock;
23
24namespace bb::avm2::simulation {
25namespace {
26
27TEST(AvmSimulationToRadixTest, BasicBits)
28{
29 EventEmitter<ToRadixEvent> to_radix_event_emitter;
30 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
31
32 StrictMock<MockExecutionIdManager> execution_id_manager;
33 StrictMock<MockGreaterThan> gt;
34 ToRadix to_radix(execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
35
36 auto [bits, truncated] = to_radix.to_le_bits(FF::one(), 254);
37
38 std::vector<bool> expected_result(254, false);
39 expected_result[0] = true;
40
41 EXPECT_EQ(bits, expected_result);
42 EXPECT_FALSE(truncated);
43 EXPECT_THAT(to_radix_event_emitter.dump_events(),
44 AllOf(SizeIs(1),
45 ElementsAre(AllOf(Field(&ToRadixEvent::value, FF::one()),
46 Field(&ToRadixEvent::radix, 2),
47 Field(&ToRadixEvent::limbs, SizeIs(254))))));
48}
49
50TEST(AvmSimulationToRadixTest, ShortBits)
51{
52 EventEmitter<ToRadixEvent> to_radix_event_emitter;
53 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
54
55 StrictMock<MockExecutionIdManager> execution_id_manager;
56 StrictMock<MockGreaterThan> gt;
57 ToRadix to_radix(execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
58
59 auto [bits, truncated] = to_radix.to_le_bits(FF::one(), 1);
60
61 std::vector<bool> expected_result = { true };
62
63 EXPECT_EQ(bits, expected_result);
64 EXPECT_FALSE(truncated);
65
66 EXPECT_THAT(to_radix_event_emitter.dump_events(),
67 AllOf(SizeIs(1), ElementsAre(AllOf(Field(&ToRadixEvent::limbs, SizeIs(1))))));
68}
69
70TEST(AvmSimulationToRadixTest, DecomposeOneBitLargeValue)
71{
72 EventEmitter<ToRadixEvent> to_radix_event_emitter;
73 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
74
75 StrictMock<MockExecutionIdManager> execution_id_manager;
76 StrictMock<MockGreaterThan> gt;
77 ToRadix to_radix(execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
78
79 auto [bits, truncated] = to_radix.to_le_bits(FF::neg_one(), 1);
80
81 // first bit of p - 1 is zero
82 std::vector<bool> expected_result = { false };
83
84 EXPECT_EQ(bits, expected_result);
85 EXPECT_TRUE(truncated);
86
87 // 254 limbs are needed to represent p - 1
88 EXPECT_THAT(to_radix_event_emitter.dump_events(),
89 AllOf(SizeIs(1), ElementsAre(AllOf(Field(&ToRadixEvent::limbs, SizeIs(254))))));
90}
91
92TEST(AvmSimulationToRadixTest, BasicRadix)
93{
94 EventEmitter<ToRadixEvent> to_radix_event_emitter;
95 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
96
97 StrictMock<MockExecutionIdManager> execution_id_manager;
98 StrictMock<MockGreaterThan> gt;
99 ToRadix to_radix(execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
100
101 auto [limbs, truncated] = to_radix.to_le_radix(FF::one(), 32, 256);
102
103 std::vector<uint8_t> expected_result(32, 0);
104 expected_result[0] = 1;
105
106 EXPECT_EQ(limbs, expected_result);
107 EXPECT_FALSE(truncated);
108
109 EXPECT_THAT(to_radix_event_emitter.dump_events(),
110 AllOf(SizeIs(1),
111 ElementsAre(AllOf(Field(&ToRadixEvent::value, FF::one()),
112 Field(&ToRadixEvent::radix, 256),
113 Field(&ToRadixEvent::limbs, SizeIs(32))))));
114}
115
116TEST(AvmSimulationToRadixTest, ShortRadix)
117{
118 EventEmitter<ToRadixEvent> to_radix_event_emitter;
119 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
120
121 StrictMock<MockExecutionIdManager> execution_id_manager;
122 StrictMock<MockGreaterThan> gt;
123 ToRadix to_radix(execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
124
125 auto [limbs, truncated] = to_radix.to_le_radix(FF::one(), 1, 256);
126
127 std::vector<uint8_t> expected_result = { 1 };
128
129 EXPECT_EQ(limbs, expected_result);
130 EXPECT_FALSE(truncated);
131
132 EXPECT_THAT(to_radix_event_emitter.dump_events(),
133 AllOf(SizeIs(1), ElementsAre(Field(&ToRadixEvent::limbs, SizeIs(1)))));
134}
135
136TEST(AvmSimulationToRadixTest, DecomposeOneRadixLargerValue)
137{
138 EventEmitter<ToRadixEvent> to_radix_event_emitter;
139 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
140
141 StrictMock<MockExecutionIdManager> execution_id_manager;
142 StrictMock<MockGreaterThan> gt;
143 ToRadix to_radix(execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
144
145 auto [limbs, truncated] = to_radix.to_le_radix(FF::neg_one(), 1, 256);
146
147 // first byte of p - 1 is zero
148 std::vector<uint8_t> expected_result = { 0 };
149
150 EXPECT_EQ(limbs, expected_result);
151 EXPECT_TRUE(truncated);
152
153 // 32 limbs are needed to represent p - 1
154 EXPECT_THAT(to_radix_event_emitter.dump_events(),
155 AllOf(SizeIs(1), ElementsAre(AllOf(Field(&ToRadixEvent::limbs, SizeIs(32))))));
156}
157
158TEST(AvmSimulationToRadixTest, DecomposeInDecimal)
159{
160 EventEmitter<ToRadixEvent> to_radix_event_emitter;
161 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
162
163 StrictMock<MockExecutionIdManager> execution_id_manager;
164 StrictMock<MockGreaterThan> gt;
165 ToRadix to_radix(execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
166
167 auto [limbs, truncated] = to_radix.to_le_radix(1337, 4, 10);
168
169 std::vector<uint8_t> expected_result = { 7, 3, 3, 1 };
170
171 EXPECT_EQ(limbs, expected_result);
172 EXPECT_FALSE(truncated);
173}
174
175TEST(AvmSimulationToRadixMemoryTest, BasicTest)
176{
177 EventEmitter<ToRadixEvent> to_radix_event_emitter;
178 EventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
179
180 MemoryStore memory;
181 StrictMock<MockExecutionIdManager> execution_id_manager;
182 EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0));
183 PureGreaterThan gt;
184 ToRadix to_radix(execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
185
186 const FF value = 1337;
187 const uint32_t radix = 10;
188 const uint32_t num_limbs = 4;
189 bool is_output_bits = false; // Output is U8, not U1
190 MemoryAddress dst_addr = 0xdeadbeef;
191
192 to_radix.to_be_radix(memory, value, radix, num_limbs, is_output_bits, dst_addr);
193
194 std::vector<uint8_t> output;
195 output.reserve(num_limbs);
196
197 for (uint32_t i = 0; i < num_limbs; ++i) {
198 output.emplace_back(memory.get(dst_addr + i).as<uint8_t>());
199 }
200
201 std::vector<uint8_t> expected_result = { 1, 3, 3, 7 };
202 EXPECT_EQ(output, expected_result);
203}
204
205TEST(AvmSimulationToRadixMemoryTest, DstOutOfRange)
206{
207 EventEmitter<ToRadixEvent> to_radix_event_emitter;
208 EventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
209
210 MemoryStore memory;
211 StrictMock<MockExecutionIdManager> execution_id_manager;
212 EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0));
213 PureGreaterThan gt;
214 ToRadix to_radix(execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
215
216 const FF value = 1337;
217 const uint32_t radix = 10;
218 const uint32_t num_limbs = 4;
219 bool is_output_bits = false; // Output is U8, not U1
220 uint32_t num_writes = num_limbs - 1;
222 AVM_HIGHEST_MEM_ADDRESS - num_writes + 1; // This will cause an out-of-bounds at the last write
223
224 EXPECT_THROW(to_radix.to_be_radix(memory, value, radix, num_limbs, is_output_bits, dst_addr), ToRadixException);
225}
226
227TEST(AvmSimulationToRadixMemoryTest, InvalidRadixValue)
228{
229 EventEmitter<ToRadixEvent> to_radix_event_emitter;
230 EventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
231
232 MemoryStore memory;
233 StrictMock<MockExecutionIdManager> execution_id_manager;
234 EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0));
235 PureGreaterThan gt;
236 ToRadix to_radix(execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
237
238 const FF value = 1337;
239 const uint32_t radix = 1; // Invalid radix
240 const uint32_t num_limbs = 4;
241 bool is_output_bits = false; // Output is U8, not U1
242 MemoryAddress dst_addr = 0xdeadbeef;
243
244 EXPECT_THROW(to_radix.to_be_radix(memory, value, radix, num_limbs, is_output_bits, dst_addr), ToRadixException);
245}
246
247TEST(AvmSimulationToRadixMemoryTest, TruncationError)
248{
249 EventEmitter<ToRadixEvent> to_radix_event_emitter;
250 EventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
251
252 MemoryStore memory;
253 StrictMock<MockExecutionIdManager> execution_id_manager;
254 EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(Return(0));
255 PureGreaterThan gt;
256 ToRadix to_radix(execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
257
258 const FF value = 1337;
259 const uint32_t radix = 10;
260 const uint32_t num_limbs = 3;
261 bool is_output_bits = false; // Output is U8, not U1
262 MemoryAddress dst_addr = 0xdeadbeef;
263
264 EXPECT_THROW_WITH_MESSAGE(to_radix.to_be_radix(memory, value, radix, num_limbs, is_output_bits, dst_addr),
265 "Truncation error");
266
267 std::vector<MemoryValue> expected_limbs = {
268 MemoryValue::from<uint8_t>(3),
269 MemoryValue::from<uint8_t>(3),
270 MemoryValue::from<uint8_t>(7),
271 };
272
273 EXPECT_THAT(to_radix_mem_event_emitter.dump_events(),
274 AllOf(SizeIs(1),
275 ElementsAre(AllOf(Field(&ToRadixMemoryEvent::limbs, expected_limbs),
276 Field(&ToRadixMemoryEvent::num_limbs, 3)))));
277}
278
279} // namespace
280} // namespace bb::avm2::simulation
#define AVM_HIGHEST_MEM_ADDRESS
const MemoryValue & get(MemoryAddress index) const override
ExecutionIdManager execution_id_manager
uint32_t dst_addr
GreaterThan gt
bool expected_result
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessage)
Definition macros.hpp:7
TEST(EmitUnencryptedLogTest, Basic)
uint32_t MemoryAddress
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
MemoryStore memory
static constexpr field neg_one()
static constexpr field one()