use core::iter;
use crate::field::Field;
use crate::{Algebra, ExtensionField};
mod binomial_extension;
mod complex;
mod packed_binomial_extension;
mod packed_quintic_extension;
mod quintic_extension;
use alloc::vec::Vec;
pub use binomial_extension::*;
pub use complex::*;
pub use packed_binomial_extension::*;
pub use packed_quintic_extension::PackedQuinticTrinomialExtensionField;
pub use quintic_extension::{QuinticTrinomialExtensionField, trinomial_quintic_mul};
pub trait BinomiallyExtendable<const D: usize>:
Field + BinomiallyExtendableAlgebra<Self, D>
{
const W: Self;
const DTH_ROOT: Self;
const EXT_GENERATOR: [Self; D];
}
pub trait BinomiallyExtendableAlgebra<F: Field, const D: usize>: Algebra<F> {
#[inline]
fn binomial_mul(a: &[Self; D], b: &[Self; D], res: &mut [Self; D], w: F) {
binomial_mul::<F, Self, Self, D>(a, b, res, w);
}
#[inline]
#[must_use]
fn binomial_add(a: &[Self; D], b: &[Self; D]) -> [Self; D] {
vector_add(a, b)
}
#[inline]
#[must_use]
fn binomial_sub(a: &[Self; D], b: &[Self; D]) -> [Self; D] {
vector_sub(a, b)
}
#[inline]
fn binomial_base_mul(lhs: [Self; D], rhs: Self) -> [Self; D] {
lhs.map(|x| x * rhs.dup())
}
}
pub trait HasFrobenius<F: Field>: ExtensionField<F> {
#[must_use]
fn frobenius(&self) -> Self;
#[must_use]
fn repeated_frobenius(&self, count: usize) -> Self;
#[must_use]
fn pseudo_inv(&self) -> Self;
#[must_use]
fn galois_orbit(self) -> Vec<Self> {
iter::successors(Some(self), |x| Some(x.frobenius()))
.take(Self::DIMENSION)
.collect()
}
}
pub trait HasTwoAdicBinomialExtension<const D: usize>: BinomiallyExtendable<D> {
const EXT_TWO_ADICITY: usize;
#[must_use]
fn ext_two_adic_generator(bits: usize) -> [Self; D];
}
pub trait QuinticTrinomialExtendable: Field + QuinticExtendableAlgebra<Self> {
const FROBENIUS_COEFFS: [[Self; 5]; 4];
const EXT_GENERATOR: [Self; 5];
}
pub trait QuinticExtendableAlgebra<F: Field>: Algebra<F> {
#[inline]
fn quintic_mul(a: &[Self; 5], b: &[Self; 5], res: &mut [Self; 5]) {
quintic_extension::trinomial_quintic_mul(a, b, res);
}
#[inline]
fn quintic_square(a: &[Self; 5], res: &mut [Self; 5]) {
quintic_extension::quintic_square(a, res);
}
#[inline]
#[must_use]
fn quintic_add(a: &[Self; 5], b: &[Self; 5]) -> [Self; 5] {
vector_add(a, b)
}
#[inline]
#[must_use]
fn quintic_sub(a: &[Self; 5], b: &[Self; 5]) -> [Self; 5] {
vector_sub(a, b)
}
#[inline]
fn quintic_base_mul(lhs: [Self; 5], rhs: Self) -> [Self; 5] {
lhs.map(|x| x * rhs.dup())
}
}
pub trait HasTwoAdicQuinticExtension: QuinticTrinomialExtendable {
const EXT_TWO_ADICITY: usize;
#[must_use]
fn ext_two_adic_generator(bits: usize) -> [Self; 5];
}