Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix mul, generator and add hardcoded tests #51

Merged
merged 2 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions math/field.sage
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ F_2 = GF(101 ^ 2, name="t", modulus=P)
print("extension field:", F_2, "of order:", F_2.order())

# Primitive element
f_2_primitive_element = F_2.primitive_element()
print("Primitive element of F_2:", f_2_primitive_element, f_2_primitive_element.order())
f_2_primitive_element = F_2([2, 1])
print("Primitive element of F_2:", f_2_primitive_element, f_2_primitive_element.multiplicative_order())

# 100th root of unity
F_2_order = F_2.order()
Expand All @@ -65,5 +65,4 @@ quotient = (F_2_order-1)//root_of_unity_order
f_2_omega_n = f_2_primitive_element ^ quotient
print("The", root_of_unity_order, "th root of unity of extension field is: ", f_2_omega_n)

######################################################################

######################################################################
50 changes: 34 additions & 16 deletions src/field/gf_101_2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,9 @@ impl<F: FiniteField> QuadraticPlutoField<F> {
/// F[X]/(X^2-2)
fn irreducible() -> F { F::from_canonical_u32(2) }

// const fn from_base(b: F) -> Self { Self { value: [b, F::zero()] } }
// const fn from_base(b: F) -> Self { Self { value: [b, F::zero()] } }

pub const fn new(a: F, b: F) -> Self {
Self { value: [a, b] }
}
pub const fn new(a: F, b: F) -> Self { Self { value: [a, b] } }
}

impl<F: FiniteField> ExtensionField<F> for QuadraticPlutoField<F> {
Expand All @@ -52,24 +50,26 @@ impl<F: FiniteField> From<F> for QuadraticPlutoField<F> {
impl<F: FiniteField> FiniteField for QuadraticPlutoField<F> {
type Storage = u32;

const NEG_ONE: Self = Self::new(F::NEG_ONE, F::ZERO);
// TODO: This is wrong
const ONE: Self = Self::new(F::ONE, F::ZERO);
0xJepsen marked this conversation as resolved.
Show resolved Hide resolved
const ORDER: Self::Storage = QUADRATIC_EXTENSION_FIELD_ORDER;
// fn zero() -> Self { Self { value: [F::zero(); EXT_DEGREE] } }
const ZERO: Self = Self::new(F::ZERO, F::TWO); // TODO: This is wrong
const ONE: Self = Self::new(F::ONE, F::ZERO);
const TWO: Self = Self::new(F::TWO, F::ZERO);
const NEG_ONE: Self = Self::new(F::NEG_ONE, F::ZERO);
// fn zero() -> Self { Self { value: [F::zero(); EXT_DEGREE] } }
const ZERO: Self = Self::new(F::ZERO, F::ZERO);

// field generator: can be verified using sage script
// ```sage
// F = GF(101)
// Ft.<t> = F[]
// P = Ft(t ^ 2 - 2)
// F_2 = GF(101 ^ 2, name="t", modulus=P)
// f_2_primitive_element = F_2.primitive_element()
// f_2_primitive_element = F_2([2, 1])
// assert f_2_primitive_element.multiplicative_order() == 101^2-1
// ```
fn generator() -> Self {
// TODO: unsure if this is correct or not, research more
Self { value: [F::from_canonical_u32(15), F::from_canonical_u32(20)] }
Self { value: [F::from_canonical_u32(2), F::from_canonical_u32(1)] }
}

/// Computes the multiplicative inverse of `a`, i.e. 1 / (a0 + a1 * t).
Expand Down Expand Up @@ -176,7 +176,7 @@ impl<F: FiniteField> Mul for QuadraticPlutoField<F> {
let a = self.value;
let b = rhs.value;
let mut res = Self::default();
res.value[0] = a[0].clone() * b[0].clone() + a[1].clone() * a[1].clone() * Self::irreducible();
res.value[0] = a[0].clone() * b[0].clone() + a[1].clone() * b[1].clone() * Self::irreducible();
res.value[1] = a[0].clone() * b[1].clone() + a[1].clone() * b[0].clone();
res
}
Expand Down Expand Up @@ -251,6 +251,27 @@ mod tests {
assert_eq!(x_2.value[1], F::new(0));
}

#[test]
fn test_add() {
let a = F2::new(F::new(10), F::new(20));
let b = F2::new(F::new(20), F::new(10));
assert_eq!(a + b, F2::new(F::new(30), F::new(30)));
}

#[test]
fn test_sub() {
let a = F2::new(F::new(10), F::new(20));
let b = F2::new(F::new(20), F::new(10));
assert_eq!(a - b, F2::new(F::new(91), F::new(10)));
}

#[test]
fn test_mul() {
let a = F2::new(F::new(10), F::new(20));
let b = F2::new(F::new(20), F::new(10));
assert_eq!(a * b, F2::new(F::new(95), F::new(96)));
}

#[test]
fn test_add_sub_neg_mul() {
let mut rng = rand::thread_rng();
Expand Down Expand Up @@ -289,10 +310,7 @@ mod tests {
let z = F2::from_base(rng.gen::<F>());
assert_eq!(x * x.inverse().unwrap(), F2::ONE);
assert_eq!(x.inverse().unwrap_or(F2::ONE) * x, F2::ONE);
assert_eq!(
x.square().inverse().unwrap_or(F2::ONE),
x.inverse().unwrap_or(F2::ONE).square()
);
assert_eq!(x.square().inverse().unwrap_or(F2::ONE), x.inverse().unwrap_or(F2::ONE).square());
assert_eq!((x / y) * y, x);
assert_eq!(x / (y * z), (x / y) / z);
assert_eq!((x * y) / z, x * (y / z));
Expand Down Expand Up @@ -322,7 +340,7 @@ mod tests {

#[test]
fn test_generator_order() {
let generator = F2::generator();
let generator = F2::ONE;
let mut x = generator;
for _ in 1..F2::ORDER {
x *= generator;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't correct right? We are just multiplying one together a bunch of times, this test would pass no matter what right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops lol yes, how did i miss this. fixed it now. Now, we're multiplying 1 by generator, order-1 times, which is the multiplicative order of the group defined by field.

Expand Down