use p3_field::PrimeField64;
use p3_util::relatively_prime_u64;
const FULL_ROUNDS_128: usize = 8;
pub const fn poseidon2_round_numbers_128<F: PrimeField64>(
width: usize,
d: u64,
) -> Result<(usize, usize), &'static str> {
if !relatively_prime_u64(d, F::ORDER_U64 - 1) {
return Err("Invalid permutation: gcd(d, F::ORDER_U64 - 1) must be 1");
}
let prime_bit_number = F::ORDER_U64.ilog2() + 1;
match prime_bit_number {
31 => match (width, d) {
(16, 3) => Ok((FULL_ROUNDS_128, 20)),
(16, 5) => Ok((FULL_ROUNDS_128, 14)),
(16, 7) => Ok((FULL_ROUNDS_128, 13)),
(16, 9) => Ok((FULL_ROUNDS_128, 13)),
(16, 11) => Ok((FULL_ROUNDS_128, 13)),
(24, 3) => Ok((FULL_ROUNDS_128, 23)),
(24, 5) => Ok((FULL_ROUNDS_128, 22)),
(24, 7) => Ok((FULL_ROUNDS_128, 21)),
(24, 9) => Ok((FULL_ROUNDS_128, 21)),
(24, 11) => Ok((FULL_ROUNDS_128, 21)),
(32, 3) => Ok((FULL_ROUNDS_128, 31)),
(32, 5) => Ok((FULL_ROUNDS_128, 30)),
(32, 7) => Ok((FULL_ROUNDS_128, 30)),
(32, 9) => Ok((FULL_ROUNDS_128, 30)),
(32, 11) => Ok((FULL_ROUNDS_128, 30)),
_ => Err("The given pair of width and D has not been checked for these fields"),
},
64 => match (width, d) {
(8, 3) => Ok((FULL_ROUNDS_128, 41)),
(8, 5) => Ok((FULL_ROUNDS_128, 27)),
(8, 7) => Ok((FULL_ROUNDS_128, 22)),
(8, 9) => Ok((FULL_ROUNDS_128, 19)),
(8, 11) => Ok((FULL_ROUNDS_128, 17)),
(12, 3) => Ok((FULL_ROUNDS_128, 42)),
(12, 5) => Ok((FULL_ROUNDS_128, 27)),
(12, 7) => Ok((FULL_ROUNDS_128, 22)),
(12, 9) => Ok((FULL_ROUNDS_128, 20)),
(12, 11) => Ok((FULL_ROUNDS_128, 18)),
(16, 3) => Ok((FULL_ROUNDS_128, 42)),
(16, 5) => Ok((FULL_ROUNDS_128, 27)),
(16, 7) => Ok((FULL_ROUNDS_128, 22)),
(16, 9) => Ok((FULL_ROUNDS_128, 20)),
(16, 11) => Ok((FULL_ROUNDS_128, 18)),
_ => Err("The given pair of width and D has not been checked for these fields"),
},
_ => Err("The optimal parameters for that size of prime have not been computed."),
}
}