//! This file was generated by running generate_params.py
//! Specification for rate 5 Poseidon using the BN256 curve.
//! Patterned after [halo2_gadgets::poseidon::primitives::P128Pow5T3]
use halo2_gadgets::poseidon::primitives::*;
use halo2_proofs::arithmetic::Field;
use halo2_proofs::halo2curves::bn256::Fr as Fp;

use super::poseidon_params;

/// The specification for the Poseidon hash function.
#[derive(Debug, Clone, Copy)]
pub struct PoseidonSpec;

/// Basically the number of columns allocated within the poseidon chip
pub const POSEIDON_WIDTH: usize = 2;
/// The number of full SBox rounds
pub const POSEIDON_RATE: usize = 1;

pub(crate) type Mds<Fp, const T: usize> = [[Fp; T]; T];

impl Spec<Fp, POSEIDON_WIDTH, POSEIDON_RATE> for PoseidonSpec {
    fn full_rounds() -> usize {
        8
    }

    fn partial_rounds() -> usize {
        56
    }

    fn sbox(val: Fp) -> Fp {
        val.pow_vartime([5])
    }

    fn secure_mds() -> usize {
        unimplemented!()
    }

    fn constants() -> (
        Vec<[Fp; POSEIDON_WIDTH]>,
        Mds<Fp, POSEIDON_WIDTH>,
        Mds<Fp, POSEIDON_WIDTH>,
    ) {
        (
            poseidon_params::ROUND_CONSTANTS[..].to_vec(),
            poseidon_params::MDS,
            poseidon_params::MDS_INV,
        )
    }
}
