use alloc::vec::Vec;
use core::{
fmt::{Debug, Display},
ops::{
Add, AddAssign, BitAnd, Div, DivAssign, Mul, MulAssign, Neg, Shl, Shr, ShrAssign, Sub,
SubAssign,
},
};
use utils::{AsBytes, Deserializable, DeserializationError, Randomizable, Serializable};
pub trait FieldElement:
Copy
+ Clone
+ Debug
+ Display
+ Default
+ Send
+ Sync
+ Eq
+ PartialEq
+ Sized
+ Add<Self, Output = Self>
+ Sub<Self, Output = Self>
+ Mul<Self, Output = Self>
+ Div<Self, Output = Self>
+ AddAssign<Self>
+ SubAssign<Self>
+ MulAssign<Self>
+ DivAssign<Self>
+ Neg<Output = Self>
+ From<u32>
+ From<u16>
+ From<u8>
+ TryFrom<u64>
+ TryFrom<u128>
+ for<'a> TryFrom<&'a [u8]>
+ ExtensionOf<<Self as FieldElement>::BaseField>
+ AsBytes
+ Randomizable
+ Serializable
+ Deserializable
{
type PositiveInteger: Debug
+ Copy
+ PartialEq
+ PartialOrd
+ ShrAssign
+ Shl<u32, Output = Self::PositiveInteger>
+ Shr<u32, Output = Self::PositiveInteger>
+ BitAnd<Output = Self::PositiveInteger>
+ From<u32>
+ From<u64>;
type BaseField: StarkField;
const EXTENSION_DEGREE: usize;
const ELEMENT_BYTES: usize;
const IS_CANONICAL: bool;
const ZERO: Self;
const ONE: Self;
#[inline]
#[must_use]
fn double(self) -> Self {
self + self
}
#[inline]
#[must_use]
fn square(self) -> Self {
self * self
}
#[inline]
#[must_use]
fn cube(self) -> Self {
self * self * self
}
#[must_use]
fn exp(self, power: Self::PositiveInteger) -> Self {
self.exp_vartime(power)
}
#[must_use]
fn exp_vartime(self, power: Self::PositiveInteger) -> Self {
let mut r = Self::ONE;
let mut b = self;
let mut p = power;
let int_zero = Self::PositiveInteger::from(0u32);
let int_one = Self::PositiveInteger::from(1u32);
if p == int_zero {
return Self::ONE;
} else if b == Self::ZERO {
return Self::ZERO;
}
while p > int_zero {
if p & int_one == int_one {
r *= b;
}
p >>= int_one;
b = b.square();
}
r
}
#[must_use]
fn inv(self) -> Self;
#[must_use]
fn conjugate(&self) -> Self;
fn base_element(&self, i: usize) -> Self::BaseField;
fn slice_as_base_elements(elements: &[Self]) -> &[Self::BaseField];
fn slice_from_base_elements(elements: &[Self::BaseField]) -> &[Self];
fn elements_as_bytes(elements: &[Self]) -> &[u8];
unsafe fn bytes_as_elements(bytes: &[u8]) -> Result<&[Self], DeserializationError>;
}
pub trait StarkField: FieldElement<BaseField = Self> {
const MODULUS: Self::PositiveInteger;
const MODULUS_BITS: u32;
const GENERATOR: Self;
const TWO_ADICITY: u32;
const TWO_ADIC_ROOT_OF_UNITY: Self;
fn get_modulus_le_bytes() -> Vec<u8>;
fn as_int(&self) -> Self::PositiveInteger;
fn get_root_of_unity(n: u32) -> Self {
assert!(n != 0, "cannot get root of unity for n = 0");
assert!(n <= Self::TWO_ADICITY, "order cannot exceed 2^{}", Self::TWO_ADICITY);
let power = Self::PositiveInteger::from(1u32) << (Self::TWO_ADICITY - n);
Self::TWO_ADIC_ROOT_OF_UNITY.exp(power)
}
fn from_bytes_with_padding(bytes: &[u8]) -> Self {
assert!(bytes.len() < Self::ELEMENT_BYTES);
let mut buf = bytes.to_vec();
buf.resize(Self::ELEMENT_BYTES, 0);
let element = match Self::try_from(buf.as_slice()) {
Ok(element) => element,
Err(_) => panic!("element deserialization failed"),
};
element
}
}
pub trait ExtensibleField<const N: usize>: StarkField {
fn mul(a: [Self; N], b: [Self; N]) -> [Self; N];
fn square(a: [Self; N]) -> [Self; N] {
<Self as ExtensibleField<N>>::mul(a, a)
}
fn mul_base(a: [Self; N], b: Self) -> [Self; N];
fn frobenius(x: [Self; N]) -> [Self; N];
fn is_supported() -> bool {
true
}
}
pub trait ExtensionOf<E: FieldElement>: From<E> {
fn mul_base(self, other: E) -> Self;
}
impl<E: FieldElement> ExtensionOf<E> for E {
#[inline(always)]
fn mul_base(self, other: E) -> Self {
self * other
}
}
pub trait ToElements<E: FieldElement> {
fn to_elements(&self) -> Vec<E>;
}
impl<E: FieldElement> ToElements<E> for () {
fn to_elements(&self) -> Vec<E> {
Vec::new()
}
}
impl<E: FieldElement> ToElements<E> for E {
fn to_elements(&self) -> Vec<E> {
vec![*self]
}
}