use crate::{BigInteger, FftField, Field};
use ark_std::{cmp::min, str::FromStr};
use num_bigint::BigUint;
pub trait PrimeField:
Field<BasePrimeField = Self>
+ FftField
+ FromStr
+ From<<Self as PrimeField>::BigInt>
+ Into<<Self as PrimeField>::BigInt>
+ From<BigUint>
+ Into<BigUint>
{
type BigInt: BigInteger;
const MODULUS: Self::BigInt;
const MODULUS_MINUS_ONE_DIV_TWO: Self::BigInt;
const MODULUS_BIT_SIZE: u32;
const TRACE: Self::BigInt;
const TRACE_MINUS_ONE_DIV_TWO: Self::BigInt;
fn from_bigint(repr: Self::BigInt) -> Option<Self>;
fn into_bigint(self) -> Self::BigInt;
fn from_be_bytes_mod_order(bytes: &[u8]) -> Self {
let mut bytes_copy = bytes.to_vec();
bytes_copy.reverse();
Self::from_le_bytes_mod_order(&bytes_copy)
}
fn from_le_bytes_mod_order(bytes: &[u8]) -> Self {
let num_modulus_bytes = ((Self::MODULUS_BIT_SIZE + 7) / 8) as usize;
let num_bytes_to_directly_convert = min(num_modulus_bytes - 1, bytes.len());
let (bytes, bytes_to_directly_convert) =
bytes.split_at(bytes.len() - num_bytes_to_directly_convert);
let mut res = Self::from_random_bytes(&bytes_to_directly_convert).unwrap();
let window_size = Self::from(256u64);
for byte in bytes.iter().rev() {
res *= window_size;
res += Self::from(*byte);
}
res
}
}