Skip to content

Commit 0524294

Browse files
committed
add more tests and comments
1 parent 50651e1 commit 0524294

File tree

2 files changed

+103
-4
lines changed

2 files changed

+103
-4
lines changed

src/field/gf_101_2.rs

+94-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ impl<F: FiniteField> QuadraticExtensionField<F> {
2727
const D: usize = 2;
2828

2929
/// irreducible polynomial used to reduce field polynomials to second degree:
30-
/// F[X]/(X^2-K)
30+
/// F[X]/(X^2-2)
3131
fn irreducible() -> F { F::from_canonical_u32(2) }
3232
}
3333

@@ -56,8 +56,22 @@ impl<F: FiniteField> FiniteField for QuadraticExtensionField<F> {
5656

5757
fn neg_one() -> Self { Self { value: [F::neg_one(), F::zero()] } }
5858

59-
fn generator() -> Self { Self { value: [F::from_canonical_u32(15), F::from_canonical_u32(20)] } }
59+
// field generator: can be verified using sage script
60+
// ```sage
61+
// F = GF(101)
62+
// Ft.<t> = F[]
63+
// P = Ft(t ^ 2 - 2)
64+
// F_2 = GF(101 ^ 2, name="t", modulus=P)
65+
// f_2_primitive_element = F_2.primitive_element()
66+
// ```
67+
fn generator() -> Self {
68+
// TODO: unsure if this is correct or not, research more
69+
Self { value: [F::from_canonical_u32(15), F::from_canonical_u32(20)] }
70+
}
6071

72+
/// Computes the multiplicative inverse of `a`, i.e. 1 / (a0 + a1 * t).
73+
/// Multiply by `a0 - a1 * t` in numerator and denominator.
74+
/// Denominator equals `(a0 + a1 * t) * (a0 - a1 * t) = a0.pow(2) - a1.pow(2) * Q::residue()`
6175
fn inverse(&self) -> Option<Self> {
6276
if *self == Self::zero() {
6377
return None;
@@ -109,6 +123,20 @@ impl<F: FiniteField> AddAssign for QuadraticExtensionField<F> {
109123
fn add_assign(&mut self, rhs: Self) { *self = self.clone() + rhs; }
110124
}
111125

126+
impl<F: FiniteField> Add<F> for QuadraticExtensionField<F> {
127+
type Output = Self;
128+
129+
fn add(self, rhs: F) -> Self::Output {
130+
let mut res = self;
131+
res.value[0] += rhs;
132+
res
133+
}
134+
}
135+
136+
impl<F: FiniteField> AddAssign<F> for QuadraticExtensionField<F> {
137+
fn add_assign(&mut self, rhs: F) { *self = *self + rhs; }
138+
}
139+
112140
impl<F: FiniteField> Sub for QuadraticExtensionField<F> {
113141
type Output = Self;
114142

@@ -126,6 +154,20 @@ impl<F: FiniteField> SubAssign for QuadraticExtensionField<F> {
126154
fn sub_assign(&mut self, rhs: Self) { *self = self.clone() - rhs; }
127155
}
128156

157+
impl<F: FiniteField> Sub<F> for QuadraticExtensionField<F> {
158+
type Output = Self;
159+
160+
fn sub(self, rhs: F) -> Self::Output {
161+
let mut res = self;
162+
res.value[0] -= rhs;
163+
res
164+
}
165+
}
166+
167+
impl<F: FiniteField> SubAssign<F> for QuadraticExtensionField<F> {
168+
fn sub_assign(&mut self, rhs: F) { *self = *self - rhs; }
169+
}
170+
129171
impl<F: FiniteField> Sum for QuadraticExtensionField<F> {
130172
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
131173
iter.reduce(|x, y| x + y).unwrap_or(Self::zero())
@@ -141,6 +183,8 @@ impl<F: FiniteField> Product for QuadraticExtensionField<F> {
141183
impl<F: FiniteField> Mul for QuadraticExtensionField<F> {
142184
type Output = Self;
143185

186+
/// Returns the multiplication of `a` and `b` using the following equation:
187+
/// (a0 + a1 * t) * (b0 + b1 * t) = a0 * b0 + a1 * b1 * irreducible() + (a0 * b1 + a1 * b0) * t
144188
fn mul(self, rhs: Self) -> Self::Output {
145189
let a = self.value;
146190
let b = rhs.value;
@@ -155,6 +199,21 @@ impl<F: FiniteField> MulAssign for QuadraticExtensionField<F> {
155199
fn mul_assign(&mut self, rhs: Self) { *self = *self * rhs; }
156200
}
157201

202+
impl<F: FiniteField> Mul<F> for QuadraticExtensionField<F> {
203+
type Output = Self;
204+
205+
fn mul(self, rhs: F) -> Self::Output {
206+
let mut res = self;
207+
res.value[0] *= rhs;
208+
res.value[1] *= rhs;
209+
res
210+
}
211+
}
212+
213+
impl<F: FiniteField> MulAssign<F> for QuadraticExtensionField<F> {
214+
fn mul_assign(&mut self, rhs: F) { *self = *self * rhs; }
215+
}
216+
158217
impl<F: FiniteField> Div for QuadraticExtensionField<F> {
159218
type Output = Self;
160219

@@ -224,6 +283,17 @@ mod tests {
224283
assert_eq!(x + y + z + x + y + z, [x, x, y, y, z, z].iter().cloned().sum());
225284
}
226285

286+
#[test]
287+
fn test_pow() {
288+
let mut rng = rand::thread_rng();
289+
let x = F2::from_base(rng.gen::<F>());
290+
291+
assert_eq!(x, x.pow(<F2 as FiniteField>::Storage::from(1_u32)));
292+
293+
let res = x.pow(<F2 as FiniteField>::Storage::from(4_u32));
294+
assert_eq!(res, x.square().square());
295+
}
296+
227297
#[test]
228298
fn test_inv_div() {
229299
let mut rng = rand::thread_rng();
@@ -240,4 +310,26 @@ mod tests {
240310
assert_eq!(x / (y * z), (x / y) / z);
241311
assert_eq!((x * y) / z, x * (y / z));
242312
}
313+
314+
#[test]
315+
fn test_generator() {
316+
assert_eq!(F2::generator() * F::from_canonical_u32(F::ORDER), F2::zero());
317+
}
318+
319+
#[test]
320+
fn test_add_sub_mul_subfield() {
321+
let mut rng = rand::thread_rng();
322+
let x = F2::from_base(rng.gen::<F>());
323+
let y = rng.gen::<F>();
324+
325+
let add1 = x + y;
326+
let sub1 = x - y;
327+
let res = x * F::two();
328+
assert_eq!(add1 + sub1, res);
329+
330+
let mul1 = x * y;
331+
let inv_mul = x * y.inverse().unwrap();
332+
let res = x.square();
333+
assert_eq!(mul1 * inv_mul, res);
334+
}
243335
}

src/field/mod.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,15 @@ pub trait FiniteField:
7070
}
7171
}
7272

73-
/// A Finite field extension trait
74-
pub trait ExtensionField<Base: FiniteField>: FiniteField + From<Base> {
73+
pub trait ExtensionField<Base: FiniteField>:
74+
FiniteField
75+
+ From<Base>
76+
+ Add<Base, Output = Self>
77+
+ AddAssign<Base>
78+
+ Sub<Base, Output = Self>
79+
+ SubAssign<Base>
80+
+ Mul<Base, Output = Self>
81+
+ MulAssign<Base> {
7582
const D: usize;
7683
fn irreducible() -> Base;
7784
fn from_base(b: Base) -> Self;

0 commit comments

Comments
 (0)