Skip to content

Commit

Permalink
Adding elligator2 for edwards curves.
Browse files Browse the repository at this point in the history
  • Loading branch information
armfazh committed Mar 3, 2020
1 parent 9a77b28 commit 7ce4815
Show file tree
Hide file tree
Showing 18 changed files with 195 additions and 78 deletions.
7 changes: 3 additions & 4 deletions benches/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@ use crate::num_bigint::BigInt;
use criterion::{criterion_group, criterion_main, Benchmark, Criterion};

use redox_ecc::ellipticcurve::EllipticCurve;
use redox_ecc::weierstrass;
use redox_ecc::weierstrass::{P256, P384, P521};
use redox_ecc::instances::{P256, P384, P521};

fn arith(c: &mut Criterion) {
for id in [P256, P384, P521].iter() {
let ec = weierstrass::Curve::from(*id);
let ec = id.get();
let mut g0 = ec.get_generator();
let mut g1 = g0.clone();
let k = ec.new_scalar(BigInt::from(-1));
c.bench(
format!("{}/ec", id).as_str(),
format!("{}/ec", id.0.name).as_str(),
Benchmark::new("add", move |b| b.iter(|| g0 = &g0 + &g0))
.with_function("mul", move |b| b.iter(|| g1 = &k * &g1))
.sample_size(10),
Expand Down
7 changes: 3 additions & 4 deletions benches/field.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
use criterion::{criterion_group, criterion_main, Benchmark, Criterion};

use redox_ecc::field::FromFactory;
use redox_ecc::weierstrass;
use redox_ecc::weierstrass::{P256, P384, P521};
use redox_ecc::instances::{P256, P384, P521};

fn arith(c: &mut Criterion) {
for id in [P256, P384, P521].iter() {
let ec = weierstrass::Curve::from(*id);
let ec = id.get();
let mut x0 = ec.f.from(-1i64);
let mut x1 = ec.f.from(-1i64);
let mut x2 = ec.f.from(-1i64);
let y0 = ec.f.from(15i64);
let y1 = ec.f.from(15i64);

c.bench(
format!("{}/fp", id).as_str(),
format!("{}/fp", id.0.name).as_str(),
Benchmark::new("add", move |b| b.iter(|| x0 = &x0 + &y0))
.with_function("mul", move |b| b.iter(|| x1 = &x1 * &y1))
.with_function("inv", move |b| b.iter(|| x2 = 1u32 / &x2))
Expand Down
4 changes: 2 additions & 2 deletions benches/h2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ extern crate num_bigint;

use criterion::{criterion_group, criterion_main, Benchmark, Criterion};

use redox_ecc::h2c::EncodeToCurve;
use redox_ecc::weierstrass::{P256_SHA256_SSWU_NU_, P384_SHA512_SSWU_NU_, P521_SHA512_SSWU_NU_};
use redox_ecc::h2c::HashToCurve;
use redox_ecc::suites::{P256_SHA256_SSWU_NU_, P384_SHA512_SSWU_NU_, P521_SHA512_SSWU_NU_};

fn h2c(c: &mut Criterion) {
let msg = "message to be hashed".as_bytes();
Expand Down
32 changes: 23 additions & 9 deletions examples/call01.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
extern crate num_bigint;

// use num_traits::identities::Zero;
use std::convert::From;

Expand All @@ -26,13 +24,14 @@ use redox_ecc::field::{FromFactory, Sqrt};
// CURVE25519_SHA256_ELL2_NU_, CURVE25519_SHA256_ELL2_RO_, CURVE25519_SHA512_ELL2_NU_,
// CURVE25519_SHA512_ELL2_RO_, CURVE448_SHA512_ELL2_NU_, CURVE448_SHA512_ELL2_RO_,
// };
use redox_ecc::instances::CURVE25519;
use redox_ecc::h2c::HashToCurve;
use redox_ecc::instances::{P256, P384};
use redox_ecc::primefield::Fp;
// use redox_ecc::weierstrass::{P256_SHA256_SSWU_NU_, P384_SHA512_SSWU_NU_, P521_SHA512_SSWU_NU_};
// use redox_ecc::weierstrass::{P256_SHA256_SSWU_RO_, P384_SHA512_SSWU_RO_, P521_SHA512_SSWU_RO_};
// use redox_ecc::weierstrass::{P256_SHA256_SVDW_NU_, P384_SHA512_SVDW_NU_, P521_SHA512_SVDW_NU_};
// use redox_ecc::weierstrass::{P256_SHA256_SVDW_RO_, P384_SHA512_SVDW_RO_, P521_SHA512_SVDW_RO_};
use redox_ecc::suites::{
EDWARDS25519_SHA256_EDELL2_NU_, EDWARDS25519_SHA256_EDELL2_RO_, EDWARDS25519_SHA512_EDELL2_NU_,
EDWARDS25519_SHA512_EDELL2_RO_, EDWARDS448_SHA512_EDELL2_NU_, EDWARDS448_SHA512_EDELL2_RO_,
P256_SHA256_SSWU_NU_, P384_SHA512_SSWU_NU_, P521_SHA512_SSWU_NU_,
};

fn main() {
println!("{}", version());
Expand Down Expand Up @@ -95,6 +94,23 @@ fn main() {
let g0 = ec.get_generator();
let g1 = ec.get_generator();
println!("G: {} ", g0 + g1);
let msg = "This is a message string".as_bytes();
let dst = "QUUX-V01-CS02".as_bytes();
for suite in [
EDWARDS25519_SHA256_EDELL2_NU_,
EDWARDS25519_SHA256_EDELL2_RO_,
EDWARDS25519_SHA512_EDELL2_NU_,
EDWARDS25519_SHA512_EDELL2_RO_,
EDWARDS448_SHA512_EDELL2_NU_,
EDWARDS448_SHA512_EDELL2_RO_,
]
.iter()
{
let h = suite.get(dst);
let mut p = h.hash(msg);
p.normalize();
println!("enc: {} {} ", suite, p);
}
// println!("G: {} ", g2 + g3);
// let g2 = ec.get_generator();
// let g3 = ec.get_generator();
Expand All @@ -109,8 +125,6 @@ fn main() {
// println!("G: {} ", d);

// let f = ec.get_field();
// let msg = "This is a message string".as_bytes();
// let dst = "QUUX-V01-CS02".as_bytes();
//
// let a = f.hash(HashID::SHA256, msg, dst, 0u8, 48usize);
// println!("a: {} ", f);
Expand Down
31 changes: 22 additions & 9 deletions src/edwards/elligator2.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,41 @@
use num_traits::identities::Zero;

use crate::edwards::Curve as TeCurve;
use crate::edwards::ProyCoordinates;
use crate::ellipticcurve::{EllipticCurve, RationalMap};
use crate::field::{CMov, Field, FromFactory, Sgn0, Sgn0Endianness, Sqrt};
use crate::field::{Field, Sgn0Endianness};
use crate::h2c::MapToCurve;
use crate::montgomery::h2c::Ell2 as MtEll2;
use crate::montgomery::Curve as MtCurve;
use crate::montgomery::Ell2 as MtEll2;
use crate::primefield::FpElt;

pub struct Ell2 {
sgn0: Sgn0Endianness,
ratmap: Box<dyn RationalMap<E0 = TeCurve, E1 = MtCurve> + 'static>,
map_to_curve: Box<dyn MapToCurve<E = MtCurve> + 'static>,
}

impl Ell2 {
pub fn new(
e: TeCurve,
ratmap: Box<dyn RationalMap<E0 = TeCurve, E1 = MtCurve>>,
z: FpElt,
sgn0: Sgn0Endianness,
ratmap: Option<Box<dyn RationalMap<E0 = TeCurve, E1 = MtCurve>>>,
) -> Ell2 {
let ell2 = MtEll2::new(e1, z);
Ell2 { ratmap, sgn0, ell2 }
let (map_to_curve, ratmap) = match ratmap {
None => {
// let mt_curve = MtCurve::from(e);
// Box::new(MtEll2::new(mt_curve, z, sgn0))
unimplemented!()
}
Some(r) => {
if r.domain() != e {
panic!("Domain of rational map is incompatible with curve")
}
let mt_curve = r.codomain();
(Box::new(MtEll2::new(mt_curve, z, sgn0)), r)
}
};
Ell2 {
map_to_curve,
ratmap,
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/edwards/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
//!
//! The edwards module is meant to be used for bar.
mod curve;
mod elligator2;
mod point;
mod scalar;

pub use crate::edwards::curve::{Curve, CurveID, Params};
pub use crate::edwards::elligator2::Ell2;
pub use crate::edwards::point::{Point, ProyCoordinates};
pub use crate::edwards::scalar::Scalar;
8 changes: 3 additions & 5 deletions src/h2c/mod.rs → src/h2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ pub trait MapToCurve {
) -> <Self::E as EllipticCurve>::Point;
}

/// EncodeToCurve is a function that outputs a point on an elliptic curve from an
/// HashToCurve is a function that outputs a point on an elliptic curve from an
/// arbitrary string.
pub trait EncodeToCurve {
pub trait HashToCurve {
type E: EllipticCurve;
fn hash(&self, msg: &[u8]) -> <Self::E as EllipticCurve>::Point;
}
Expand All @@ -47,7 +47,7 @@ where
pub ro: bool,
}

impl<EE> EncodeToCurve for Encoding<EE>
impl<EE> HashToCurve for Encoding<EE>
where
EE: EllipticCurve,
{
Expand All @@ -66,5 +66,3 @@ where
p * &self.cofactor
}
}

pub mod suites;
1 change: 1 addition & 0 deletions src/instances/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ mod ted;
mod weier;

pub use crate::instances::mont::{CURVE25519, CURVE448};
pub use crate::instances::rational_maps::{edwards25519_to_curve25519, edwards448_to_curve448};
pub use crate::instances::ted::{EDWARDS25519, EDWARDS448};
pub use crate::instances::weier::{P256, P384, P521, SECP256K1};
2 changes: 1 addition & 1 deletion src/instances/mont.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::montgomery::{Curve, CurveID, Params};
use crate::montgomery::{CurveID, Params};

/// CURVE25519 is the curve25519 elliptic curve as specified in RFC-7748.
pub static CURVE25519: CurveID = CurveID(CURVE25519_PARAMS);
Expand Down
87 changes: 85 additions & 2 deletions src/instances/rational_maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,22 @@ use crate::edwards;
use crate::edwards::Curve as TeCurve;
use crate::edwards::Point as TePoint;
use crate::ellipticcurve::{EcPoint, EllipticCurve, RationalMap};
use crate::field::Field;
use crate::field::{Field, FromFactory};
use crate::instances::{CURVE25519, CURVE448, EDWARDS25519, EDWARDS448};
use crate::montgomery;
use crate::montgomery::Curve as MtCurve;
use crate::montgomery::Point as MtPoint;
use crate::primefield::FpElt;

pub struct Te2Mt25519 {
pub fn edwards25519_to_curve25519() -> impl RationalMap<E0 = TeCurve, E1 = MtCurve> {
let e0 = EDWARDS25519.get();
let e1 = CURVE25519.get();
let invsqr_d =
e0.f.from("6853475219497561581579357271197624642482790079785650197046958215289687604742");
Te2Mt25519 { e0, e1, invsqr_d }
}

struct Te2Mt25519 {
e0: TeCurve,
e1: MtCurve,
invsqr_d: FpElt,
Expand Down Expand Up @@ -64,3 +73,77 @@ impl RationalMap for Te2Mt25519 {
}
}
}

struct Te2Mt448 {
e0: TeCurve,
e1: MtCurve,
}

impl RationalMap for Te2Mt448 {
type E0 = TeCurve;
type E1 = MtCurve;

fn domain(&self) -> Self::E0 {
self.e0.clone()
}
fn codomain(&self) -> Self::E1 {
self.e1.clone()
}
fn push(&self, p: TePoint) -> MtPoint {
if p.is_zero() {
self.e1.identity()
} else {
let (x, y, z) = (&p.c.x, &p.c.y, &p.c.z);
let f = &self.e0.f;
let f2 = f.from(2);
let x2 = x ^ 2u32;
let y2 = y ^ 2u32;
let z2 = z ^ 2u32;
let zz = x * &x2; // zz = x^3
let xx = x * &y2; // xx = x*y^2
let yy = y * (f2 * z2 - y2 - x2); // yy = y*(2z^2-y^2-x^2)
self.e1.new_point(montgomery::ProyCoordinates {
x: xx,
y: yy,
z: zz,
})
}
}
fn pull(&self, p: MtPoint) -> TePoint {
if p.is_zero() {
self.e0.identity()
} else {
let f = &self.e0.f;
let (f2, f4) = (&f.from(2), &f.from(4));
let (x, y, z) = (&p.c.x, &p.c.y, &p.c.z);
let x2 = x ^ 2u32;
let x3 = &x2 * x;
let x4 = &x2 ^ 2u32;
let x5 = &x3 * &x2;
let y2 = y ^ 2u32;
let z2 = z ^ 2u32;
let z3 = &z2 * z;
let z4 = &z2 ^ 2u32;
let xx = f4 * y * z * (&x2 - &z2);
let z0 = x4 - f2 * &x2 * &z2 + &z4 + f4 * &y2 * &z2;
let yy = -(&x5 - f2 * &x3 * &z2 + x * &z4 - f4 * x * &y2 * &z2);
let z1 = x5 - f2 * &x3 * &z2 + x * z4 - f2 * x2 * &y2 * z - f2 * y2 * z3;
let tt = &xx * &yy;
let xx = &xx * &z1;
let yy = &yy * &z0;
let zz = z0 * z1;
self.e0.new_point(edwards::ProyCoordinates {
x: xx,
y: yy,
t: tt,
z: zz,
})
}
}
}

pub fn edwards448_to_curve448() -> impl RationalMap<E0 = TeCurve, E1 = MtCurve> {
let e0 = EDWARDS448.get();
let e1 = CURVE448.get();
Te2Mt448 { e0, e1 }
}
2 changes: 1 addition & 1 deletion src/instances/ted.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::edwards::{Curve, CurveID, Params};
use crate::edwards::{CurveID, Params};

/// EDWARDS25519 is the edwards25519 elliptic curve as specified in RFC-7748.
pub static EDWARDS25519: CurveID = CurveID(&EDWARDS25519_PARAMS);
Expand Down
2 changes: 1 addition & 1 deletion src/instances/weier.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::weierstrass::{Curve, CurveID, Params};
use crate::weierstrass::{CurveID, Params};

/// P256 is the NIST P-256 elliptic curve.
pub static P256: CurveID = CurveID(P256_PARAMS);
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ pub mod ops;
pub mod primefield;

pub mod ellipticcurve;
pub mod h2c;

pub mod edwards;
pub mod h2c;
pub mod montgomery;
pub mod weierstrass;

pub mod instances;
pub mod suites;

#[cfg(test)]
mod tests;
Expand Down
24 changes: 16 additions & 8 deletions src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,27 @@ macro_rules! make_trait {
),
pub trait $name
where
Self: Sized
+ for<'b> std::ops::$trait<&'b Self, Output = Self>
for<'a, 'b> Self: Sized
+ 'a
+ 'static
+ std::ops::$trait<&'b Self, Output = Self>
+ std::ops::$trait<Self, Output = Self>,
{
// for<'a, 'b> &'a Self: std::ops::$trait<&'b Self, Output = Self>,
// for<'a, 'b> &'a Self: std::ops::$trait<&'b Self, Output = Self>,
// for<'a, 'b> &'a Self: Sized
// + std::ops::$trait<&'b Self, Output = Self>
// + std::ops::$trait<Self, Output = Self>,
}
);
impl<T> $name for T where
T: Sized
+ std::ops::$trait<T, Output = T>
+ for<'b> std::ops::$trait<&'b T, Output = T>
impl<T> $name for T
where
for<'a, 'b> T: Sized
+ 'a
+ 'static
+ std::ops::$trait<&'b T, Output = T>
+ std::ops::$trait<T, Output = T>,
{
// for<'a, 'b> &'a T:
// Sized + std::ops::$trait<&'b T, Output = T> + std::ops::$trait<T, Output = T>,
}
};
(unary, $trait:ident, $name:ident) => {
Expand Down
Loading

0 comments on commit 7ce4815

Please sign in to comment.