Remaining extension field tower

This commit is contained in:
Sean Bowe
2016-07-03 10:16:51 -06:00
parent 17416ed162
commit c8a0d56ba4
7 changed files with 412 additions and 13 deletions
-6
View File
@@ -51,12 +51,6 @@ impl<P: PrimeFieldParams> Field for Fp<P> {
}
}
fn is_zero(&self) -> bool {
use num::Zero;
self.value == BigUint::zero()
}
fn inverse(&self) -> Self {
if self.is_zero() {
// TODO: this should likely bleed through the abstraction layers
+127
View File
@@ -0,0 +1,127 @@
use ::Fq2;
use ::Fq6;
use rand::Rng;
use fields::Field;
use std::ops::{Mul,Add,Sub,Neg};
use std::cmp::{PartialEq, Eq};
use std::marker::PhantomData;
use std::fmt;
pub trait Fp12Params {
fn non_residue() -> Fq2;
fn name() -> &'static str;
}
pub struct Fp12<P: Fp12Params> {
a: Fq6,
b: Fq6,
_marker: PhantomData<P>
}
impl<P: Fp12Params> Fp12<P> {
pub fn new(a: Fq6, b: Fq6) -> Self {
Fp12 {
a: a,
b: b,
_marker: PhantomData
}
}
}
impl<P: Fp12Params> fmt::Debug for Fp12<P> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}({:?}, {:?})", P::name(), self.a, self.b)
}
}
impl<P: Fp12Params> Clone for Fp12<P> {
fn clone(&self) -> Self {
Fp12 {
a: self.a.clone(),
b: self.b.clone(),
_marker: PhantomData
}
}
}
impl<P: Fp12Params> Field for Fp12<P> {
fn zero() -> Self {
Fp12 {
a: Fq6::zero(),
b: Fq6::zero(),
_marker: PhantomData
}
}
fn one() -> Self {
Fp12 {
a: Fq6::one(),
b: Fq6::zero(),
_marker: PhantomData
}
}
fn random<R: Rng>(rng: &mut R) -> Self {
Fp12 {
a: Fq6::random(rng),
b: Fq6::random(rng),
_marker: PhantomData
}
}
fn inverse(&self) -> Self {
let t = (self.a.squared() - (self.b.squared().mul_by_nonresidue(&P::non_residue()))).inverse();
Fp12 {
a: &self.a * &t,
b: -(&self.b * &t),
_marker: PhantomData
}
}
fn squared(&self) -> Self {
let a = &self.a; let b = &self.b;
let ab = &(a * b);
Fp12 {
a: (b.mul_by_nonresidue(&P::non_residue()) + a) * (a + b) - ab - ab.mul_by_nonresidue(&P::non_residue()),
b: ab + ab,
_marker: PhantomData
}
}
fn eq(&self, other: &Self) -> bool {
self.a == other.a && self.b == other.b
}
fn neg(&self) -> Self {
Fp12 {
a: -(&self.a),
b: -(&self.b),
_marker: PhantomData
}
}
fn mul(&self, other: &Self) -> Self {
let a_a = &(&self.a * &other.a);
let b_b = &(&self.b * &other.b);
Fp12 {
a: b_b.mul_by_nonresidue(&P::non_residue()) + a_a,
b: (&self.a + &self.b) * (&other.a + &other.b) - a_a - b_b,
_marker: PhantomData
}
}
fn sub(&self, other: &Self) -> Self {
Fp12 {
a: &self.a - &other.a,
b: &self.b - &other.b,
_marker: PhantomData
}
}
fn add(&self, other: &Self) -> Self {
Fp12 {
a: &self.a + &other.a,
b: &self.b + &other.b,
_marker: PhantomData
}
}
}
forward_ops_to_field_ops!(impl(P: Fp12Params) Fp12<P>);
+1 -4
View File
@@ -1,6 +1,5 @@
use ::Fq;
use rand::Rng;
use fields::fp::PrimeFieldParams;
use fields::Field;
use std::ops::{Mul,Add,Sub,Neg};
use std::cmp::{PartialEq, Eq};
@@ -66,9 +65,7 @@ impl<P: Fp2Params> Field for Fp2<P> {
_marker: PhantomData
}
}
fn is_zero(&self) -> bool {
self == &Self::zero()
}
fn inverse(&self) -> Self {
let t = (self.a.squared() - (self.b.squared() * P::non_residue())).inverse();
+147
View File
@@ -0,0 +1,147 @@
use ::Fq2;
use rand::Rng;
use fields::Field;
use std::ops::{Mul,Add,Sub,Neg};
use std::cmp::{PartialEq, Eq};
use std::marker::PhantomData;
use std::fmt;
pub trait Fp6Params {
fn non_residue() -> Fq2;
fn name() -> &'static str;
}
pub struct Fp6<P: Fp6Params> {
a: Fq2,
b: Fq2,
c: Fq2,
_marker: PhantomData<P>
}
impl<P: Fp6Params> Fp6<P> {
pub fn new(a: Fq2, b: Fq2, c: Fq2) -> Self {
Fp6 {
a: a,
b: b,
c: c,
_marker: PhantomData
}
}
}
impl<P: Fp6Params> fmt::Debug for Fp6<P> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}({:?}, {:?}, {:?})", P::name(), self.a, self.b, self.c)
}
}
impl<P: Fp6Params> Clone for Fp6<P> {
fn clone(&self) -> Self {
Fp6 {
a: self.a.clone(),
b: self.b.clone(),
c: self.c.clone(),
_marker: PhantomData
}
}
}
impl<P: Fp6Params> Field for Fp6<P> {
fn zero() -> Self {
Fp6 {
a: Fq2::zero(),
b: Fq2::zero(),
c: Fq2::zero(),
_marker: PhantomData
}
}
fn one() -> Self {
Fp6 {
a: Fq2::one(),
b: Fq2::zero(),
c: Fq2::zero(),
_marker: PhantomData
}
}
fn random<R: Rng>(rng: &mut R) -> Self {
Fp6 {
a: Fq2::random(rng),
b: Fq2::random(rng),
c: Fq2::random(rng),
_marker: PhantomData
}
}
fn inverse(&self) -> Self {
let c0 = self.a.squared() - &self.b * &self.c * P::non_residue();
let c1 = self.c.squared() * P::non_residue() - &self.a * &self.b;
let c2 = self.b.squared() - &self.a * &self.c;
let t = ((&self.c * &c1 + &self.b * &c2) * P::non_residue() + &self.a * &c0).inverse();
Fp6 {
a: &t * &c0,
b: &t * &c1,
c: &t * &c2,
_marker: PhantomData
}
}
fn eq(&self, other: &Self) -> bool {
self.a == other.a && self.b == other.b && self.c == other.c
}
fn neg(&self) -> Self {
Fp6 {
a: -(&self.a),
b: -(&self.b),
c: -(&self.c),
_marker: PhantomData
}
}
fn mul(&self, other: &Self) -> Self {
let a_a = &self.a * &other.a;
let b_b = &self.b * &other.b;
let c_c = &self.c * &other.c;
Fp6 {
a: ((&self.b + &self.c) * (&other.b + &other.c) - &b_b - &c_c) * P::non_residue() + &a_a,
b: (&self.a + &self.b) * (&other.a + &other.b) - &a_a - &b_b + &c_c * P::non_residue(),
c: (&self.a + &self.c) * (&other.a + &other.c) - &a_a + &b_b - &c_c,
_marker: PhantomData
}
}
fn sub(&self, other: &Self) -> Self {
Fp6 {
a: &self.a - &other.a,
b: &self.b - &other.b,
c: &self.c - &other.c,
_marker: PhantomData
}
}
fn add(&self, other: &Self) -> Self {
Fp6 {
a: &self.a + &other.a,
b: &self.b + &other.b,
c: &self.c + &other.c,
_marker: PhantomData
}
}
}
impl<P: Fp6Params> Fp6<P> {
pub fn mul_by_nonresidue(&self, other: &Fq2) -> Fp6<P> {
Fp6 {
a: &self.c * other,
b: self.a.clone(),
c: self.b.clone(),
_marker: PhantomData
}
}
}
forward_ops_to_field_ops!(impl(P: Fp6Params) Fp6<P>);
+5 -1
View File
@@ -3,6 +3,8 @@ mod macros;
pub mod fp;
pub mod fp2;
pub mod fp6;
pub mod fp12;
#[cfg(test)]
pub mod tests;
@@ -15,7 +17,9 @@ pub trait Field: Sized + Clone + Debug {
fn zero() -> Self;
fn one() -> Self;
fn random<R: Rng>(rng: &mut R) -> Self;
fn is_zero(&self) -> bool;
fn is_zero(&self) -> bool {
self.eq(&Self::zero())
}
fn inverse(&self) -> Self;
fn squared(&self) -> Self {
self.mul(self)