extern crate byteorder; #[macro_use] extern crate crunchy; extern crate rand; #[cfg(feature = "rustc-serialize")] extern crate rustc_serialize; pub mod arith; mod fields; mod groups; use fields::FieldElement; use groups::{GroupElement, G1Params, G2Params, GroupParams}; use std::ops::{Add, Mul, Neg, Sub}; use rand::Rng; #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "rustc-serialize", derive(RustcDecodable, RustcEncodable))] #[repr(C)] pub struct Fr(fields::Fr); impl Fr { pub fn zero() -> Self { Fr(fields::Fr::zero()) } pub fn one() -> Self { Fr(fields::Fr::one()) } pub fn random(rng: &mut R) -> Self { Fr(fields::Fr::random(rng)) } pub fn pow(&self, exp: Fr) -> Self { Fr(self.0.pow(exp.0)) } pub fn from_str(s: &str) -> Option { fields::Fr::from_str(s).map(|e| Fr(e)) } pub fn inverse(&self) -> Option { self.0.inverse().map(|e| Fr(e)) } pub fn is_zero(&self) -> bool { self.0.is_zero() } pub fn interpret(buf: &[u8; 64]) -> Fr { Fr(fields::Fr::interpret(buf)) } pub fn from_slice(slice: &[u8]) -> Result { arith::U256::from_slice(slice) .map_err(|_| FieldError::InvalidSliceLength) // todo: maybe more sensful error handling .and_then(|x| fields::Fr::new_mul_factor(x).ok_or(FieldError::NotMember)) .map(|x| Fr(x)) } pub fn to_big_endian(&self, slice: &mut [u8]) -> Result<(), FieldError> { self.0 .raw() .to_big_endian(slice) .map_err(|_| FieldError::InvalidSliceLength) } } impl Add for Fr { type Output = Fr; fn add(self, other: Fr) -> Fr { Fr(self.0 + other.0) } } impl Sub for Fr { type Output = Fr; fn sub(self, other: Fr) -> Fr { Fr(self.0 - other.0) } } impl Neg for Fr { type Output = Fr; fn neg(self) -> Fr { Fr(-self.0) } } impl Mul for Fr { type Output = Fr; fn mul(self, other: Fr) -> Fr { Fr(self.0 * other.0) } } #[derive(Debug)] pub enum FieldError { InvalidSliceLength, NotMember, } pub use groups::Error as GroupError; #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "rustc-serialize", derive(RustcDecodable, RustcEncodable))] #[repr(C)] pub struct Fq(fields::Fq); impl Fq { pub fn zero() -> Self { Fq(fields::Fq::zero()) } pub fn one() -> Self { Fq(fields::Fq::one()) } pub fn random(rng: &mut R) -> Self { Fq(fields::Fq::random(rng)) } pub fn pow(&self, exp: Fq) -> Self { Fq(self.0.pow(exp.0)) } pub fn from_str(s: &str) -> Option { fields::Fq::from_str(s).map(|e| Fq(e)) } pub fn inverse(&self) -> Option { self.0.inverse().map(|e| Fq(e)) } pub fn is_zero(&self) -> bool { self.0.is_zero() } pub fn interpret(buf: &[u8; 64]) -> Fq { Fq(fields::Fq::interpret(buf)) } pub fn from_slice(slice: &[u8]) -> Result { arith::U256::from_slice(slice) .map_err(|_| FieldError::InvalidSliceLength) // todo: maybe more sensful error handling .and_then(|x| fields::Fq::new(x).ok_or(FieldError::NotMember)) .map(|x| Fq(x)) } pub fn to_big_endian(&self, slice: &mut [u8]) -> Result<(), FieldError> { let mut a: arith::U256 = self.0.into(); // convert from Montgomery representation a.mul( &fields::Fq::one().raw(), &fields::Fq::modulus(), self.0.inv(), ); a.to_big_endian(slice) .map_err(|_| FieldError::InvalidSliceLength) } pub fn from_u256(u256: arith::U256) -> Result { Ok(Fq(fields::Fq::new(u256).ok_or(FieldError::NotMember)?)) } pub fn into_u256(self) -> arith::U256 { (self.0).into() } } impl Add for Fq { type Output = Fq; fn add(self, other: Fq) -> Fq { Fq(self.0 + other.0) } } impl Sub for Fq { type Output = Fq; fn sub(self, other: Fq) -> Fq { Fq(self.0 - other.0) } } impl Neg for Fq { type Output = Fq; fn neg(self) -> Fq { Fq(-self.0) } } impl Mul for Fq { type Output = Fq; fn mul(self, other: Fq) -> Fq { Fq(self.0 * other.0) } } #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[repr(C)] pub struct Fq2(fields::Fq2); impl Fq2 { pub fn one() -> Fq2 { Fq2(fields::Fq2::one()) } pub fn i() -> Fq2 { Fq2::new(Fq::zero(), Fq::one()) } pub fn zero() -> Fq2 { Fq2(fields::Fq2::zero()) } /// Initalizes new F_q2(a + bi, a is real coeff, b is imaginary) pub fn new(a: Fq, b: Fq) -> Fq2 { Fq2(fields::Fq2::new(a.0, b.0)) } pub fn is_zero(&self) -> bool { self.0.is_zero() } pub fn pow(&self, exp: arith::U256) -> Self { Fq2(self.0.pow(exp)) } pub fn real(&self) -> Fq { Fq(*self.0.real()) } pub fn imaginary(&self) -> Fq { Fq(*self.0.imaginary()) } } impl Add for Fq2 { type Output = Self; fn add(self, other: Self) -> Self { Fq2(self.0 + other.0) } } impl Sub for Fq2 { type Output = Self; fn sub(self, other: Self) -> Self { Fq2(self.0 - other.0) } } impl Neg for Fq2 { type Output = Self; fn neg(self) -> Self { Fq2(-self.0) } } impl Mul for Fq2 { type Output = Self; fn mul(self, other: Self) -> Self { Fq2(self.0 * other.0) } } pub trait Group : Send + Sync + Copy + Clone + PartialEq + Eq + Sized + Add + Sub + Neg + Mul { fn zero() -> Self; fn one() -> Self; fn random(rng: &mut R) -> Self; fn is_zero(&self) -> bool; fn normalize(&mut self); } #[derive(Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "rustc-serialize", derive(RustcDecodable, RustcEncodable))] #[repr(C)] pub struct G1(groups::G1); impl G1 { pub fn new(x: Fq, y: Fq, z: Fq) -> Self { G1(groups::G1::new(x.0, y.0, z.0)) } pub fn x(&self) -> Fq { Fq(self.0.x().clone()) } pub fn set_x(&mut self, x: Fq) { *self.0.x_mut() = x.0 } pub fn y(&self) -> Fq { Fq(self.0.y().clone()) } pub fn set_y(&mut self, y: Fq) { *self.0.y_mut() = y.0 } pub fn z(&self) -> Fq { Fq(self.0.z().clone()) } pub fn set_z(&mut self, z: Fq) { *self.0.z_mut() = z.0 } pub fn b() -> Fq { Fq(G1Params::coeff_b()) } } impl Group for G1 { fn zero() -> Self { G1(groups::G1::zero()) } fn one() -> Self { G1(groups::G1::one()) } fn random(rng: &mut R) -> Self { G1(groups::G1::random(rng)) } fn is_zero(&self) -> bool { self.0.is_zero() } fn normalize(&mut self) { let new = match self.0.to_affine() { Some(a) => a, None => return, }; self.0 = new.to_jacobian(); } } impl Add for G1 { type Output = G1; fn add(self, other: G1) -> G1 { G1(self.0 + other.0) } } impl Sub for G1 { type Output = G1; fn sub(self, other: G1) -> G1 { G1(self.0 - other.0) } } impl Neg for G1 { type Output = G1; fn neg(self) -> G1 { G1(-self.0) } } impl Mul for G1 { type Output = G1; fn mul(self, other: Fr) -> G1 { G1(self.0 * other.0) } } #[derive(Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "rustc-serialize", derive(RustcDecodable, RustcEncodable))] #[repr(C)] pub struct AffineG1(groups::AffineG1); impl AffineG1 { pub fn new(x: Fq, y: Fq) -> Result { Ok(AffineG1(groups::AffineG1::new(x.0, y.0)?)) } pub fn x(&self) -> Fq { Fq(self.0.x().clone()) } pub fn set_x(&mut self, x: Fq) { *self.0.x_mut() = x.0 } pub fn y(&self) -> Fq { Fq(self.0.y().clone()) } pub fn set_y(&mut self, y: Fq) { *self.0.y_mut() = y.0 } pub fn from_jacobian(g1: G1) -> Option { g1.0.to_affine().map(|x| AffineG1(x)) } } impl From for G1 { fn from(affine: AffineG1) -> Self { G1(affine.0.to_jacobian()) } } #[derive(Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "rustc-serialize", derive(RustcDecodable, RustcEncodable))] #[repr(C)] pub struct G2(groups::G2); impl G2 { pub fn new(x: Fq2, y: Fq2, z: Fq2) -> Self { G2(groups::G2::new(x.0, y.0, z.0)) } pub fn x(&self) -> Fq2 { Fq2(self.0.x().clone()) } pub fn set_x(&mut self, x: Fq2) { *self.0.x_mut() = x.0 } pub fn y(&self) -> Fq2 { Fq2(self.0.y().clone()) } pub fn set_y(&mut self, y: Fq2) { *self.0.y_mut() = y.0 } pub fn z(&self) -> Fq2 { Fq2(self.0.z().clone()) } pub fn set_z(&mut self, z: Fq2) { *self.0.z_mut() = z.0 } pub fn b() -> Fq2 { Fq2(G2Params::coeff_b()) } } impl Group for G2 { fn zero() -> Self { G2(groups::G2::zero()) } fn one() -> Self { G2(groups::G2::one()) } fn random(rng: &mut R) -> Self { G2(groups::G2::random(rng)) } fn is_zero(&self) -> bool { self.0.is_zero() } fn normalize(&mut self) { let new = match self.0.to_affine() { Some(a) => a, None => return, }; self.0 = new.to_jacobian(); } } impl Add for G2 { type Output = G2; fn add(self, other: G2) -> G2 { G2(self.0 + other.0) } } impl Sub for G2 { type Output = G2; fn sub(self, other: G2) -> G2 { G2(self.0 - other.0) } } impl Neg for G2 { type Output = G2; fn neg(self) -> G2 { G2(-self.0) } } impl Mul for G2 { type Output = G2; fn mul(self, other: Fr) -> G2 { G2(self.0 * other.0) } } #[derive(Copy, Clone, PartialEq, Eq)] #[repr(C)] pub struct Gt(fields::Fq12); impl Gt { pub fn one() -> Self { Gt(fields::Fq12::one()) } pub fn pow(&self, exp: Fr) -> Self { Gt(self.0.pow(exp.0)) } pub fn inverse(&self) -> Self { Gt(self.0.inverse().unwrap()) } } impl Mul for Gt { type Output = Gt; fn mul(self, other: Gt) -> Gt { Gt(self.0 * other.0) } } pub fn pairing(p: G1, q: G2) -> Gt { Gt(groups::pairing(&p.0, &q.0)) } #[derive(Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "rustc-serialize", derive(RustcDecodable, RustcEncodable))] #[repr(C)] pub struct AffineG2(groups::AffineG2); impl AffineG2 { pub fn new(x: Fq2, y: Fq2) -> Result { Ok(AffineG2(groups::AffineG2::new(x.0, y.0)?)) } pub fn x(&self) -> Fq2 { Fq2(self.0.x().clone()) } pub fn set_x(&mut self, x: Fq2) { *self.0.x_mut() = x.0 } pub fn y(&self) -> Fq2 { Fq2(self.0.y().clone()) } pub fn set_y(&mut self, y: Fq2) { *self.0.y_mut() = y.0 } pub fn from_jacobian(g2: G2) -> Option { g2.0.to_affine().map(|x| AffineG2(x)) } } impl From for G2 { fn from(affine: AffineG2) -> Self { G2(affine.0.to_jacobian()) } }