barretenberg
Loading...
Searching...
No Matches
poseidon2_permutation.hpp
1#pragma once
2
3#include "poseidon2_params.hpp"
4
5#include "barretenberg/common/throw_or_abort.hpp"
6
7#include <array>
8#include <cstddef>
9#include <cstdint>
10#include <vector>
11
12namespace crypto {
13
20template <typename Params> class Poseidon2Permutation {
21 public:
22 // t = sponge permutation size (in field elements)
23 // t = rate + capacity
24 // capacity = 1 field element (256 bits)
25 // rate = number of field elements that can be compressed per permutation
26 static constexpr size_t t = Params::t;
27 // d = degree of s-box polynomials. For a given field, `d` is the smallest element of `p` such that gdc(d, p - 1) =
28 // 1 (excluding 1) For bn254/grumpkin, d = 5
29 static constexpr size_t d = Params::d;
30 // sbox size = number of bits in p
31 static constexpr size_t sbox_size = Params::sbox_size;
32 // number of full sbox rounds
33 static constexpr size_t rounds_f = Params::rounds_f;
34 // number of partial sbox rounds
35 static constexpr size_t rounds_p = Params::rounds_p;
36 static constexpr size_t NUM_ROUNDS = Params::rounds_f + Params::rounds_p;
37
38 using FF = typename Params::FF;
39 using State = std::array<FF, t>;
40 using RoundConstants = std::array<FF, t>;
41 using MatrixDiagonal = std::array<FF, t>;
42 using RoundConstantsContainer = std::array<RoundConstants, NUM_ROUNDS>;
43
44 static constexpr MatrixDiagonal internal_matrix_diagonal =
45 Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal;
46 static constexpr RoundConstantsContainer round_constants = Poseidon2Bn254ScalarFieldParams::round_constants;
47
48 static constexpr void matrix_multiplication_4x4(State& input)
49 {
61 auto t0 = input[0] + input[1]; // A + B
62 auto t1 = input[2] + input[3]; // C + D
63 auto t2 = input[1] + input[1]; // 2B
64 t2 += t1; // 2B + C + D
65 auto t3 = input[3] + input[3]; // 2D
66 t3 += t0; // 2D + A + B
67 auto t4 = t1 + t1;
68 t4 += t4;
69 t4 += t3; // A + B + 4C + 6D
70 auto t5 = t0 + t0;
71 t5 += t5;
72 t5 += t2; // 4A + 6B + C + D
73 auto t6 = t3 + t5; // 5A + 7B + C + 3D
74 auto t7 = t2 + t4; // A + 3B + 5C + 7D
75 input[0] = t6;
76 input[1] = t5;
77 input[2] = t7;
78 input[3] = t4;
79 }
80
81 static constexpr void add_round_constants(State& input, const RoundConstants& rc)
82 {
83 for (size_t i = 0; i < t; ++i) {
84 input[i] += rc[i];
85 }
86 }
87
88 static constexpr void matrix_multiplication_internal(State& input)
89 {
90 // for t = 4
91 auto sum = input[0];
92 for (size_t i = 1; i < t; ++i) {
93 sum += input[i];
94 }
95 for (size_t i = 0; i < t; ++i) {
96 input[i] *= internal_matrix_diagonal[i];
97 input[i] += sum;
98 }
99 }
100
101 static constexpr void matrix_multiplication_external(State& input)
102 {
103 if constexpr (t == 4) {
105 } else {
106 // erm panic
107 throw_or_abort("not supported");
108 }
109 }
110
111 static constexpr void apply_single_sbox(FF& input)
112 {
113 // hardcoded assumption that d = 5. should fix this or not make d configurable
114 auto xx = input.sqr();
115 auto xxxx = xx.sqr();
116 input *= xxxx;
117 }
118
119 static constexpr void apply_sbox(State& input)
120 {
121 for (auto& in : input) {
122 apply_single_sbox(in);
123 }
124 }
125
126 static constexpr State permutation(const State& input)
127 {
128 // deep copy
129 State current_state(input);
130
131 // Apply 1st linear layer
132 matrix_multiplication_external(current_state);
133
134 constexpr size_t rounds_f_beginning = rounds_f / 2;
135 for (size_t i = 0; i < rounds_f_beginning; ++i) {
136 add_round_constants(current_state, round_constants[i]);
137 apply_sbox(current_state);
138 matrix_multiplication_external(current_state);
139 }
140
141 const size_t p_end = rounds_f_beginning + rounds_p;
142 for (size_t i = rounds_f_beginning; i < p_end; ++i) {
143 current_state[0] += round_constants[i][0];
144 apply_single_sbox(current_state[0]);
145 matrix_multiplication_internal(current_state);
146 }
147
148 for (size_t i = p_end; i < NUM_ROUNDS; ++i) {
149 add_round_constants(current_state, round_constants[i]);
150 apply_sbox(current_state);
151 matrix_multiplication_external(current_state);
152 }
153 return current_state;
154 }
155};
156} // namespace crypto
Applies the Poseidon2 permutation function from https://eprint.iacr.org/2023/323 ....
Definition: poseidon2_permutation.hpp:20
static constexpr void matrix_multiplication_4x4(State &input)
Definition: poseidon2_permutation.hpp:48
Definition: aes128.cpp:9
BBERG_INLINE constexpr field sqr() const noexcept
Definition: field_impl.hpp:61