Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
poseidon2.test.cpp
Go to the documentation of this file.
2
3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
5
11
12namespace bb::avm2::simulation {
13namespace {
14
15using ::testing::_;
16using ::testing::ElementsAre;
17using ::testing::ElementsAreArray;
18using ::testing::Field;
19using ::testing::StrictMock;
20
21class Poseidon2SimulationTest : public ::testing::Test {
22 protected:
23 Poseidon2SimulationTest()
24 {
25 EXPECT_CALL(execution_id_manager, get_execution_id())
26 .WillRepeatedly(testing::Return(0)); // Default execution ID for testing
27 }
28
29 EventEmitter<Poseidon2HashEvent> hash_event_emitter;
30 EventEmitter<Poseidon2PermutationEvent> perm_event_emitter;
31 EventEmitter<Poseidon2PermutationMemoryEvent> perm_mem_event_emitter;
32
33 StrictMock<MockExecutionIdManager> execution_id_manager;
34
35 PureGreaterThan gt;
37 Poseidon2(execution_id_manager, gt, hash_event_emitter, perm_event_emitter, perm_mem_event_emitter);
38};
39
40TEST_F(Poseidon2SimulationTest, Hash)
41{
42 // Taken From barretenberg/crypto/poseidon2/poseidon2.test.cpp
43 FF a("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
44 FF b("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
45 FF c("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
46 FF d("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
47
48 std::vector<FF> input = { a, b, c, d };
49
50 FF result = poseidon2.hash(input);
51 FF expected("0x2f43a0f83b51a6f5fc839dea0ecec74947637802a579fa9841930a25a0bcec11");
52 EXPECT_EQ(result, expected);
53
54 std::vector<Poseidon2HashEvent> event_result = hash_event_emitter.dump_events();
55
56 EXPECT_THAT(event_result,
57 ElementsAre(testing::AllOf(Field(&Poseidon2HashEvent::inputs, ElementsAreArray(input)),
59 Field(&Poseidon2HashEvent::output, expected))));
60}
61
62TEST_F(Poseidon2SimulationTest, Permutation)
63{
64 // Taken From barretenberg/crypto/poseidon2/poseidon2.test.cpp
65 FF a("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
66 FF b("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
67 FF c("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
68 FF d("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789");
69
70 std::array<FF, 4> input = { a, b, c, d };
71 auto result = poseidon2.permutation(input);
72
73 std::array<FF, 4> expected = {
74 FF("0x2bf1eaf87f7d27e8dc4056e9af975985bccc89077a21891d6c7b6ccce0631f95"),
75 FF("0x0c01fa1b8d0748becafbe452c0cb0231c38224ea824554c9362518eebdd5701f"),
76 FF("0x018555a8eb50cf07f64b019ebaf3af3c925c93e631f3ecd455db07bbb52bbdd3"),
77 FF("0x0cbea457c91c22c6c31fd89afd2541efc2edf31736b9f721e823b2165c90fd41"),
78 };
79 EXPECT_THAT(result, ElementsAreArray(expected));
80
82
83 EXPECT_THAT(event_results,
84 ElementsAre(AllOf(Field(&Poseidon2PermutationEvent::input, ElementsAreArray(input)),
85 Field(&Poseidon2PermutationEvent::output, ElementsAreArray(expected)))));
86}
87
88// This test may seem redundant, but since we kind of re-implement the Poseidon2 sponge function, it's good to have it.
89TEST_F(Poseidon2SimulationTest, RandomHash)
90{
91 std::vector<FF> input;
92 input.reserve(14);
93
94 for (int i = 0; i < 14; i++) {
95 input.push_back(FF::random_element());
96 }
97
98 FF result = poseidon2.hash(input);
99 FF bb_result = crypto::Poseidon2<crypto::Poseidon2Bn254ScalarFieldParams>::hash(input);
100
101 EXPECT_EQ(result, bb_result);
102}
103
104TEST_F(Poseidon2SimulationTest, PermutationWithMemory)
105{
106 MemoryStore mem;
107 MemoryAddress src_address = 0;
108
109 // Inputs taken From barretenberg/crypto/poseidon2/poseidon2.test.cpp
110 std::array<FF, 4> inputs = { FF("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"),
111 FF("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"),
112 FF("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"),
113 FF("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789") };
114 // Fill the memory with 4 FF Elements
115 for (uint32_t i = 0; i < 4; ++i) {
116 mem.set(src_address + i, MemoryValue::from<FF>(inputs[i]));
117 }
118
119 MemoryAddress dst_address = 4;
120
121 poseidon2.permutation(mem, src_address, dst_address);
122
123 std::array<FF, 4> expected = {
124 FF("0x2bf1eaf87f7d27e8dc4056e9af975985bccc89077a21891d6c7b6ccce0631f95"),
125 FF("0x0c01fa1b8d0748becafbe452c0cb0231c38224ea824554c9362518eebdd5701f"),
126 FF("0x018555a8eb50cf07f64b019ebaf3af3c925c93e631f3ecd455db07bbb52bbdd3"),
127 FF("0x0cbea457c91c22c6c31fd89afd2541efc2edf31736b9f721e823b2165c90fd41"),
128 };
129
130 // Read the memory at the destination address and check if it matches the expected output
131 for (uint32_t i = 0; i < expected.size(); ++i) {
132 EXPECT_EQ(mem.get(dst_address + i).as_ff(), expected[i]);
133 }
134}
135
136TEST_F(Poseidon2SimulationTest, PermutationWithMemoryAddressOutOfRange)
137{
138 MemoryStore mem;
139 MemoryAddress src_address = AVM_HIGHEST_MEM_ADDRESS; // This will cause an out of range error
140 MemoryAddress dst_address = 0;
141
142 EXPECT_THROW(poseidon2.permutation(mem, src_address, dst_address), std::runtime_error);
143}
144
145TEST_F(Poseidon2SimulationTest, PermutationWithMemoryInvalidMemTag)
146{
147 MemoryStore mem;
148 MemoryAddress src_address = 0;
149 MemoryAddress dst_address = 4;
150
151 // Inputs taken From barretenberg/crypto/poseidon2/poseidon2.test.cpp
153 MemoryValue::from<FF>(FF("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")),
154 MemoryValue::from<FF>(FF("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")),
155 MemoryValue::from<uint64_t>(123456789), // Invalid tag
156 MemoryValue::from<FF>(FF("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"))
157 };
158
159 // Fill the memory with 4 elements
160 for (uint32_t i = 0; i < inputs.size(); ++i) {
161 mem.set(src_address + i, inputs[i]);
162 }
163
164 EXPECT_THROW(poseidon2.permutation(mem, src_address, dst_address), Poseidon2Exception);
165}
166
167} // namespace
168} // namespace bb::avm2::simulation
#define AVM_HIGHEST_MEM_ADDRESS
EventEmitter< Poseidon2PermutationMemoryEvent > perm_mem_event_emitter
EventEmitter< Poseidon2PermutationEvent > perm_event_emitter
EventEmitter< Poseidon2HashEvent > hash_event_emitter
void set(MemoryAddress index, MemoryValue value) override
const MemoryValue & get(MemoryAddress index) const override
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
Implements a parallelized batch insertion indexed tree Accepts template argument of the type of store...
Circuit form of Poseidon2 permutation from https://eprint.iacr.org/2023/323.
ExecutionIdManager execution_id_manager
MemoryStore mem
GreaterThan gt
FF a
FF b
uint32_t MemoryAddress
AvmFlavorSettings::FF FF
Definition field.hpp:10
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:188
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::vector< std::array< FF, 4 > > intermediate_states
static field random_element(numeric::RNG *engine=nullptr) noexcept