extern crate rand;
extern crate rustc_serialize;
extern crate byteorder;
pub mod arith;
mod fields;
mod groups;
use fields::FieldElement;
use groups::GroupElement;
use std::ops::{Add, Sub, Mul, Neg};
use rand::Rng;
#[derive(Copy, Clone, Debug, PartialEq, Eq, 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<R: Rng>(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<Self> { fields::Fr::from_str(s).map(|e| Fr(e)) }
pub fn inverse(&self) -> Option<Self> { 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<Self, FieldError> {
arith::U256::from_slice(slice)
.map_err(|_| FieldError::InvalidSliceLength) .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<Fr> for Fr {
type Output = Fr;
fn add(self, other: Fr) -> Fr { Fr(self.0 + other.0) }
}
impl Sub<Fr> 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, 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<R: Rng>(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<Self> { fields::Fq::from_str(s).map(|e| Fq(e)) }
pub fn inverse(&self) -> Option<Self> { 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<Self, FieldError> {
arith::U256::from_slice(slice)
.map_err(|_| FieldError::InvalidSliceLength) .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();
a.mul(&fields::Fq::one().raw(), &fields::Fq::modulus(), self.0.inv());
a.to_big_endian(slice).map_err(|_| FieldError::InvalidSliceLength)
}
}
impl Add<Fq> for Fq {
type Output = Fq;
fn add(self, other: Fq) -> Fq { Fq(self.0 + other.0) }
}
impl Sub<Fq> 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) }
}
pub struct Fq2(fields::Fq2);
impl Fq2 {
pub fn one() -> Fq2 {
Fq2(fields::Fq2::one())
}
pub fn zero() -> Fq2 {
Fq2(fields::Fq2::zero())
}
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 trait Group:
rustc_serialize::Encodable +
rustc_serialize::Decodable +
'static +
Send +
Sync +
Copy +
Clone +
PartialEq +
Eq +
Sized +
Add<Self, Output=Self> +
Sub<Self, Output=Self> +
Neg<Output=Self> +
Mul<Fr, Output=Self>
{
fn zero() -> Self;
fn one() -> Self;
fn random<R: Rng>(rng: &mut R) -> Self;
fn is_zero(&self) -> bool;
fn normalize(&mut self);
}
#[derive(Copy, Clone, PartialEq, Eq, 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
}
}
impl Group for G1 {
fn zero() -> Self { G1(groups::G1::zero()) }
fn one() -> Self { G1(groups::G1::one()) }
fn random<R: Rng>(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<G1> for G1 {
type Output = G1;
fn add(self, other: G1) -> G1 { G1(self.0 + other.0) }
}
impl Sub<G1> 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<Fr> for G1 {
type Output = G1;
fn mul(self, other: Fr) -> G1 { G1(self.0 * other.0) }
}
#[derive(Copy, Clone, PartialEq, Eq, RustcDecodable, RustcEncodable)]
#[repr(C)]
pub struct AffineG1(groups::AffineG1);
impl AffineG1 {
pub fn new(x: Fq, y: Fq) -> Result<Self, GroupError> {
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<Self> {
g1.0.to_affine().map(|x| AffineG1(x))
}
}
impl From<AffineG1> for G1 {
fn from(affine: AffineG1) -> Self {
G1(affine.0.to_jacobian())
}
}
#[derive(Copy, Clone, PartialEq, Eq, 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
}
}
impl Group for G2 {
fn zero() -> Self { G2(groups::G2::zero()) }
fn one() -> Self { G2(groups::G2::one()) }
fn random<R: Rng>(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<G2> for G2 {
type Output = G2;
fn add(self, other: G2) -> G2 { G2(self.0 + other.0) }
}
impl Sub<G2> 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<Fr> 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<Gt> 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, RustcDecodable, RustcEncodable)]
#[repr(C)]
pub struct AffineG2(groups::AffineG2);
impl AffineG2 {
pub fn new(x: Fq2, y: Fq2) -> Result<Self, GroupError> {
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<Self> {
g2.0.to_affine().map(|x| AffineG2(x))
}
}
impl From<AffineG2> for G2 {
fn from(affine: AffineG2) -> Self {
G2(affine.0.to_jacobian())
}
}