use super::binary::BinaryRepr;
use super::finite_field::{FiniteField, Residue};
use super::goldilocks::Goldilocks;
use super::mersenne31::Mersenne31;
use super::{Field, is_prime, private};
pub trait PrimeField: Field + private::PrimeFieldSeal {}
impl<const P: u64> private::PrimeFieldSeal for FiniteField<P, 1, Residue> {}
impl<const P: u64> PrimeField for FiniteField<P, 1, Residue> {}
impl private::PrimeFieldSeal for Mersenne31 {}
impl PrimeField for Mersenne31 {}
impl private::PrimeFieldSeal for Goldilocks {}
impl PrimeField for Goldilocks {}
impl<R: BinaryRepr<1>> private::PrimeFieldSeal for FiniteField<2, 1, R> {}
impl<R: BinaryRepr<1>> PrimeField for FiniteField<2, 1, R> {}
#[must_use]
pub const fn reduce<const P: u64>(value: u64) -> u64 {
assert!(is_prime(P), "characteristic is not prime");
value % P
}
#[must_use]
#[allow(clippy::cast_possible_truncation, clippy::cast_lossless)]
pub const fn reduce_wide<const P: u64>(value: u128) -> u64 {
assert!(is_prime(P), "characteristic is not prime");
(value % P as u128) as u64
}