Git Product home page Git Product logo

bn's People

Contributors

daira avatar ebfull avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bn's Issues

New core implementation

I'm designing a new "core" for the cryptography in this library, mostly in the interest of performance and flexibility.

Features include:

  • The library will support multiple BN curve implementations all behind this abstract API. In particular, I plan to integrate a stronger curve construction which should be more secure and more useful for zk-SNARKs.
  • The user can perform miller loops (with any number of point tuples) manually if they want to avoid unnecessary final exponentiations or redundant ate loops. The Ethereum folks will need to expose all of this functionality in their precompiles if they want to give users maximum performance and flexibility, especially if you need to use newer zk-SNARK schemes or do batch/probablistic verification of proofs.
  • The user can perform G2 precomputation for the miller loop manually.
  • Support for mixed addition.
  • Support for curve point compression (the same way that Zcash compresses proofs).

API preview:

pub trait Field<E: Engine>: Sized +
                            Eq +
                            PartialEq +
                            Copy +
                            Clone +
                            Send +
                            Sync +
                            Debug +
                            'static
{
    fn zero() -> Self;
    fn one(&E) -> Self;
    fn random<R: rand::Rng>(&E, &mut R) -> Self;

    fn is_zero(&self) -> bool;
    
    fn square(&mut self, &E);
    fn double(&mut self, &E);
    fn negate(&mut self, &E);
    fn add_assign(&mut self, &E, other: &Self);
    fn sub_assign(&mut self, &E, other: &Self);
    fn mul_assign(&mut self, &E, other: &Self);
    fn inverse(&self, &E) -> Option<Self>;
    fn sqrt(&self, &E) -> Option<Self>;
    fn powi<I: IntoIterator<Item=u64>>(&self, engine: &E, exp: I) -> Self;
    fn powb<I: IntoIterator<Item=bool>>(&self, engine: &E, exp: I) -> Self;
}

pub trait PrimeField<E: Engine>: Field<E>
{
    type Repr: AsRef<[u64]>;

    fn from_str(&E, s: &str) -> Result<Self, ()>;
    fn from_repr(&E, Self::Repr) -> Result<Self, ()>;
    fn into_repr(&self, &E) -> Self::Repr;
}

/// A representation of a group element that can be serialized and deserialized,
/// but is not guaranteed to be a point on the curve.
pub trait GroupRepresentation<E: Engine, F: Field<E>, G: Group<E, F>>: Copy +
                                                                       Clone +
                                                                       Sized +
                                                                       Send +
                                                                       Sync +
                                                                       Debug +
                                                                       'static
{
    /// Attempt to parse the representation as an element on
    /// the curve in the affine.
    fn to_affine(&self, &E) -> Option<G::Affine>;

    /// This is like `to_affine` except the caller is
    /// responsible for ensuring the point is on the curve.
    /// If it isn't, this function is allowed to panic,
    /// but not guaranteed to.
    fn to_affine_unchecked(&self, &E) -> G::Affine;
}

pub trait GroupAffine<E: Engine, F: Field<E>, G: Group<E, F>>: Copy +
                                                               Clone +
                                                               Sized +
                                                               Send +
                                                               Sync +
                                                               Debug +
                                                               PartialEq +
                                                               Eq +
                                                               'static
{
    fn to_jacobian(&self, &E) -> G;
    fn to_compressed(&self, &E) -> G::Compressed;
    fn to_uncompressed(&self, &E) -> G::Uncompressed;
}

pub trait Group<E: Engine, F: Field<E>>: Sized +
                                         Eq +
                                         PartialEq +
                                         Copy +
                                         Clone +
                                         Send +
                                         Sync +
                                         Debug +
                                         'static
{
    type Affine: GroupAffine<E, F, Self>;
    type Compressed: GroupRepresentation<E, F, Self>;
    type Uncompressed: GroupRepresentation<E, F, Self>;
    type Prepared: Clone + 'static;

    fn zero(&E) -> Self;
    fn one(&E) -> Self;
    fn random<R: rand::Rng>(&E, &mut R) -> Self;

    fn is_zero(&E) -> Self;

    fn to_affine(&self, &E) -> Self::Affine;
    fn prepare(&self, &E) -> Self::Prepared;

    fn double(&mut self, &E);
    fn negate(&mut self, engine: &E);
    fn add_assign(&mut self, &E, other: &Self);
    fn add_assign_mixed(&mut self, &E, other: &Self::Affine);
    fn mul_assign(&mut self, &E, other: &E::Fr);
}

pub trait Engine: Sized {
    type Fq: PrimeField<Self>;
    type Fr: PrimeField<Self>;
    type Fqe: Field<Self>;
    type Fqk: Field<Self>;
    type G1: Group<Self, Self::Fq>;
    type G2: Group<Self, Self::Fqe>;

    fn new() -> Self;

    fn miller_loop<'a, I>(&self, I) -> Self::Fqk
        where I: IntoIterator<Item=&'a (
                                    &'a <Self::G1 as Group<Self, Self::Fq>>::Prepared,
                                    &'a <Self::G2 as Group<Self, Self::Fqe>>::Prepared
                               )>;

    fn final_exponentiation(&self, &Self::Fqk) -> Self::Fqk;

    fn pairing(&self, p: &Self::G1, q: &Self::G2) -> Self::Fqk
    {
        self.final_exponentiation(&self.miller_loop(
            [(&p.prepare(self), &q.prepare(self))].into_iter()
        ))
    }
}

Why does a pairing take so long?

https://crypto.stanford.edu/pbc/

I was under impression pairings would take roughly 30 milliseconds according to the link above.

But my test shows otherwise:

$ time cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/hello_world`
PT0.321907197S seconds for whatever you did.

real	0m0.840s
user	0m0.792s
sys	0m0.012s

My test code:

extern crate bn;
extern crate rand;
extern crate time;
use bn::{Group, Fr, G1, G2, pairing};
use time::PreciseTime;

fn main() {
	let rng = &mut rand::thread_rng();

	// Generate private keys
	let bob_sk = Fr::random(rng);
	let carol_sk = Fr::random(rng);

	// Generate public keys in G1 and G2
	let (bob_pk1, bob_pk2) = (G1::one() * bob_sk, G2::one() * bob_sk);
	let (carol_pk1, carol_pk2) = (G1::one() * carol_sk, G2::one() * carol_sk);

	// Time the pairing
	let start = PreciseTime::now();
	let alice_ss = pairing(bob_pk1, carol_pk2);
	let end = PreciseTime::now();
	
	println!("{} seconds for whatever you did.", start.to(end));
}

@ChronusZ

few PRs

seems like a lot of people fork and add bits but don't PR back to the main lib?

wondering if there's some way that maybe co-ordination could be improved? I wonder why they don't contribute back...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.