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 rings.
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 ring implementing `Algebra<F>`.
10//!
11//! This file implements the generic methods from which Poseidon2 can be built.
12
13use p3_field::{Algebra, Field, InjectiveMonomial, PrimeCharacteristicRing};
14
15use crate::{MDSMat4, mds_light_permutation};
16
17/// A generic method performing the transformation:
18///
19/// `s -> (s + rc)^D`
20///
21/// This is a little slower than field specific implementations (particularly for packed fields) so should
22/// only be used in non performance critical places.
23#[inline(always)]
24pub fn add_rc_and_sbox_generic<F: Field, A: Algebra<F> + InjectiveMonomial<D>, const D: u64>(
25    val: &mut A,
26    rc: F,
27) {
28    *val += rc;
29    *val = val.injective_exp_n();
30}
31
32pub trait GenericPoseidon2LinearLayers<const WIDTH: usize>: Sync {
33    /// A generic implementation of the matrix multiplication
34    /// corresponding to the internal linear layer.
35    fn internal_linear_layer<R: PrimeCharacteristicRing>(state: &mut [R; WIDTH]);
36
37    /// A generic implementation of the matrix multiplication
38    /// corresponding to the external linear layer.
39    fn external_linear_layer<R: PrimeCharacteristicRing>(state: &mut [R; WIDTH]) {
40        mds_light_permutation(state, &MDSMat4);
41    }
42}