Curve instantiation on extension field
This commit is contained in:
parent
b277f0d1e3
commit
17416ed162
|
@ -82,25 +82,6 @@ impl<P: PrimeFieldParams> Field for Fp<P> {
|
|||
res
|
||||
}
|
||||
}
|
||||
|
||||
fn pow<P2: PrimeFieldParams>(&self, exp: &Fp<P2>) -> Self {
|
||||
let mut res = Self::one();
|
||||
|
||||
let mut found_one = false;
|
||||
|
||||
for i in (0..P2::bits()).rev() {
|
||||
if found_one {
|
||||
res = res.squared();
|
||||
}
|
||||
|
||||
if exp.test_bit(i) {
|
||||
found_one = true;
|
||||
res = res * self;
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn neg(&self) -> Self {
|
||||
use num::Zero;
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
use ::Fq;
|
||||
use rand::Rng;
|
||||
use fields::fp::PrimeFieldParams;
|
||||
use fields::Field;
|
||||
use std::ops::{Mul,Add,Sub,Neg};
|
||||
use std::cmp::{PartialEq, Eq};
|
||||
use std::marker::PhantomData;
|
||||
use std::fmt;
|
||||
|
||||
pub trait Fp2Params {
|
||||
fn non_residue() -> Fq;
|
||||
fn name() -> &'static str;
|
||||
}
|
||||
|
||||
pub struct Fp2<P: Fp2Params> {
|
||||
a: Fq,
|
||||
b: Fq,
|
||||
_marker: PhantomData<P>
|
||||
}
|
||||
|
||||
impl<P: Fp2Params> Fp2<P> {
|
||||
pub fn new(a: Fq, b: Fq) -> Self {
|
||||
Fp2 {
|
||||
a: a,
|
||||
b: b,
|
||||
_marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: Fp2Params> fmt::Debug for Fp2<P> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}({:?}, {:?})", P::name(), self.a, self.b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: Fp2Params> Clone for Fp2<P> {
|
||||
fn clone(&self) -> Self {
|
||||
Fp2 {
|
||||
a: self.a.clone(),
|
||||
b: self.b.clone(),
|
||||
_marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: Fp2Params> Field for Fp2<P> {
|
||||
fn zero() -> Self {
|
||||
Fp2 {
|
||||
a: Fq::zero(),
|
||||
b: Fq::zero(),
|
||||
_marker: PhantomData
|
||||
}
|
||||
}
|
||||
fn one() -> Self {
|
||||
Fp2 {
|
||||
a: Fq::one(),
|
||||
b: Fq::zero(),
|
||||
_marker: PhantomData
|
||||
}
|
||||
}
|
||||
fn random<R: Rng>(rng: &mut R) -> Self {
|
||||
Fp2 {
|
||||
a: Fq::random(rng),
|
||||
b: Fq::random(rng),
|
||||
_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();
|
||||
|
||||
Fp2 {
|
||||
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);
|
||||
|
||||
Fp2 {
|
||||
a: (b * P::non_residue() + a) * (a + b) - ab - ab * 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 {
|
||||
Fp2 {
|
||||
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);
|
||||
|
||||
Fp2 {
|
||||
a: b_b * 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 {
|
||||
Fp2 {
|
||||
a: &self.a - &other.a,
|
||||
b: &self.b - &other.b,
|
||||
_marker: PhantomData
|
||||
}
|
||||
}
|
||||
fn add(&self, other: &Self) -> Self {
|
||||
Fp2 {
|
||||
a: &self.a + &other.a,
|
||||
b: &self.b + &other.b,
|
||||
_marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, P: Fp2Params> Mul<&'a Fq> for &'b Fp2<P> {
|
||||
type Output = Fp2<P>;
|
||||
|
||||
fn mul(self, other: &Fq) -> Fp2<P> {
|
||||
Fp2 {
|
||||
a: &self.a * other,
|
||||
b: &self.b * other,
|
||||
_marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forward_ops_to_field_ops!(impl(P: Fp2Params) Fp2<P>);
|
|
@ -2,6 +2,7 @@
|
|||
mod macros;
|
||||
|
||||
pub mod fp;
|
||||
pub mod fp2;
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests;
|
||||
|
@ -11,18 +12,35 @@ use self::fp::{Fp, PrimeFieldParams};
|
|||
use std::fmt::Debug;
|
||||
|
||||
pub trait Field: Sized + Clone + Debug {
|
||||
fn zero() -> Self;
|
||||
fn one() -> Self;
|
||||
fn zero() -> Self;
|
||||
fn one() -> Self;
|
||||
fn random<R: Rng>(rng: &mut R) -> Self;
|
||||
fn is_zero(&self) -> bool;
|
||||
fn inverse(&self) -> Self;
|
||||
fn squared(&self) -> Self {
|
||||
self.mul(self)
|
||||
self.mul(self)
|
||||
}
|
||||
fn pow<P: PrimeFieldParams>(&self, exp: &Fp<P>) -> Self {
|
||||
let mut res = Self::one();
|
||||
|
||||
let mut found_one = false;
|
||||
|
||||
for i in (0..P::bits()).rev() {
|
||||
if found_one {
|
||||
res = res.squared();
|
||||
}
|
||||
|
||||
if exp.test_bit(i) {
|
||||
found_one = true;
|
||||
res = self.mul(&res);
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
fn pow<P: PrimeFieldParams>(&self, exp: &Fp<P>) -> Self;
|
||||
fn eq(&self, other: &Self) -> bool;
|
||||
fn ne(&self, other: &Self) -> bool {
|
||||
!self.eq(other)
|
||||
!self.eq(other)
|
||||
}
|
||||
|
||||
fn neg(&self) -> Self;
|
||||
|
|
|
@ -7,12 +7,15 @@ mod params;
|
|||
mod groups;
|
||||
|
||||
pub use fields::fp::Fp;
|
||||
pub use params::{FrParams,FqParams,G1Params};
|
||||
pub use fields::fp2::Fp2;
|
||||
pub use params::{FrParams,FqParams,Fq2Params,G1Params,G2Params};
|
||||
pub use fields::Field;
|
||||
pub use groups::Jacobian;
|
||||
|
||||
pub type Fr = Fp<FrParams>;
|
||||
pub type Fq = Fp<FqParams>;
|
||||
pub type Fq2 = Fp2<Fq2Params>;
|
||||
|
||||
pub type Scalar = Fr;
|
||||
pub type G1 = Jacobian<G1Params>;
|
||||
pub type G2 = Jacobian<G2Params>;
|
||||
|
|
102
src/params.rs
102
src/params.rs
|
@ -1,7 +1,8 @@
|
|||
use num::{Num,BigUint};
|
||||
use fields::Field;
|
||||
use fields::fp::PrimeFieldParams;
|
||||
use super::{Fr,Fq,G1};
|
||||
use fields::fp2::Fp2Params;
|
||||
use super::{Fr,Fq,Fq2,G1,G2};
|
||||
use groups::*;
|
||||
|
||||
pub struct FrParams;
|
||||
|
@ -28,20 +29,20 @@ impl PrimeFieldParams for FqParams {
|
|||
fn test_fr() {
|
||||
use fields;
|
||||
|
||||
fields::tests::field_trials::<super::Fr>();
|
||||
fields::tests::field_trials::<Fr>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq() {
|
||||
use fields;
|
||||
|
||||
fields::tests::field_trials::<super::Fq>();
|
||||
fields::tests::field_trials::<Fq>();
|
||||
}
|
||||
|
||||
pub struct G1Params;
|
||||
|
||||
impl GroupParams for G1Params {
|
||||
type Base = super::Fq;
|
||||
type Base = Fq;
|
||||
|
||||
fn name() -> &'static str {
|
||||
"G1"
|
||||
|
@ -62,12 +63,15 @@ fn test_g1() {
|
|||
use groups;
|
||||
|
||||
groups::tests::group_trials::<G1Params>();
|
||||
|
||||
assert_eq!(G1::zero(), G1::one() + (G1::zero() - G1::one()));
|
||||
assert_eq!(G1::zero(), G1::one() * Fr::from("21888242871839275222246405745257275088548364400416034343698204186575808495616") + G1::one());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn g1_test_vector() {
|
||||
let a = G1::one() * &Fr::from("19797905000333868150253315089095386158892526856493194078073564469188852136946");
|
||||
let b = G1::one() * &Fr::from("2730506433347642574983433139433778984782882168213690554721050571242082865799");
|
||||
let a = G1::one() * Fr::from("19797905000333868150253315089095386158892526856493194078073564469188852136946");
|
||||
let b = G1::one() * Fr::from("2730506433347642574983433139433778984782882168213690554721050571242082865799");
|
||||
let e = &a + &b;
|
||||
|
||||
let expect = G1::new(
|
||||
|
@ -76,5 +80,89 @@ fn g1_test_vector() {
|
|||
Fq::one()
|
||||
).unwrap();
|
||||
|
||||
assert!(expect.eq(&e));
|
||||
assert_eq!(expect, e);
|
||||
}
|
||||
|
||||
pub struct Fq2Params;
|
||||
|
||||
impl Fp2Params for Fq2Params {
|
||||
fn non_residue() -> Fq {
|
||||
Fq::from("21888242871839275222246405745257275088696311157297823662689037894645226208582")
|
||||
}
|
||||
fn name() -> &'static str {
|
||||
"Fq2"
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fq2() {
|
||||
use fields;
|
||||
|
||||
fields::tests::field_trials::<Fq2>();
|
||||
}
|
||||
|
||||
pub struct G2Params;
|
||||
|
||||
impl G2Params {
|
||||
pub fn twist() -> Fq2 {
|
||||
Fq2::new(Fq::from("9"), Fq::from("1"))
|
||||
}
|
||||
}
|
||||
|
||||
impl GroupParams for G2Params {
|
||||
type Base = Fq2;
|
||||
|
||||
fn name() -> &'static str {
|
||||
"G2"
|
||||
}
|
||||
fn zero() -> Jacobian<Self> {
|
||||
Jacobian::new(Fq2::zero(), Fq2::one(), Fq2::zero()).unwrap()
|
||||
}
|
||||
fn one() -> Jacobian<Self> {
|
||||
Jacobian::new(
|
||||
Fq2::new(
|
||||
Fq::from("10857046999023057135944570762232829481370756359578518086990519993285655852781"),
|
||||
Fq::from("11559732032986387107991004021392285783925812861821192530917403151452391805634")
|
||||
),
|
||||
Fq2::new(
|
||||
Fq::from("8495653923123431417604973247489272438418190587263600148770280649306958101930"),
|
||||
Fq::from("4082367875863433681332203403145435568316851327593401208105741076214120093531")
|
||||
),
|
||||
Fq2::one()
|
||||
).unwrap()
|
||||
}
|
||||
fn coeff_b() -> Self::Base {
|
||||
&G2Params::twist().inverse() * &Fq::from("3")
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_g2() {
|
||||
use groups;
|
||||
|
||||
groups::tests::group_trials::<G2Params>();
|
||||
|
||||
assert_eq!(G2::zero(), G2::one() + (G2::zero() - G2::one()));
|
||||
assert_eq!(G2::zero(), G2::one() * Fr::from("21888242871839275222246405745257275088548364400416034343698204186575808495616") + G2::one());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn g2_test_vector() {
|
||||
let a = G2::one() * Fr::from("19797905000333868150253315089095386158892526856493194078073564469188852136946");
|
||||
let b = G2::one() * Fr::from("2730506433347642574983433139433778984782882168213690554721050571242082865799");
|
||||
let e = &a + &b;
|
||||
|
||||
let expect = G2::new(
|
||||
Fq2::new(
|
||||
Fq::from("10805137482603266627116066166226222153808813611856467496561473491230213987197"),
|
||||
Fq::from("11018998371825437935082073888099464993330606622517843684670450190973893289235")
|
||||
),
|
||||
Fq2::new(
|
||||
Fq::from("371699491666579792038680273553261511891341995868329474144713691525212078012"),
|
||||
Fq::from("2123259504314265904107110265140842273706723557882599408954283209162529085097")
|
||||
),
|
||||
Fq2::one()
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(expect, e);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue