23template <
typename Params,
typename Builder>
28 State current_state(input);
29 NativeState current_native_state;
30 for (
size_t i = 0; i < t; ++i) {
31 current_native_state[i] = current_state[i].get_value();
35 NativePermutation::matrix_multiplication_external(current_native_state);
36 matrix_multiplication_external(
builder, current_state);
39 constexpr size_t rounds_f_beginning = rounds_f / 2;
40 for (
size_t i = 0; i < rounds_f_beginning; ++i) {
41 poseidon2_external_gate_<FF> in{ current_state[0].witness_index,
42 current_state[1].witness_index,
43 current_state[2].witness_index,
44 current_state[3].witness_index,
46 builder->create_poseidon2_external_gate(in);
48 NativePermutation::add_round_constants(current_native_state, round_constants[i]);
49 NativePermutation::apply_sbox(current_native_state);
50 NativePermutation::matrix_multiplication_external(current_native_state);
51 for (
size_t j = 0; j < t; ++j) {
59 current_state[0].witness_index,
60 current_state[1].witness_index,
61 current_state[2].witness_index,
62 current_state[3].witness_index);
65 const size_t p_end = rounds_f_beginning + rounds_p;
66 for (
size_t i = rounds_f_beginning; i < p_end; ++i) {
67 poseidon2_internal_gate_<FF> in{ current_state[0].witness_index,
68 current_state[1].witness_index,
69 current_state[2].witness_index,
70 current_state[3].witness_index,
72 builder->create_poseidon2_internal_gate(in);
74 NativePermutation::apply_single_sbox(current_native_state[0]);
75 NativePermutation::matrix_multiplication_internal(current_native_state);
76 for (
size_t j = 0; j < t; ++j) {
84 current_state[0].witness_index,
85 current_state[1].witness_index,
86 current_state[2].witness_index,
87 current_state[3].witness_index);
90 for (
size_t i = p_end; i < NUM_ROUNDS; ++i) {
91 poseidon2_external_gate_<FF> in{ current_state[0].witness_index,
92 current_state[1].witness_index,
93 current_state[2].witness_index,
94 current_state[3].witness_index,
96 builder->create_poseidon2_external_gate(in);
98 NativePermutation::add_round_constants(current_native_state, round_constants[i]);
99 NativePermutation::apply_sbox(current_native_state);
100 NativePermutation::matrix_multiplication_external(current_native_state);
101 for (
size_t j = 0; j < t; ++j) {
110 current_state[0].witness_index,
111 current_state[1].witness_index,
112 current_state[2].witness_index,
113 current_state[3].witness_index);
114 return current_state;
130template <
typename Params,
typename Builder>
139 .a = state[0].witness_index,
140 .b = state[1].witness_index,
141 .c = state[3].witness_index,
154 .a = state[1].witness_index,
155 .b = state[2].witness_index,
156 .c = state[3].witness_index,
169 .a = state[0].witness_index,
170 .b = state[1].witness_index,
199 .b = state[2].witness_index,
200 .c = state[3].witness_index,
229template class Poseidon2Permutation<crypto::Poseidon2Bn254ScalarFieldParams, MegaCircuitBuilder>;
230template class Poseidon2Permutation<crypto::Poseidon2Bn254ScalarFieldParams, UltraCircuitBuilder>;
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.
static void matrix_multiplication_external(Builder *builder, State &state)
Separate function to do just the first linear layer (equivalent to external matrix mul).
bb::fr get_value() const
Given a := *this, compute its value given by a.v * a.mul + a.add.
constexpr uint32_t round_constants[64]
Value get_value(int64_t keyCount, int64_t valueCount)