Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
poseidon2_permutation.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
8
10
12
13#include <array>
14#include <cstddef>
15#include <cstdint>
16
17namespace bb::crypto {
18
25template <typename Params> class Poseidon2Permutation {
26 public:
27 // t = sponge permutation size (in field elements)
28 // t = rate + capacity
29 // capacity = 1 field element (256 bits)
30 // rate = number of field elements that can be compressed per permutation
31 static constexpr size_t t = Params::t;
32 // d = degree of s-box polynomials. For a given field, `d` is the smallest element of `p` such that gdc(d, p - 1) =
33 // 1 (excluding 1) For bn254/grumpkin, d = 5
34 static constexpr size_t d = Params::d;
35 // sbox size = number of bits in p
36 static constexpr size_t sbox_size = Params::sbox_size;
37 // number of full sbox rounds
38 static constexpr size_t rounds_f = Params::rounds_f;
39 // number of partial sbox rounds
40 static constexpr size_t rounds_p = Params::rounds_p;
41 static constexpr size_t NUM_ROUNDS = Params::rounds_f + Params::rounds_p;
42
43 using FF = typename Params::FF;
44 using State = std::array<FF, t>;
45 using RoundConstants = std::array<FF, t>;
46 using MatrixDiagonal = std::array<FF, t>;
48
51
52 static constexpr void matrix_multiplication_4x4(State& input)
53 {
65 auto t0 = input[0] + input[1]; // A + B
66 auto t1 = input[2] + input[3]; // C + D
67 auto t2 = input[1] + input[1]; // 2B
68 t2 += t1; // 2B + C + D
69 auto t3 = input[3] + input[3]; // 2D
70 t3 += t0; // 2D + A + B
71 auto t4 = t1 + t1;
72 t4 += t4;
73 t4 += t3; // A + B + 4C + 6D
74 auto t5 = t0 + t0;
75 t5 += t5;
76 t5 += t2; // 4A + 6B + C + D
77 auto t6 = t3 + t5; // 5A + 7B + C + 3D
78 auto t7 = t2 + t4; // A + 3B + 5C + 7D
79 input[0] = t6;
80 input[1] = t5;
81 input[2] = t7;
82 input[3] = t4;
83 }
84
85 static constexpr void add_round_constants(State& input, const RoundConstants& rc)
86 {
87 for (size_t i = 0; i < t; ++i) {
88 input[i] += rc[i];
89 }
90 }
91
92 static constexpr void matrix_multiplication_internal(State& input)
93 {
94 // for t = 4
95 auto sum = input[0];
96 for (size_t i = 1; i < t; ++i) {
97 sum += input[i];
98 }
99 for (size_t i = 0; i < t; ++i) {
100 input[i] *= internal_matrix_diagonal[i];
101 input[i] += sum;
102 }
103 }
104
105 static constexpr void matrix_multiplication_external(State& input)
106 {
107 if constexpr (t == 4) {
109 } else {
110 // erm panic
111 throw_or_abort("not supported");
112 }
113 }
114
115 static constexpr void apply_single_sbox(FF& input)
116 {
117 // hardcoded assumption that d = 5. should fix this or not make d configurable
118 auto xx = input.sqr();
119 auto xxxx = xx.sqr();
120 input *= xxxx;
121 }
122
123 static constexpr void apply_sbox(State& input)
124 {
125 for (auto& in : input) {
127 }
128 }
129
137 static constexpr State permutation(const State& input)
138 {
139 // deep copy
140 State current_state(input);
141
142 // Apply 1st linear layer
143 matrix_multiplication_external(current_state);
144
145 // First set of external rounds
146 constexpr size_t rounds_f_beginning = rounds_f / 2;
147 for (size_t i = 0; i < rounds_f_beginning; ++i) {
148 add_round_constants(current_state, round_constants[i]);
149 apply_sbox(current_state);
150 matrix_multiplication_external(current_state);
151 }
152
153 // Internal rounds
154 const size_t p_end = rounds_f_beginning + rounds_p;
155 for (size_t i = rounds_f_beginning; i < p_end; ++i) {
156 current_state[0] += round_constants[i][0];
157 apply_single_sbox(current_state[0]);
158 matrix_multiplication_internal(current_state);
159 }
160
161 // Remaining external rounds
162 for (size_t i = p_end; i < NUM_ROUNDS; ++i) {
163 add_round_constants(current_state, round_constants[i]);
164 apply_sbox(current_state);
165 matrix_multiplication_external(current_state);
166 }
167 return current_state;
168 }
169};
170} // namespace bb::crypto
Applies the Poseidon2 permutation function from https://eprint.iacr.org/2023/323 ....
static constexpr State permutation(const State &input)
Native form of Poseidon2 permutation from https://eprint.iacr.org/2023/323.
static constexpr void matrix_multiplication_4x4(State &input)
static constexpr void apply_single_sbox(FF &input)
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 MatrixDiagonal internal_matrix_diagonal
std::array< RoundConstants, NUM_ROUNDS > RoundConstantsContainer
static constexpr RoundConstantsContainer round_constants
Inner sum(Cont< Inner, Args... > const &in)
Definition container.hpp:70
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static constexpr std::array< FF, t > internal_matrix_diagonal
static constexpr std::array< std::array< FF, t >, rounds_f+rounds_p > round_constants
void throw_or_abort(std::string const &err)