rescue_poseidon 0.32.11

Sponge construction based Algebraic Hash Functions
use franklin_crypto::bellman::Engine;

#[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum HashFamily {
    Rescue,
    Poseidon,
    RescuePrime,
    Poseidon2,
}

#[derive(Copy, Clone, Debug, serde::Serialize, serde::Deserialize)]
pub enum CustomGate {
    QuinticWidth4,
    QuinticWidth3,
    None,
}

#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum Step {
    Double { index: usize },
    Add { left: usize, right: usize },
}

#[derive(Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum Sbox {
    Alpha(u64),
    AlphaInverse(Vec<u64>, u64),
    AddChain(Vec<Step>, u64),
}

impl From<addchain::Step> for Step {
    fn from(value: addchain::Step) -> Self {
        match value {
            addchain::Step::Add { left, right } => Step::Add { left, right },
            addchain::Step::Double { index } => Step::Double { index },
        }
    }
}

impl std::fmt::Debug for Sbox {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Alpha(alpha) => write!(f, "sbox x^{}", alpha),
            Self::AlphaInverse(vec, alpha) => {
                write!(f, "inverse sbox [u64; {}] for x^{}", vec.len(), alpha)
            }
            Self::AddChain(_, alpha) => write!(f, "add chain inverse sbox for x^{}", alpha),
        }
    }
}

pub trait HashParams<E: Engine, const RATE: usize, const WIDTH: usize>: Clone + Send + Sync + serde::Serialize + serde::de::DeserializeOwned {
    #[inline]
    fn allows_specialization(&self) -> bool {
        false
    }
    fn hash_family(&self) -> HashFamily;
    fn constants_of_round(&self, round: usize) -> &[E::Fr; WIDTH];
    fn mds_matrix(&self) -> &[[E::Fr; WIDTH]; WIDTH];
    fn number_of_full_rounds(&self) -> usize;
    fn number_of_partial_rounds(&self) -> usize;
    fn alpha(&self) -> &Sbox;
    fn alpha_inv(&self) -> &Sbox;
    fn optimized_round_constants(&self) -> &[[E::Fr; WIDTH]];
    fn optimized_mds_matrixes(&self) -> (&[[E::Fr; WIDTH]; WIDTH], &[[[E::Fr; WIDTH]; WIDTH]]);
    fn custom_gate(&self) -> CustomGate;
    fn use_custom_gate(&mut self, gate: CustomGate);
    fn specialized_affine_transformation_for_round(&self, _state: &mut [E::Fr; WIDTH], _round_constants: &[E::Fr; WIDTH]) {
        unimplemented!("not implemented by default");
    }

    fn try_to_poseidon2_params(&self) -> Option<&crate::poseidon2::Poseidon2Params<E, RATE, WIDTH>> {
        None
    }
}