86 constexpr MemoryAddress HIGHEST_SLICE_ADDRESS = AVM_HIGHEST_MEM_ADDRESS - AVM_KECCAKF1600_STATE_SIZE + 1;
97 if (src_out_of_range) {
100 if (dst_out_of_range) {
110 for (
size_t k = 0; k < AVM_KECCAKF1600_STATE_SIZE; k++) {
114 src_mem_values[k] = mem_val;
121 format(
"Read slice tag invalid - addr: ", addr,
" tag: ",
static_cast<uint32_t
>(
tag)));
130 for (
size_t k = 0; k < AVM_KECCAKF1600_STATE_SIZE; k++) {
131 state_input_values[k % 5][k / 5] = src_mem_values[k];
136 for (uint8_t round_idx = 0; round_idx < AVM_KECCAKF1600_NUM_ROUNDS; round_idx++) {
144 const auto theta_acc = [&](
size_t i,
size_t step) ->
const MemoryValue& {
145 return step == 0 ? state_input_values[i][0] : theta_xor_values[i][step - 1];
147 for (
size_t step = 0; step < 4; ++step) {
148 for (
size_t s = 0; s + 1 < 4; s += 2) {
149 auto [c0, c1] =
bitwise.simd_xor_op_64(theta_acc(s, step),
150 state_input_values[s][step + 1],
151 theta_acc(s + 1, step),
152 state_input_values[s + 1][step + 1]);
153 theta_xor_values[s][step] = c0;
154 theta_xor_values[s + 1][step] = c1;
156 theta_xor_values[4][step] =
bitwise.xor_op(theta_acc(4, step), state_input_values[4][step + 1]);
161 for (
size_t i = 0; i < 5; ++i) {
162 theta_xor_row_rotl1_values[i] = unconstrained_rotate_left(theta_xor_values[i][3], 1);
169 for (
size_t i = 0; i + 1 < 5; i += 2) {
170 auto [c0, c1] =
bitwise.simd_xor_op_64(theta_xor_values[(i + 4) % 5][3],
171 theta_xor_row_rotl1_values[(i + 1) % 5],
172 theta_xor_values[i % 5][3],
173 theta_xor_row_rotl1_values[(i + 1 + 1) % 5]);
174 theta_combined_xor_values[i] = c0;
175 theta_combined_xor_values[i + 1] = c1;
177 theta_combined_xor_values[4] =
bitwise.xor_op(theta_xor_values[3][3], theta_xor_row_rotl1_values[0]);
183 for (
size_t idx = 0; idx + 1 < 25; idx += 2) {
184 const size_t i0 = idx / 5;
185 const size_t j0 = idx % 5;
186 const size_t i1 = (idx + 1) / 5;
187 const size_t j1 = (idx + 1) % 5;
188 auto [c0, c1] =
bitwise.simd_xor_op_64(state_input_values[i0][j0],
189 theta_combined_xor_values[i0],
190 state_input_values[i1][j1],
191 theta_combined_xor_values[i1]);
192 state_theta_values[i0][j0] = c0;
193 state_theta_values[i1][j1] = c1;
195 state_theta_values[4][4] =
bitwise.xor_op(state_input_values[4][4], theta_combined_xor_values[4]);
204 for (
size_t i = 0; i < 5; ++i) {
205 for (
size_t j = 0; j < 5; ++j) {
208 state_rho_values[i][j] = unconstrained_rotate_left(state_theta_values[i][j],
len);
209 if (
len > 0 &&
len <= 32) {
210 range_check.assert_range(state_theta_values[i][j].as<uint64_t>() >> (64 -
len),
len);
211 }
else if (
len > 32) {
212 range_check.assert_range(state_theta_values[i][j].as<uint64_t>() & ((1ULL << (64 -
len)) - 1),
222 for (
size_t i = 0; i < 5; ++i) {
223 for (
size_t j = 0; j < 5; ++j) {
225 state_pi_not_values[i][j] = ~state_pi_values[i][j];
234 for (
size_t idx = 0; idx + 1 < 25; idx += 2) {
235 const size_t i0 = idx / 5;
236 const size_t j0 = idx % 5;
237 const size_t i1 = (idx + 1) / 5;
238 const size_t j1 = (idx + 1) % 5;
239 auto [c0, c1] =
bitwise.simd_and_op_64(state_pi_not_values[(i0 + 1) % 5][j0],
240 state_pi_values[(i0 + 2) % 5][j0],
241 state_pi_not_values[(i1 + 1) % 5][j1],
242 state_pi_values[(i1 + 2) % 5][j1]);
243 state_pi_and_values[i0][j0] = c0;
244 state_pi_and_values[i1][j1] = c1;
246 state_pi_and_values[4][4] =
247 bitwise.and_op(state_pi_not_values[(4 + 1) % 5][4], state_pi_values[(4 + 2) % 5][4]);
251 for (
size_t idx = 0; idx + 1 < 25; idx += 2) {
252 const size_t i0 = idx / 5;
253 const size_t j0 = idx % 5;
254 const size_t i1 = (idx + 1) / 5;
255 const size_t j1 = (idx + 1) % 5;
256 auto [c0, c1] =
bitwise.simd_xor_op_64(state_pi_values[i0][j0],
257 state_pi_and_values[i0][j0],
258 state_pi_values[i1][j1],
259 state_pi_and_values[i1][j1]);
260 state_chi_values[i0][j0] = c0;
261 state_chi_values[i1][j1] = c1;
263 state_chi_values[4][4] =
bitwise.xor_op(state_pi_values[4][4], state_pi_and_values[4][4]);
270 rounds_data[round_idx] = {
271 .state = two_dim_array_to_uint64(state_input_values),
272 .theta_xor = two_dim_array_to_uint64(theta_xor_values),
273 .theta_xor_row_rotl1 = array_to_uint64(theta_xor_row_rotl1_values),
274 .theta_combined_xor = array_to_uint64(theta_combined_xor_values),
275 .state_theta = two_dim_array_to_uint64(state_theta_values),
276 .state_rho = two_dim_array_to_uint64(state_rho_values),
277 .state_pi_not = two_dim_array_to_uint64(state_pi_not_values),
278 .state_pi_and = two_dim_array_to_uint64(state_pi_and_values),
279 .state_chi = two_dim_array_to_uint64(state_chi_values),
280 .state_iota_00 = iota_00_value.
as<uint64_t>(),
283 state_input_values = state_chi_values;
284 state_input_values[0][0] = iota_00_value;
288 for (
size_t i = 0; i < 5; i++) {
289 for (
size_t j = 0; j < 5; j++) {
294 keccakf1600_event.
rounds = rounds_data;