8#include "barretenberg/aztec/aztec_constants.hpp"
27 { C::poseidon2_perm_T_0_6, C::poseidon2_perm_T_0_5, C::poseidon2_perm_T_0_7, C::poseidon2_perm_T_0_4 },
28 { C::poseidon2_perm_T_1_6, C::poseidon2_perm_T_1_5, C::poseidon2_perm_T_1_7, C::poseidon2_perm_T_1_4 },
29 { C::poseidon2_perm_T_2_6, C::poseidon2_perm_T_2_5, C::poseidon2_perm_T_2_7, C::poseidon2_perm_T_2_4 },
30 { C::poseidon2_perm_T_3_6, C::poseidon2_perm_T_3_5, C::poseidon2_perm_T_3_7, C::poseidon2_perm_T_3_4 },
34 { C::poseidon2_perm_T_60_6, C::poseidon2_perm_T_60_5, C::poseidon2_perm_T_60_7, C::poseidon2_perm_T_60_4 },
35 { C::poseidon2_perm_T_61_6, C::poseidon2_perm_T_61_5, C::poseidon2_perm_T_61_7, C::poseidon2_perm_T_61_4 },
36 { C::poseidon2_perm_T_62_6, C::poseidon2_perm_T_62_5, C::poseidon2_perm_T_62_7, C::poseidon2_perm_T_62_4 },
37 { C::poseidon2_perm_T_63_6, C::poseidon2_perm_T_63_5, C::poseidon2_perm_T_63_7, C::poseidon2_perm_T_63_4 },
43 C::poseidon2_perm_B_4_0, C::poseidon2_perm_B_5_0, C::poseidon2_perm_B_6_0, C::poseidon2_perm_B_7_0,
44 C::poseidon2_perm_B_8_0, C::poseidon2_perm_B_9_0, C::poseidon2_perm_B_10_0, C::poseidon2_perm_B_11_0,
45 C::poseidon2_perm_B_12_0, C::poseidon2_perm_B_13_0, C::poseidon2_perm_B_14_0, C::poseidon2_perm_B_15_0,
46 C::poseidon2_perm_B_16_0, C::poseidon2_perm_B_17_0, C::poseidon2_perm_B_18_0, C::poseidon2_perm_B_19_0,
47 C::poseidon2_perm_B_20_0, C::poseidon2_perm_B_21_0, C::poseidon2_perm_B_22_0, C::poseidon2_perm_B_23_0,
48 C::poseidon2_perm_B_24_0, C::poseidon2_perm_B_25_0, C::poseidon2_perm_B_26_0, C::poseidon2_perm_B_27_0,
49 C::poseidon2_perm_B_28_0, C::poseidon2_perm_B_29_0, C::poseidon2_perm_B_30_0, C::poseidon2_perm_B_31_0,
50 C::poseidon2_perm_B_32_0, C::poseidon2_perm_B_33_0, C::poseidon2_perm_B_34_0, C::poseidon2_perm_B_35_0,
51 C::poseidon2_perm_B_36_0, C::poseidon2_perm_B_37_0, C::poseidon2_perm_B_38_0, C::poseidon2_perm_B_39_0,
52 C::poseidon2_perm_B_40_0, C::poseidon2_perm_B_41_0, C::poseidon2_perm_B_42_0, C::poseidon2_perm_B_43_0,
53 C::poseidon2_perm_B_44_0, C::poseidon2_perm_B_45_0, C::poseidon2_perm_B_46_0, C::poseidon2_perm_B_47_0,
54 C::poseidon2_perm_B_48_0, C::poseidon2_perm_B_49_0, C::poseidon2_perm_B_50_0, C::poseidon2_perm_B_51_0,
55 C::poseidon2_perm_B_52_0, C::poseidon2_perm_B_53_0, C::poseidon2_perm_B_54_0, C::poseidon2_perm_B_55_0,
56 C::poseidon2_perm_B_56_0, C::poseidon2_perm_B_57_0, C::poseidon2_perm_B_58_0, C::poseidon2_perm_B_59_0,
73 for (
const auto&
event : hash_events) {
74 auto input_size =
event.inputs.size();
76 const auto num_perm_events =
event.intermediate_states.size() - 1;
80 const auto padding_size = (2 * input_size) % 3;
82 for (
size_t i = 0; i < num_perm_events; i++) {
83 std::array<FF, 3> perm_input = { 0, 0, 0 };
84 auto perm_state =
event.intermediate_states[i];
85 const auto& perm_output =
event.intermediate_states[i + 1];
86 size_t chunk_size = std::min(input_size,
static_cast<size_t>(3));
88 for (
size_t j = 0; j < chunk_size; j++) {
90 perm_input[j] =
event.inputs[(i * 3) + j];
92 perm_state[j] += perm_input[j];
96 { C::poseidon2_hash_sel, 1 },
97 { C::poseidon2_hash_start, i == 0 ? 1 : 0 },
98 { C::poseidon2_hash_end, i == (num_perm_events - 1) ? 1 : 0 },
99 { C::poseidon2_hash_input_len,
event.inputs.size() },
100 { C::poseidon2_hash_padding, padding_size },
101 { C::poseidon2_hash_input_0, perm_input[0] },
102 { C::poseidon2_hash_input_1, perm_input[1] },
103 { C::poseidon2_hash_input_2, perm_input[2] },
105 { C::poseidon2_hash_num_perm_rounds_rem, num_perm_events - i },
106 { C::poseidon2_hash_num_perm_rounds_rem_min_one_inv,
107 num_perm_events - i - 1 },
109 { C::poseidon2_hash_a_0, perm_state[0] },
110 { C::poseidon2_hash_a_1, perm_state[1] },
111 { C::poseidon2_hash_a_2, perm_state[2] },
112 { C::poseidon2_hash_a_3, perm_state[3] },
114 { C::poseidon2_hash_b_0, perm_output[0] },
115 { C::poseidon2_hash_b_1, perm_output[1] },
116 { C::poseidon2_hash_b_2, perm_output[2] },
117 { C::poseidon2_hash_b_3, perm_output[3] },
118 { C::poseidon2_hash_output,
event.output },
120 input_size -= chunk_size;
125 trace.invert_columns({ { C::poseidon2_hash_num_perm_rounds_rem_min_one_inv } });
141 std::array<FF, 4> current_state;
145 for (
const auto&
event : perm_events) {
148 current_state =
event.input;
154 { C::poseidon2_perm_sel, 1 },
155 { C::poseidon2_perm_a_0,
event.input[0] },
156 { C::poseidon2_perm_a_1,
event.input[1] },
157 { C::poseidon2_perm_a_2,
event.input[2] },
158 { C::poseidon2_perm_a_3,
event.input[3] },
160 { C::poseidon2_perm_EXT_LAYER_6, current_state[0] },
161 { C::poseidon2_perm_EXT_LAYER_5, current_state[1] },
162 { C::poseidon2_perm_EXT_LAYER_7, current_state[2] },
163 { C::poseidon2_perm_EXT_LAYER_4, current_state[3] },
170 for (
size_t i = 0; i < rounds_f_beginning; ++i) {
174 const auto& cols = initial_full_round_cols[i];
176 { { { cols[0], current_state[0] },
177 { cols[1], current_state[1] },
178 { cols[2], current_state[2] },
179 { cols[3], current_state[3] } } });
185 for (
size_t i = rounds_f_beginning; i < p_end; ++i) {
189 const size_t partial_idx = i - rounds_f_beginning;
190 trace.set(row, { { { partial_round_cols[partial_idx], current_state[0] } } });
196 { { { C::poseidon2_perm_B_59_1, current_state[1] },
197 { C::poseidon2_perm_B_59_2, current_state[2] },
198 { C::poseidon2_perm_B_59_3, current_state[3] } } });
205 const auto& cols = final_full_round_cols[i - p_end];
207 { { { cols[0], current_state[0] },
208 { cols[1], current_state[1] },
209 { cols[2], current_state[2] },
210 { cols[3], current_state[3] } } });
215 { C::poseidon2_perm_b_0, current_state[0] },
216 { C::poseidon2_perm_b_1, current_state[1] },
217 { C::poseidon2_perm_b_2, current_state[2] },
218 { C::poseidon2_perm_b_3, current_state[3] },
245 for (
const auto&
event : perm_mem_events) {
247 const uint64_t
src_addr =
static_cast<uint64_t
>(
event.src_address);
248 const uint64_t
dst_addr =
static_cast<uint64_t
>(
event.dst_address);
252 const bool src_out_of_range_err =
src_addr + 3 > AVM_HIGHEST_MEM_ADDRESS;
253 const bool dst_out_of_range_err =
dst_addr + 3 > AVM_HIGHEST_MEM_ADDRESS;
254 const bool should_read_mem = !(src_out_of_range_err || dst_out_of_range_err);
258 std::ranges::any_of(
event.input, [](
const auto& input) { return input.get_tag() != MemoryTag::FF; });
260 FF batch_tag_inv = 0;
265 FF batched_tag_check = 0;
269 for (uint32_t i = 0; i <
event.input.size(); i++) {
270 uint32_t exponent = 3 * i;
271 uint32_t current_tag =
static_cast<uint32_t
>(
event.input[i].get_tag());
272 batched_tag_check += (
FF(current_tag) -
FF(target_tag)) *
FF((1 << exponent));
274 batch_tag_inv = batched_tag_check.invert();
277 const bool err = src_out_of_range_err || dst_out_of_range_err || invalid_tag;
281 { C::poseidon2_perm_mem_sel, 1 },
282 { C::poseidon2_perm_mem_execution_clk,
event.execution_clk },
283 { C::poseidon2_perm_mem_space_id,
event.space_id },
284 { C::poseidon2_perm_mem_max_mem_addr, AVM_HIGHEST_MEM_ADDRESS },
286 { C::poseidon2_perm_mem_sel_src_out_of_range_err, src_out_of_range_err ? 1 : 0 },
287 { C::poseidon2_perm_mem_sel_dst_out_of_range_err, dst_out_of_range_err ? 1 : 0 },
288 { C::poseidon2_perm_mem_sel_invalid_tag_err, invalid_tag ? 1 : 0 },
289 { C::poseidon2_perm_mem_batch_tag_inv, batch_tag_inv },
290 { C::poseidon2_perm_mem_err, err ? 1 : 0 },
292 { C::poseidon2_perm_mem_sel_should_read_mem, should_read_mem ? 1 : 0 },
294 { C::poseidon2_perm_mem_read_address_0_,
src_addr },
295 { C::poseidon2_perm_mem_read_address_1_,
src_addr + 1 },
296 { C::poseidon2_perm_mem_read_address_2_,
src_addr + 2 },
297 { C::poseidon2_perm_mem_read_address_3_,
src_addr + 3 },
299 { C::poseidon2_perm_mem_write_address_0_,
dst_addr },
300 { C::poseidon2_perm_mem_write_address_1_,
dst_addr + 1 },
301 { C::poseidon2_perm_mem_write_address_2_,
dst_addr + 2 },
302 { C::poseidon2_perm_mem_write_address_3_,
dst_addr + 3 },
304 { C::poseidon2_perm_mem_input_0_,
event.input[0].as_ff() },
305 { C::poseidon2_perm_mem_input_1_,
event.input[1].as_ff() },
306 { C::poseidon2_perm_mem_input_2_,
event.input[2].as_ff() },
307 { C::poseidon2_perm_mem_input_3_,
event.input[3].as_ff() },
309 { C::poseidon2_perm_mem_input_tag_0_,
static_cast<uint8_t
>(
event.input[0].get_tag()) },
310 { C::poseidon2_perm_mem_input_tag_1_,
static_cast<uint8_t
>(
event.input[1].get_tag()) },
311 { C::poseidon2_perm_mem_input_tag_2_,
static_cast<uint8_t
>(
event.input[2].get_tag()) },
312 { C::poseidon2_perm_mem_input_tag_3_,
static_cast<uint8_t
>(
event.input[3].get_tag()) },
314 { C::poseidon2_perm_mem_sel_should_exec, !err ? 1 : 0 },
315 { C::poseidon2_perm_mem_output_0_,
event.output[0] },
316 { C::poseidon2_perm_mem_output_1_,
event.output[1] },
317 { C::poseidon2_perm_mem_output_2_,
event.output[2] },
318 { C::poseidon2_perm_mem_output_3_,
event.output[3] },
328 .add<InteractionType::LookupSequential, lookup_poseidon2_mem_input_output_poseidon2_perm_settings>()
331 .add<InteractionType::LookupGeneric, lookup_poseidon2_mem_check_dst_addr_in_range_settings>(C::gt_sel);
std::vector< Event > Container
InteractionDefinition & add(auto &&... args)
static const InteractionDefinition interactions
void process_permutation(const simulation::EventEmitterInterface< simulation::Poseidon2PermutationEvent >::Container &perm_events, TraceContainer &trace)
Processes the permutation events for the Poseidon2 permutation function. It populates the columns for...
void process_permutation_with_memory(const simulation::EventEmitterInterface< simulation::Poseidon2PermutationMemoryEvent >::Container &perm_mem_events, TraceContainer &trace)
Processes the events for the Poseidon2 memory-aware permutation function. It populates the columns fo...
void process_hash(const simulation::EventEmitterInterface< simulation::Poseidon2HashEvent >::Container &hash_events, TraceContainer &trace)
Processes the hash events for the Poseidon2 hash function. It populates the columns for the poseidon2...
Applies the Poseidon2 permutation function from https://eprint.iacr.org/2023/323.
static constexpr size_t NUM_ROUNDS
static constexpr size_t rounds_f
static constexpr size_t rounds_p
static constexpr void apply_single_sbox(FF &input)
S-box: x -> x^5.
static constexpr void matrix_multiplication_internal(State &input)
static constexpr void matrix_multiplication_external(State &input)
static constexpr void add_round_constants(State &input, const RoundConstants &rc)
static constexpr void apply_sbox(State &input)
static constexpr RoundConstantsContainer round_constants
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
simulation::PublicDataTreeReadWriteEvent event
Settings to be passed ot GenericLookupRelationImpl.