1use ark_ff::Field;
2
3#[cfg(not(feature = "std"))]
4use alloc::vec::Vec;
5use unroll::unroll_for_loops;
6
7pub trait Sponge<F: Field> {
9 type Digest;
11
12 fn hash(bytes: &[u8]) -> Self::Digest;
14
15 fn hash_field(elems: &[F]) -> Self::Digest;
17
18 fn merge(digests: &[Self::Digest; 2]) -> Self::Digest;
20}
21
22pub trait Jive<F: Field> {
24 fn compress(elems: &[F]) -> Vec<F>;
28
29 fn compress_k(elems: &[F], k: usize) -> Vec<F>;
33}
34
35pub trait Anemoi<'a, F: Field> {
38 const NUM_COLUMNS: usize;
40 const NUM_ROUNDS: usize;
42
43 const WIDTH: usize;
46 const RATE: usize;
48 const OUTPUT_SIZE: usize;
50
51 const MDS: Option<&'a [F]> = None;
55 const ARK_C: &'a [F];
57 const ARK_D: &'a [F];
59
60 const GROUP_GENERATOR: u32;
63
64 const ALPHA: u32;
66 const INV_ALPHA: F;
68 const BETA: u32;
70 const DELTA: F;
72 const QUAD: u32 = 2;
75
76 fn mul_by_generator(x: &F) -> F {
79 match Self::GROUP_GENERATOR {
80 2 => x.double(),
81 3 => x.double() + x,
82 5 => x.double().double() + x,
83 7 => (x.double() + x).double() + x,
84 9 => x.double().double().double() + x,
85 11 => (x.double().double() + x).double() + x,
86 13 => ((x.double() + x).double() + x).double() + x,
87 15 => x.double().double().double().double() - x,
88 17 => x.double().double().double().double() + x,
89 _ => F::from(Self::GROUP_GENERATOR as u64) * x,
90 }
91 }
92
93 fn exp_by_alpha(x: F) -> F {
95 match Self::ALPHA {
96 3 => x.square() * x,
97 5 => x.square().square() * x,
98 7 => (x.square() * x).square() * x,
99 11 => (x.square().square() * x).square() * x,
100 13 => ((x.square() * x).square() * x).square() * x,
101 17 => x.square().square().square().square() * x,
102 _ => x.pow([Self::ALPHA as u64]),
103 }
104 }
105
106 fn exp_by_inv_alpha(x: F) -> F;
109
110 #[inline(always)]
112 #[unroll_for_loops]
113 fn ark_layer(state: &mut [F], round_ctr: usize) {
114 debug_assert!(state.len() == Self::WIDTH);
115 assert!(round_ctr < Self::NUM_ROUNDS);
116 let range = round_ctr * Self::NUM_COLUMNS..(round_ctr + 1) * Self::NUM_COLUMNS;
117
118 let c = &Self::ARK_C[range.clone()];
119 let d = &Self::ARK_D[range];
120
121 for i in 0..Self::NUM_COLUMNS {
122 state[i] += c[i];
123 state[Self::NUM_COLUMNS + i] += d[i];
124 }
125 }
126
127 #[inline(always)]
129 fn mds_layer(state: &mut [F]) {
130 debug_assert!(state.len() == Self::WIDTH);
131
132 match Self::NUM_COLUMNS {
136 1 => {
137 state[1] += state[0];
141 state[0] += state[1];
142 }
143 2 => {
144 state[0] += Self::mul_by_generator(&state[1]);
145 state[1] += Self::mul_by_generator(&state[0]);
146
147 state[3] += Self::mul_by_generator(&state[2]);
148 state[2] += Self::mul_by_generator(&state[3]);
149 state.swap(2, 3);
150
151 state[2] += state[0];
153 state[3] += state[1];
154
155 state[0] += state[2];
156 state[1] += state[3];
157 }
158 3 => {
159 Self::mds_internal(&mut state[..Self::NUM_COLUMNS]);
160 state[Self::NUM_COLUMNS..].rotate_left(1);
161 Self::mds_internal(&mut state[Self::NUM_COLUMNS..]);
162
163 state[3] += state[0];
165 state[4] += state[1];
166 state[5] += state[2];
167
168 state[0] += state[3];
169 state[1] += state[4];
170 state[2] += state[5];
171 }
172 4 => {
173 Self::mds_internal(&mut state[..Self::NUM_COLUMNS]);
174 state[Self::NUM_COLUMNS..].rotate_left(1);
175 Self::mds_internal(&mut state[Self::NUM_COLUMNS..]);
176
177 state[4] += state[0];
179 state[5] += state[1];
180 state[6] += state[2];
181 state[7] += state[3];
182
183 state[0] += state[4];
184 state[1] += state[5];
185 state[2] += state[6];
186 state[3] += state[7];
187 }
188 5 => {
189 let x = state[..Self::NUM_COLUMNS].to_vec();
190 let mut y = state[Self::NUM_COLUMNS..].to_vec();
191 y.rotate_left(1);
192
193 let sum_coeffs = x[0] + x[1] + x[2] + x[3] + x[4];
194 state[0] = sum_coeffs + x[3] + (x[2] + x[3] + x[4].double()).double();
195 state[1] = sum_coeffs + x[4] + (x[3] + x[4] + x[0].double()).double();
196 state[2] = sum_coeffs + x[0] + (x[4] + x[0] + x[1].double()).double();
197 state[3] = sum_coeffs + x[1] + (x[0] + x[1] + x[2].double()).double();
198 state[4] = sum_coeffs + x[2] + (x[1] + x[2] + x[3].double()).double();
199
200 let sum_coeffs = y[0] + y[1] + y[2] + y[3] + y[4];
201 state[5] = sum_coeffs + y[3] + (y[2] + y[3] + y[4].double()).double();
202 state[6] = sum_coeffs + y[4] + (y[3] + y[4] + y[0].double()).double();
203 state[7] = sum_coeffs + y[0] + (y[4] + y[0] + y[1].double()).double();
204 state[8] = sum_coeffs + y[1] + (y[0] + y[1] + y[2].double()).double();
205 state[9] = sum_coeffs + y[2] + (y[1] + y[2] + y[3].double()).double();
206
207 state[5] += state[0];
209 state[6] += state[1];
210 state[7] += state[2];
211 state[8] += state[3];
212 state[9] += state[4];
213
214 state[0] += state[5];
215 state[1] += state[6];
216 state[2] += state[7];
217 state[3] += state[8];
218 state[4] += state[9];
219 }
220 6 => {
221 let x = state[..Self::NUM_COLUMNS].to_vec();
222 let mut y = state[Self::NUM_COLUMNS..].to_vec();
223 y.rotate_left(1);
224
225 let sum_coeffs = x[0] + x[1] + x[2] + x[3] + x[4] + x[5];
226 state[0] =
227 sum_coeffs + x[3] + x[5] + (x[2] + x[3] + (x[4] + x[5]).double()).double();
228 state[1] =
229 sum_coeffs + x[4] + x[0] + (x[3] + x[4] + (x[5] + x[0]).double()).double();
230 state[2] =
231 sum_coeffs + x[5] + x[1] + (x[4] + x[5] + (x[0] + x[1]).double()).double();
232 state[3] =
233 sum_coeffs + x[0] + x[2] + (x[5] + x[0] + (x[1] + x[2]).double()).double();
234 state[4] =
235 sum_coeffs + x[1] + x[3] + (x[0] + x[1] + (x[2] + x[3]).double()).double();
236 state[5] =
237 sum_coeffs + x[2] + x[4] + (x[1] + x[2] + (x[3] + x[4]).double()).double();
238
239 let sum_coeffs = y[0] + y[1] + y[2] + y[3] + y[4] + y[5];
240 state[6] =
241 sum_coeffs + y[3] + y[5] + (y[2] + y[3] + (y[4] + y[5]).double()).double();
242 state[7] =
243 sum_coeffs + y[4] + y[0] + (y[3] + y[4] + (y[5] + y[0]).double()).double();
244 state[8] =
245 sum_coeffs + y[5] + y[1] + (y[4] + y[5] + (y[0] + y[1]).double()).double();
246 state[9] =
247 sum_coeffs + y[0] + y[2] + (y[5] + y[0] + (y[1] + y[2]).double()).double();
248 state[10] =
249 sum_coeffs + y[1] + y[3] + (y[0] + y[1] + (y[2] + y[3]).double()).double();
250 state[11] =
251 sum_coeffs + y[2] + y[4] + (y[1] + y[2] + (y[3] + y[4]).double()).double();
252
253 state[6] += state[0];
255 state[7] += state[1];
256 state[8] += state[2];
257 state[9] += state[3];
258 state[10] += state[4];
259 state[11] += state[5];
260
261 state[0] += state[6];
262 state[1] += state[7];
263 state[2] += state[8];
264 state[3] += state[9];
265 state[4] += state[10];
266 state[5] += state[11];
267 }
268 _ => {
269 let mds = Self::MDS.expect("NO MDS matrix specified for this instance.");
270 let mut result = vec![F::zero(); Self::WIDTH];
272 for (index, r) in result.iter_mut().enumerate().take(Self::NUM_COLUMNS) {
273 for j in 0..Self::NUM_COLUMNS {
274 *r += mds[index * Self::NUM_COLUMNS + j] * state[j];
275 }
276 }
277
278 state[Self::NUM_COLUMNS..].rotate_left(1);
279 for (index, r) in result.iter_mut().skip(Self::NUM_COLUMNS).enumerate() {
280 for j in 0..Self::NUM_COLUMNS {
281 *r += mds[index * Self::NUM_COLUMNS + j] * state[Self::NUM_COLUMNS + j];
282 }
283 }
284
285 for i in 0..Self::NUM_COLUMNS {
287 state[Self::NUM_COLUMNS + i] = result[i] + result[Self::NUM_COLUMNS + i];
288 }
289 for i in 0..Self::NUM_COLUMNS {
290 state[i] = result[i] + state[Self::NUM_COLUMNS + i];
291 }
292 }
293 }
294 }
295
296 #[inline(always)]
298 fn mds_internal(state: &mut [F]) {
299 debug_assert!(state.len() == Self::WIDTH);
300
301 match Self::NUM_COLUMNS {
302 3 => {
303 let tmp = state[0] + Self::mul_by_generator(&state[2]);
304 state[2] += state[1];
305 state[2] += Self::mul_by_generator(&state[0]);
306
307 state[0] = tmp + state[2];
308 state[1] += tmp;
309 }
310 4 => {
311 state[0] += state[1];
312 state[2] += state[3];
313 state[3] += Self::mul_by_generator(&state[0]);
314 state[1] = Self::mul_by_generator(&(state[1] + state[2]));
315
316 state[0] += state[1];
317 state[2] += Self::mul_by_generator(&state[3]);
318 state[1] += state[2];
319 state[3] += state[0];
320 }
321 _ => (),
322 }
323 }
324
325 #[inline(always)]
327 #[unroll_for_loops]
328 fn sbox_layer(state: &mut [F]) {
329 debug_assert!(state.len() == Self::WIDTH);
330
331 let mut x = state[..Self::NUM_COLUMNS].to_vec();
332 let mut y = state[Self::NUM_COLUMNS..].to_vec();
333
334 x.iter_mut().enumerate().for_each(|(i, t)| {
335 let y2 = y[i].square();
336 *t -= Self::mul_by_generator(&y2);
337 });
338
339 let mut x_alpha_inv = x.clone();
340 x_alpha_inv
341 .iter_mut()
342 .for_each(|t| *t = Self::exp_by_inv_alpha(*t));
343
344 y.iter_mut()
345 .enumerate()
346 .for_each(|(i, t)| *t -= x_alpha_inv[i]);
347
348 state
349 .iter_mut()
350 .enumerate()
351 .take(Self::NUM_COLUMNS)
352 .for_each(|(i, t)| {
353 let y2 = y[i].square();
354 *t = x[i] + Self::mul_by_generator(&y2) + Self::DELTA;
355 });
356
357 state[Self::NUM_COLUMNS..].copy_from_slice(&y);
358 }
359
360 fn round(state: &mut [F], round_ctr: usize) {
362 debug_assert!(state.len() == Self::WIDTH);
363
364 Self::ark_layer(state, round_ctr);
365 Self::mds_layer(state);
366 Self::sbox_layer(state);
367 }
368
369 fn permutation(state: &mut [F]) {
371 debug_assert!(state.len() == Self::WIDTH);
372
373 for i in 0..Self::NUM_ROUNDS {
374 Self::round(state, i);
375 }
376
377 Self::mds_layer(state)
378 }
379}