1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
30using ::testing::ElementsAreArray;
31using ::testing::NiceMock;
32using ::testing::Return;
33using ::testing::ReturnRef;
35using tracegen::Poseidon2TraceBuilder;
36using tracegen::TestTraceContainer;
90 FF a(
"9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
91 FF b(
"9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
92 FF c(
"0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
93 FF d(
"0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
95 std::array<FF, 4> input = {
a,
b, c, d };
96 auto result =
poseidon2.permutation(input);
98 std::array<FF, 4> expected = {
99 FF(
"0x2bf1eaf87f7d27e8dc4056e9af975985bccc89077a21891d6c7b6ccce0631f95"),
100 FF(
"0x0c01fa1b8d0748becafbe452c0cb0231c38224ea824554c9362518eebdd5701f"),
101 FF(
"0x018555a8eb50cf07f64b019ebaf3af3c925c93e631f3ecd455db07bbb52bbdd3"),
102 FF(
"0x0cbea457c91c22c6c31fd89afd2541efc2edf31736b9f721e823b2165c90fd41"),
105 EXPECT_THAT(result, ElementsAreArray(expected));
113 check_relation<poseidon2_perm>(
trace);
118 FF a(
"9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
119 FF b(
"9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
120 FF c(
"0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
122 std::vector<FF> input = {
a,
b, c };
129 { { C::precomputed_first_row, 1 } },
136 check_relation<poseidon2_hash>(
trace);
142 FF a(
"9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
143 FF b(
"9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
144 FF c(
"0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
145 FF d(
"0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
147 std::vector<FF> input = {
a,
b, c, d };
151 { { C::precomputed_first_row, 1 } },
158 check_relation<poseidon2_hash>(
trace);
163 std::vector<FF> input = { 1, 2, 3, 4 };
167 EXPECT_EQ(result, bb_result);
171 EXPECT_EQ(result, bb_result);
174 { { C::precomputed_first_row, 1 } },
182 check_relation<poseidon2_hash>(
trace);
187 std::vector<FF> input = { 1, 2, 3, 4 };
192 { { C::precomputed_first_row, 1 } },
198 check_interaction<Poseidon2TraceBuilder, lookup_poseidon2_hash_poseidon2_perm_settings>(
trace);
202 check_relation<poseidon2_hash>(
trace);
203 check_relation<poseidon2_perm>(
trace);
204 check_all_interactions<Poseidon2TraceBuilder>(
trace);
209 std::vector<FF> input = { 1, 2, 3, 4 };
214 { { C::precomputed_first_row, 1 } },
221 (check_interaction<Poseidon2TraceBuilder, lookup_poseidon2_hash_poseidon2_perm_settings>(
trace)),
222 "Failed.*POSEIDON2_PERM. Could not find tuple in destination.");
226 check_relation<poseidon2_hash>(
trace);
242 MemoryValue::from<FF>(1), MemoryValue::from<FF>(2), MemoryValue::from<FF>(3), MemoryValue::from<FF>(4)
253 .WillOnce(ReturnRef(
inputs[0]))
254 .WillOnce(ReturnRef(
inputs[1]))
255 .WillOnce(ReturnRef(
inputs[2]))
256 .WillOnce(ReturnRef(
inputs[3]));
257 EXPECT_CALL(
memory, set).Times(4);
263 check_relation<poseidon2_mem>(
trace);
270 .WillOnce(ReturnRef(
inputs[0]))
271 .WillOnce(ReturnRef(
inputs[1]))
272 .WillOnce(ReturnRef(
inputs[2]))
273 .WillOnce(ReturnRef(
inputs[3]));
274 EXPECT_CALL(
memory, set).Times(4);
277 std::vector<FF> outputs = {
FF(
"0x224785a48a72c75e2cbb698143e71d5d41bd89a2b9a7185871e39a54ce5785b1"),
278 FF(
"0x225bb800db22c4f4b09ace45cb484d42b0dd7dfe8708ee26aacde6f2c1fb2cb8"),
279 FF(
"0x1180f4260e60b4264c987b503075ea8374b53ed06c5145f8c21c2aadb5087d21"),
280 FF(
"0x16c877b5b9c04d873218804ccbf65d0eeb12db447f66c9ca26fec380055df7e9") };
287 { C::execution_sel, 1 },
288 { C::execution_sel_exec_dispatch_poseidon2_perm, 1 },
307 for (uint32_t i = 0; i <
inputs.size(); ++i) {
311 trace.
set(C::memory_tag, i,
static_cast<uint32_t
>(
inputs[i].get_tag()));
314 uint32_t write_index = i +
static_cast<uint32_t
>(
inputs.size());
316 trace.
set(C::memory_value, write_index, outputs[i]);
317 trace.
set(C::memory_sel, write_index, 1);
318 trace.
set(C::memory_rw, write_index, 1);
326 check_all_interactions<Poseidon2TraceBuilder>(
trace);
327 check_relation<poseidon2_mem>(
trace);
334 MemoryValue::from<FF>(1), MemoryValue::from<FF>(2), MemoryValue::from<uint64_t>(3), MemoryValue::from<FF>(4)
339 .WillOnce(ReturnRef(
inputs[0]))
340 .WillOnce(ReturnRef(
inputs[1]))
341 .WillOnce(ReturnRef(
inputs[2]))
342 .WillOnce(ReturnRef(
inputs[3]));
349 { C::execution_sel, 1 },
350 { C::execution_sel_exec_dispatch_poseidon2_perm, 1 },
353 { C::execution_sel_opcode_error, 1 },
370 for (uint32_t i = 0; i <
inputs.size(); ++i) {
374 trace.
set(C::memory_tag, i,
static_cast<uint32_t
>(
inputs[i].get_tag()));
379 "Poseidon2Exception.* input tag is not FF");
386 check_relation<poseidon2_mem>(
trace);
387 check_all_interactions<Poseidon2TraceBuilder>(
trace);
398 { C::execution_sel, 1 },
399 { C::execution_sel_exec_dispatch_poseidon2_perm, 1 },
402 { C::execution_sel_opcode_error, 1 },
412 { C::gt_input_a,
static_cast<uint64_t
>(
src_address) + 3 },
419 "Poseidon2Exception.* src or dst address out of range");
427 check_relation<poseidon2_mem>(
trace);
428 check_all_interactions<Poseidon2TraceBuilder>(
trace);
#define AVM_HIGHEST_MEM_ADDRESS
EventEmitter< Poseidon2PermutationMemoryEvent > perm_mem_event_emitter
EventEmitter< Poseidon2PermutationEvent > perm_event_emitter
EventEmitter< Poseidon2HashEvent > hash_event_emitter
EventEmitter< Poseidon2HashEvent > hash_event_emitter
EventEmitter< GreaterThanEvent > gt_event_emitter
EventEmitter< Poseidon2PermutationMemoryEvent > perm_mem_event_emitter
Poseidon2ConstrainingTest()
EventEmitter< Poseidon2PermutationEvent > perm_event_emitter
ExecutionIdManager execution_id_manager
DeduplicatingEventEmitter< FieldGreaterThanEvent > field_gt_event_emitter
NiceMock< MockRangeCheck > range_check
Poseidon2TraceBuilder builder
Poseidon2MemoryConstrainingTest()
NiceMock< MockMemory > memory
std::vector< MemoryValue > inputs
uint32_t get_num_rows() const
void set(Column col, uint32_t row, const FF &value)
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessage)
TEST_F(AvmRecursiveTests, GoblinRecursion)
A test of the Goblinized AVM recursive verifier.
TestTraceContainer empty_trace()
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept