use gridiron::fp_256::Fp256;
use internal::fp2elem::Fp2Elem;
use internal::fp6elem::Fp6Elem;
use internal::Square;
use num_traits::{Inv, Pow};
use num_traits::{One, Zero};
use std::ops::{Add, Div, Mul, Neg, Sub};
pub trait Field:
One
+ Zero
+ Copy
+ Eq
+ Square
+ Neg<Output = Self>
+ Add<Output = Self>
+ Mul<Output = Self>
+ Div<Output = Self>
+ Mul<u64, Output = Self>
+ Inv<Output = Self>
+ Pow<u64, Output = Self>
+ Sub<Output = Self>
{
fn prop_semigroup(a: Self, b: Self, c: Self) -> bool {
a + (b + c) == (a + b) + c
}
fn prop_monoid_identity(a: Self) -> bool {
a + Zero::zero() == <Self as Zero>::zero() + a && a + Zero::zero() == a
}
fn prop_inv(a: Self, b: Self) -> bool {
a == a * (b.inv() * b) && a == a * (b * b.inv())
}
fn prop_one_is_mul_identity(a: Self) -> bool {
<Self as One>::one() * a == a && a == a * <Self as One>::one()
}
fn prop_zero_is_add_identity(a: Self) -> bool {
<Self as Zero>::zero() + a == a && a == a + <Self as Zero>::zero()
}
fn prop_eq_reflexive(a: Self, b: Self) -> bool {
if a == b {
b == a
} else {
b != a
}
}
fn prop_sub_same_as_neg_add(a: Self, b: Self) -> bool {
a + -b == a - b
}
fn prop_mul_distributive(a: Self, b: Self, c: Self) -> bool {
a * (b + c) == a * b + a * c
}
fn prop_mul_assoc(a: Self, b: Self, c: Self) -> bool {
a * (b * c) == a * b * c
}
fn prop_mul_commutative(a: Self, b: Self, c: Self) -> bool {
b * a * c == a * b * c
}
fn prop_add_assoc(a: Self, b: Self, c: Self) -> bool {
a + (b + c) == a + b + c
}
fn prop_add_commutative(a: Self, b: Self, c: Self) -> bool {
b + a + c == a + b + c
}
fn prop_pow_is_mul(a: Self) -> bool {
a * a == a.pow(2) && a * a * a == a.pow(3)
}
fn prop_x_sub_y_eq_x_plus_y_mul_neg1(x: Self, y: Self) -> bool {
let expected = x - y;
let result = x + y * -<Self as One>::one();
expected == result
}
fn prop_square_same_as_mul_self(a: Self) -> bool {
let expected = a * a;
let result = a.square();
expected == result
}
fn prop_square2_same_as_pow4(a: Self) -> bool {
let expected = a.square().square();
let result = a.pow(4);
expected == result
}
}
impl Field for Fp256 {}
pub trait ExtensionField
where
Self: Sized,
{
fn xi() -> Fp2Elem<Self>;
fn frobenius_factor_1() -> Fp2Elem<Self>;
fn frobenius_factor_2() -> Fp2Elem<Self>;
fn frobenius_factor_fp12() -> Fp2Elem<Self>;
fn v() -> Fp6Elem<Self>;
}
impl ExtensionField for Fp256 {
fn xi() -> Fp2Elem<Self> {
Fp2Elem {
elem1: Self::one(),
elem2: Self::from(3),
}
}
fn frobenius_factor_1() -> Fp2Elem<Self> {
Fp2Elem {
elem1: Fp256::new([
10152034302813700371,
5910894795777456359,
14398057480029393543,
4157656819842861741,
]),
elem2: Fp256::new([
9835675280104486275,
9619923852149600437,
2532242589814639790,
2538033321941726048,
]),
}
}
fn frobenius_factor_2() -> Fp2Elem<Self> {
Fp2Elem {
elem1: Fp256::new([
5336372648656334014,
6941289609049853728,
9236154747144999992,
3167884188894353858,
]),
elem2: Fp256::new([
3495480140663869659,
1714212734068687130,
3842326168498000073,
3448346194462013600,
]),
}
}
fn frobenius_factor_fp12() -> Fp2Elem<Self> {
Fp2Elem {
elem1: Fp256::new([
6172816157978064364,
15531380640859193161,
4208214814791383088,
1381111911921189058,
]),
elem2: Fp256::new([
5433908856227636904,
332129275666774768,
11468426909293708658,
3185871405125745500,
]),
}
}
fn v() -> Fp6Elem<Self> {
Fp6Elem {
elem1: Zero::zero(),
elem2: One::one(),
elem3: Zero::zero(),
}
}
}