p3_poseidon2/
generic.rs

1//! Whilst high speed implementations of Poseidon2 rely on a detailed understanding of the underlying field structure
2//! it is also useful to have a generic constructor which works for a much larger range of fields.
3//!
4//! Indeed, for a fixed field F, the Poseidon2 permutation consists of three basic operations:
5//! - Addition by elements in F.
6//! - A power map x -> x^n.
7//! - Multiplication by an F valued matrix.
8//!
9//! This means that it is possible to define a Poseidon2 over any abstract field FA which has implementations of:
10//! - Add<F, Output = FA>
11//! - Mul<F, Output = FA>
12//!
13//! This file implements the two matrix multiplications methods from which Poseidon2 can be built.
14
15use p3_field::FieldAlgebra;
16
17use crate::{mds_light_permutation, MDSMat4};
18
19/// A generic method performing the transformation:
20///
21/// `s -> (s + rc)^D`
22///
23/// This is a little slower than field specific implementations (particularly for packed fields) so should
24/// only be used in non performance critical places.
25#[inline(always)]
26pub fn add_rc_and_sbox_generic<FA: FieldAlgebra, const D: u64>(val: &mut FA, rc: FA::F) {
27    *val += FA::from_f(rc);
28    *val = val.exp_const_u64::<D>();
29}
30
31pub trait GenericPoseidon2LinearLayers<FA: FieldAlgebra, const WIDTH: usize>: Sync {
32    /// A generic implementation of the internal linear layer.
33    fn internal_linear_layer(state: &mut [FA; WIDTH]);
34
35    /// A generic implementation of the external linear layer.
36    fn external_linear_layer(state: &mut [FA; WIDTH]) {
37        mds_light_permutation(state, &MDSMat4);
38    }
39}