13template <
typename Builder>
17 State current_state(input);
18 NativeState current_native_state;
19 for (
size_t i = 0; i < t; ++i) {
20 current_native_state[i] = current_state[i].get_value();
24 NativePermutation::matrix_multiplication_external(current_native_state);
25 matrix_multiplication_external(current_state);
28 constexpr size_t rounds_f_beginning = rounds_f / 2;
29 for (
size_t i = 0; i < rounds_f_beginning; ++i) {
30 poseidon2_external_gate_<FF> in{ current_state[0].get_witness_index(),
31 current_state[1].get_witness_index(),
32 current_state[2].get_witness_index(),
33 current_state[3].get_witness_index(),
35 builder->create_poseidon2_external_gate(in);
37 NativePermutation::add_round_constants(current_native_state, round_constants[i]);
38 NativePermutation::apply_sbox(current_native_state);
39 NativePermutation::matrix_multiplication_external(current_native_state);
40 for (
size_t j = 0; j < t; ++j) {
45 propagate_current_state_to_next_row(
builder, current_state,
builder->blocks.poseidon2_external);
48 const size_t p_end = rounds_f_beginning + rounds_p;
49 for (
size_t i = rounds_f_beginning; i < p_end; ++i) {
50 poseidon2_internal_gate_<FF> in{ current_state[0].get_witness_index(),
51 current_state[1].get_witness_index(),
52 current_state[2].get_witness_index(),
53 current_state[3].get_witness_index(),
55 builder->create_poseidon2_internal_gate(in);
57 NativePermutation::apply_single_sbox(current_native_state[0]);
58 NativePermutation::matrix_multiplication_internal(current_native_state);
59 for (
size_t j = 0; j < t; ++j) {
64 propagate_current_state_to_next_row(
builder, current_state,
builder->blocks.poseidon2_internal);
67 for (
size_t i = p_end; i < NUM_ROUNDS; ++i) {
68 poseidon2_external_gate_<FF> in{ current_state[0].get_witness_index(),
69 current_state[1].get_witness_index(),
70 current_state[2].get_witness_index(),
71 current_state[3].get_witness_index(),
73 builder->create_poseidon2_external_gate(in);
75 NativePermutation::add_round_constants(current_native_state, round_constants[i]);
76 NativePermutation::apply_sbox(current_native_state);
77 NativePermutation::matrix_multiplication_external(current_native_state);
78 for (
size_t j = 0; j < t; ++j) {
83 propagate_current_state_to_next_row(
builder, current_state,
builder->blocks.poseidon2_external);
93template <
typename Builder>
106 state[1] = tmp2.
add_two(state[0] * four, state[1] * four);
109 state[0] = state[1] + tmp1;
112 state[3] = tmp1.
add_two(state[2] * four, state[3] * four);
115 state[2] = state[3] + tmp2;
118 ASSERT(state[0].is_normalized() && state[1].is_normalized() && state[2].is_normalized() &&
119 state[3].is_normalized());
122template class Poseidon2Permutation<MegaCircuitBuilder>;
123template class Poseidon2Permutation<UltraCircuitBuilder>;
#define ASSERT(expression,...)
static void matrix_multiplication_external(State &state)
In-circuit method to efficiently multiply the inital state by the external matrix ....
std::array< field_t< Builder >, t > State
static State permutation(Builder *builder, const State &input)
Circuit form of Poseidon2 permutation from https://eprint.iacr.org/2023/323.
field_t add_two(const field_t &add_b, const field_t &add_c) const
Efficiently compute (this + a + b) using big_mul gate.
constexpr uint32_t round_constants[64]