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