37 size_t input_size = input.size();
39 auto num_perm_events = (input_size / 3) +
static_cast<size_t>(input_size % 3 != 0);
42 intermediate_states.reserve(num_perm_events + 1);
47 std::array<FF, 4> perm_state = { 0, 0, 0, iv };
48 intermediate_states.push_back(perm_state);
50 for (
size_t i = 0; i < num_perm_events; i++) {
52 size_t chunk_size = std::min(input_size,
static_cast<size_t>(3));
54 for (
size_t j = 0; j < chunk_size; j++) {
55 perm_state[j] += input[(i * 3) + j];
58 intermediate_states.push_back(perm_state);
60 input_size -= chunk_size;
64 { .inputs = input, .intermediate_states =
std::move(intermediate_states), .output = perm_state[0] });
95 const auto space_id =
memory.get_space_id();
105 uint64_t max_read_address =
static_cast<uint64_t
>(
src_address) + 3;
106 uint64_t max_write_address =
static_cast<uint64_t
>(
dst_address) + 3;
111 if (read_out_of_range || write_out_of_range) {
112 throw InternalPoseidon2Exception(
"src or dst address out of range");
116 for (uint32_t i = 0; i < 4; i++) {
122 if (std::ranges::any_of(
123 input.begin(), input.end(), [](
const MemoryValue& val) { return val.get_tag() != MemoryTag::FF; })) {
124 throw InternalPoseidon2Exception(
"An input tag is not FF");
136 for (uint32_t i = 0; i < 4; i++) {
140 .execution_clk = execution_clk,
146 }
catch (
const InternalPoseidon2Exception& e) {
148 .execution_clk = execution_clk,
152 .output = { 0, 0, 0, 0 } });