Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
pure_keccakf1600.test.cpp
Go to the documentation of this file.
1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
3
12
13using ::testing::ElementsAre;
14
15namespace bb::avm2::simulation {
16namespace {
17
18class PureKeccakSimulationTest : public ::testing::Test {
19 protected:
20 MemoryStore memory;
21 PureKeccakF1600 keccak;
22};
23
24TEST_F(PureKeccakSimulationTest, MatchesReferenceImplementation)
25{
27 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
28 };
29
30 const MemoryAddress src_addr = 1979;
31 const MemoryAddress dst_addr = 3030;
32
33 for (size_t i = 0; i < AVM_KECCAKF1600_STATE_SIZE; i++) {
34 memory.set(src_addr + static_cast<MemoryAddress>(i), MemoryValue::from<uint64_t>(input[i]));
35 }
36
37 keccak.permutation(memory, dst_addr, src_addr);
38
39 // Read output.
41 for (size_t i = 0; i < AVM_KECCAKF1600_STATE_SIZE; i++) {
42 MemoryValue val = memory.get(dst_addr + static_cast<MemoryAddress>(i));
43 EXPECT_EQ(val.get_tag(), MemoryTag::U64);
44 output[i] = val.as<uint64_t>();
45 }
46
47 ethash_keccakf1600(input.data()); // Mutate input
48 EXPECT_THAT(input, testing::ElementsAreArray(output));
49}
50
51// Test Vector from: https://github.com/XKCP/XKCP/blob/master/tests/TestVectors/KeccakF-1600-IntermediateValues.txt
52TEST_F(PureKeccakSimulationTest, OfficialTestVectorEmptyInput)
53{
55
56 for (size_t i = 0; i < AVM_KECCAKF1600_STATE_SIZE; i++) {
57 memory.set(static_cast<MemoryAddress>(i), MemoryValue::from<uint64_t>(input[i]));
58 }
59
60 keccak.permutation(memory, 0, 0);
61
63 for (size_t i = 0; i < AVM_KECCAKF1600_STATE_SIZE; i++) {
64 MemoryValue val = memory.get(static_cast<MemoryAddress>(i));
65 EXPECT_EQ(val.get_tag(), MemoryTag::U64);
66 output[i] = val.as<uint64_t>();
67 }
68
69 EXPECT_THAT(output,
70 ElementsAre(0xF1258F7940E1DDE7,
71 0x84D5CCF933C0478A,
72 0xD598261EA65AA9EE,
73 0xBD1547306F80494D,
74 0x8B284E056253D057,
75 0xFF97A42D7F8E6FD4,
76 0x90FEE5A0A44647C4,
77 0x8C5BDA0CD6192E76,
78 0xAD30A6F71B19059C,
79 0x30935AB7D08FFC64,
80 0xEB5AA93F2317D635,
81 0xA9A6E6260D712103,
82 0x81A57C16DBCF555F,
83 0x43B831CD0347C826,
84 0x01F22F1A11A5569F,
85 0x05E5635A21D9AE61,
86 0x64BEFEF28CC970F2,
87 0x613670957BC46611,
88 0xB87C5A554FD00ECB,
89 0x8C3EE88A1CCF32C8,
90 0x940C7922AE3A2614,
91 0x1841F924A2C509E4,
92 0x16F53526E70465C2,
93 0x75F644E97F30A13B,
94 0xEAF1FF7B5CECA249));
95}
96
97TEST_F(PureKeccakSimulationTest, OfficialTestVector)
98{
100 0xF1258F7940E1DDE7, 0x84D5CCF933C0478A, 0xD598261EA65AA9EE, 0xBD1547306F80494D, 0x8B284E056253D057,
101 0xFF97A42D7F8E6FD4, 0x90FEE5A0A44647C4, 0x8C5BDA0CD6192E76, 0xAD30A6F71B19059C, 0x30935AB7D08FFC64,
102 0xEB5AA93F2317D635, 0xA9A6E6260D712103, 0x81A57C16DBCF555F, 0x43B831CD0347C826, 0x01F22F1A11A5569F,
103 0x05E5635A21D9AE61, 0x64BEFEF28CC970F2, 0x613670957BC46611, 0xB87C5A554FD00ECB, 0x8C3EE88A1CCF32C8,
104 0x940C7922AE3A2614, 0x1841F924A2C509E4, 0x16F53526E70465C2, 0x75F644E97F30A13B, 0xEAF1FF7B5CECA249,
105 };
106
107 for (size_t i = 0; i < AVM_KECCAKF1600_STATE_SIZE; i++) {
108 memory.set(static_cast<MemoryAddress>(i), MemoryValue::from<uint64_t>(input[i]));
109 }
110
111 keccak.permutation(memory, 0, 0);
112
114 for (size_t i = 0; i < AVM_KECCAKF1600_STATE_SIZE; i++) {
115 MemoryValue val = memory.get(static_cast<MemoryAddress>(i));
116 EXPECT_EQ(val.get_tag(), MemoryTag::U64);
117 output[i] = val.as<uint64_t>();
118 }
119
120 EXPECT_THAT(output,
121 ElementsAre(
122 // 3C CB 6E F9 4D 95 5C 2D in little endian
123 0x2D5C954DF96ECB3C,
124 // 6D B5 57 70 D0 2C 33 6A in little endian
125 0x6A332CD07057B56D,
126 // 6C 6B D7 70 12 8D 3D 09 in little endian
127 0x093D8D1270D76B6C,
128 // 94 D0 69 55 B2 D9 20 8A in little endian
129 0x8A20D9B25569D094,
130 // 56 F1 E7 E5 99 4F 9C 4F in little endian
131 0x4F9C4F99E5E7F156,
132 // 38 FB 65 DA A2 B9 57 F9 in little endian
133 0xF957B9A2DA65FB38,
134 // 0D AF 75 12 AE 3D 77 85 in little endian
135 0x85773DAE1275AF0D,
136 // F7 10 D8 C3 47 F2 F4 FA in little endian
137 0xFAF4F247C3D810F7,
138 // 59 87 9A F7 E6 9E 1B 1F in little endian
139 0x1F1B9EE6F79A8759,
140 // 25 B4 98 EE 0F CC FE E4 in little endian
141 0xE4FECC0FEE98B425,
142 // A1 68 CE B9 B6 61 CE 68 in little endian
143 0x68CE61B6B9CE68A1,
144 // 4F 97 8F BA C4 66 EA DE in little endian
145 0xDEEA66C4BA8F974F,
146 // F5 B1 AF 6E 83 3D C4 33 in little endian
147 0x33C43D836EAFB1F5,
148 // D9 DB 19 27 04 54 06 E0 in little endian
149 0xE00654042719DBD9,
150 // 65 12 83 09 F0 A9 F8 7C in little endian
151 0x7CF8A9F009831265,
152 // 43 47 17 BF A6 49 54 FD in little endian
153 0xFD5449A6BF174743,
154 // 40 4B 99 D8 33 AD DD 97 in little endian
155 0x97DDAD33D8994B40,
156 // 74 E7 0B 5D FC D5 EA 48 in little endian
157 0x48EAD5FC5D0BE774,
158 // 3C B0 B7 55 EE C8 B8 E3 in little endian
159 0xE3B8C8EE55B7B03C,
160 // E9 42 9E 64 6E 22 A0 91 in little endian
161 0x91A0226E649E42E9,
162 // 7B DD BA E7 29 31 0E 90 in little endian
163 0x900E3129E7BADD7B,
164 // E8 CC A3 FA C5 9E 2A 20 in little endian
165 0x202A9EC5FAA3CCE8,
166 // B6 3D 1C 4E 46 02 34 5B in little endian
167 0x5B3402464E1C3DB6,
168 // 59 10 4C A4 62 4E 9F 60 in little endian
169 0x609F4E62A44C1059,
170 // 5C BF 8F 6A D2 6C D0 20 in little endian
171 0x20D06CD26A8FBF5C));
172}
173
174TEST_F(PureKeccakSimulationTest, TagError)
175{
176 const MemoryAddress src_addr = 1970;
177 const MemoryAddress src_addr_wrong_tag = 1979;
178 const MemoryAddress dst_addr = 3030;
179 const MemoryTag wrong_tag = MemoryTag::U128;
180
181 // Initialize the full slice with U64 values in standard Keccak layout
182 for (size_t i = 0; i < AVM_KECCAKF1600_STATE_SIZE; i++) {
183 memory.set(src_addr + static_cast<MemoryAddress>(i),
185 }
186
187 // Override just the first value with U128 to trigger the tag error
188 memory.set(src_addr_wrong_tag, MemoryValue::from_tag_truncating(wrong_tag, 0));
189
191 keccak.permutation(memory, dst_addr, src_addr),
192 format("Read slice tag invalid - addr: ", src_addr_wrong_tag, " tag: ", static_cast<uint32_t>(wrong_tag)));
193}
194
195TEST_F(PureKeccakSimulationTest, SrcSliceOutOfBounds)
196{
198 const MemoryAddress dst_addr = 3030;
199
200 EXPECT_THROW_WITH_MESSAGE(keccak.permutation(memory, dst_addr, src_addr), "Read slice out of range");
201}
202
203TEST_F(PureKeccakSimulationTest, DstSliceOutOfBounds)
204{
205 const MemoryAddress src_addr = 1970;
207
208 EXPECT_THROW_WITH_MESSAGE(keccak.permutation(memory, dst_addr, src_addr), "Write slice out of range");
209}
210
211} // namespace
212} // namespace bb::avm2::simulation
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
Definition assert.hpp:192
#define AVM_KECCAKF1600_STATE_SIZE
#define AVM_HIGHEST_MEM_ADDRESS
static TaggedValue from_tag_truncating(ValueTag tag, FF value)
void permutation(MemoryInterface &memory, MemoryAddress dst_addr, MemoryAddress src_addr) override
Permutation Keccak-f[1600] consisting in AVM_KECCAKF1600_NUM_ROUNDS (24) rounds and a state of 25 64-...
void set(MemoryAddress index, MemoryValue value) override
const MemoryValue & get(MemoryAddress index) const override
std::string format(Args... args)
Definition log.hpp:24
uint32_t dst_addr
void ethash_keccakf1600(uint64_t state[KECCAKF1600_LANES]) NOEXCEPT
TaggedValue MemoryValue
uint32_t MemoryAddress
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:185
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
KeccakF1600 keccak
MemoryStore memory