mirror of
https://github.com/pezkuwichain/bizinikiwi-bn.git
synced 2026-07-23 07:55:40 +00:00
510 lines
10 KiB
Rust
510 lines
10 KiB
Rust
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;
|
|
|
|
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<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) // 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<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)]
|
|
#[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<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) // 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<Self, FieldError> {
|
|
Ok(Fq(fields::Fq::new(u256).ok_or(FieldError::NotMember)?))
|
|
}
|
|
}
|
|
|
|
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())
|
|
}
|
|
|
|
/// 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: Fq) -> Self {
|
|
Fq2(self.0.pow(exp.0))
|
|
}
|
|
}
|
|
|
|
pub trait Group
|
|
: 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)]
|
|
#[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
|
|
}
|
|
}
|
|
|
|
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)]
|
|
#[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<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)]
|
|
#[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
|
|
}
|
|
}
|
|
|
|
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)]
|
|
#[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<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())
|
|
}
|
|
}
|