Skip to content

Commit

Permalink
Merge branch 'master' into singlethread
Browse files Browse the repository at this point in the history
  • Loading branch information
stefandeml committed Jan 23, 2019
2 parents 3bdd066 + 6e5cfe2 commit 29fd0a9
Show file tree
Hide file tree
Showing 13 changed files with 609 additions and 47 deletions.
15 changes: 9 additions & 6 deletions Cargo.toml
@@ -1,22 +1,25 @@
[package]
authors = ["Sean Bowe <ewillbefull@gmail.com>"]
authors = ["Sean Bowe <ewillbefull@gmail.com>", "Alex Vlasov <alex.m.vlasov@gmail.com>", "Alex Gluchowski <alex@gluchowski.net"]
description = "zk-SNARK library"
documentation = "https://github.com/ebfull/bellman"
homepage = "https://github.com/ebfull/bellman"
documentation = "https://github.com/matterinc/bellman"
homepage = "https://github.com/matterinc/bellman"
license = "MIT/Apache-2.0"
name = "bellman"
repository = "https://github.com/ebfull/bellman"
version = "0.1.0"
repository = "https://github.com/matterinc/bellman"
version = "0.1.2"

[dependencies]
rand = "0.4"
bit-vec = "0.4.4"
futures = "0.1"
pairing = "0.14"
pairing = { git = 'https://github.com/matterinc/pairing' }
ff = { git = 'https://github.com/matterinc/ff', features = ["derive"] }
byteorder = "1"
futures-cpupool = { version = "0.1", optional = true }
num_cpus = { version = "1", optional = true }
crossbeam = { version = "0.3", optional = true }
pbr = "1.0.1"
time = "0.1"

[features]
default = ["multithread"]
Expand Down
6 changes: 3 additions & 3 deletions README.md
@@ -1,6 +1,6 @@
# bellman [![Crates.io](https://img.shields.io/crates/v/bellman.svg)](https://crates.io/crates/bellman) #

This is a research project being built for [Zcash](https://z.cash/).
# bellman "Community edition"
Originally developed for ZCash, with extensions from us to make it a little more pleasant. Uses our "community edition" pairing for Ethereum's BN256 curve.

## License

Expand Down
27 changes: 22 additions & 5 deletions src/domain.rs
Expand Up @@ -12,11 +12,14 @@

use pairing::{
Engine,
Field,
PrimeField,
CurveProjective
};

use ff::{
Field,
PrimeField
};

use super::{
SynthesisError
};
Expand Down Expand Up @@ -47,22 +50,36 @@ impl<E: Engine, G: Group<E>> EvaluationDomain<E, G> {

pub fn from_coeffs(mut coeffs: Vec<G>) -> Result<EvaluationDomain<E, G>, SynthesisError>
{
use ff::PrimeField;
// Compute the size of our evaluation domain

let coeffs_len = coeffs.len();

// m is a size of domain where Z polynomial does NOT vanish
// in normal domain Z is in a form of (X-1)(X-2)...(X-N)
let mut m = 1;
let mut exp = 0;
while m < coeffs.len() {
let mut omega = E::Fr::root_of_unity();
let max_degree = (1 << E::Fr::S) - 1;

if coeffs_len > max_degree {
return Err(SynthesisError::PolynomialDegreeTooLarge)
}

while m < coeffs_len {
m *= 2;
exp += 1;

// The pairing-friendly curve may not be able to support
// large enough (radix2) evaluation domains.
if exp >= E::Fr::S {
if exp > E::Fr::S {
return Err(SynthesisError::PolynomialDegreeTooLarge)
}
}

// If full domain is not needed - limit it,
// e.g. if (2^N)th power is not required, just double omega and get 2^(N-1)th
// Compute omega, the 2^exp primitive root of unity
let mut omega = E::Fr::root_of_unity();
for _ in exp..E::Fr::S {
omega.square();
}
Expand Down
38 changes: 34 additions & 4 deletions src/groth16/generator.rs
@@ -1,16 +1,25 @@
extern crate time;

use super::super::verbose_flag;

use self::time::PreciseTime;

use rand::Rng;

use std::sync::Arc;

use pairing::{
Engine,
PrimeField,
Field,
Wnaf,
CurveProjective,
CurveAffine
};

use ff::{
PrimeField,
Field
};

use super::{
Parameters,
VerifyingKey
Expand Down Expand Up @@ -182,6 +191,8 @@ pub fn generate_parameters<E, C>(
) -> Result<Parameters<E>, SynthesisError>
where E: Engine, C: Circuit<E>
{
let verbose = verbose_flag();

let mut assembly = KeypairAssembly {
num_inputs: 0,
num_aux: 0,
Expand Down Expand Up @@ -210,6 +221,7 @@ pub fn generate_parameters<E, C>(
);
}

if verbose {eprintln!("Making {} powers of tau", assembly.num_constraints)};
// Create bases for blind evaluation of polynomials at tau
let powers_of_tau = vec![Scalar::<E>(E::Fr::zero()); assembly.num_constraints];
let mut powers_of_tau = EvaluationDomain::from_coeffs(powers_of_tau)?;
Expand Down Expand Up @@ -242,6 +254,8 @@ pub fn generate_parameters<E, C>(
let mut h = vec![E::G1::zero(); powers_of_tau.as_ref().len() - 1];
{
// Compute powers of tau
if verbose {eprintln!("computing powers of tau...")};
let start = PreciseTime::now();
{
let powers_of_tau = powers_of_tau.as_mut();
worker.scope(powers_of_tau.len(), |scope, chunk| {
Expand All @@ -258,17 +272,19 @@ pub fn generate_parameters<E, C>(
}
});
}
if verbose {eprintln!("powers of tau stage 1 done in {} s", start.to(PreciseTime::now()).num_milliseconds() as f64 / 1000.0);};

// coeff = t(x) / delta
let mut coeff = powers_of_tau.z(&tau);
coeff.mul_assign(&delta_inverse);

if verbose {eprintln!("computing the H query with multiple threads...")};
let start = PreciseTime::now();
// Compute the H query with multiple threads
worker.scope(h.len(), |scope, chunk| {
for (h, p) in h.chunks_mut(chunk).zip(powers_of_tau.as_ref().chunks(chunk))
{
let mut g1_wnaf = g1_wnaf.shared();

scope.spawn(move || {
// Set values of the H query to g1^{(tau^i * t(tau)) / delta}
for (h, p) in h.iter_mut().zip(p.iter())
Expand All @@ -286,18 +302,27 @@ pub fn generate_parameters<E, C>(
});
}
});
if verbose {eprintln!("computing the H query done in {} s", start.to(PreciseTime::now()).num_milliseconds() as f64 / 1000.0);};
}

if verbose {eprintln!("using inverse FFT to convert powers of tau to Lagrange coefficients...")};
let start = PreciseTime::now();

// Use inverse FFT to convert powers of tau to Lagrange coefficients
powers_of_tau.ifft(&worker);
let powers_of_tau = powers_of_tau.into_coeffs();

if verbose {eprintln!("powers of tau stage 2 done in {} s", start.to(PreciseTime::now()).num_milliseconds() as f64 / 1000.0)};

let mut a = vec![E::G1::zero(); assembly.num_inputs + assembly.num_aux];
let mut b_g1 = vec![E::G1::zero(); assembly.num_inputs + assembly.num_aux];
let mut b_g2 = vec![E::G2::zero(); assembly.num_inputs + assembly.num_aux];
let mut ic = vec![E::G1::zero(); assembly.num_inputs];
let mut l = vec![E::G1::zero(); assembly.num_aux];

if verbose {eprintln!("evaluating polynomials...")};
let start = PreciseTime::now();

fn eval<E: Engine>(
// wNAF window tables
g1_wnaf: &Wnaf<usize, &[E::G1], &mut Vec<i64>>,
Expand Down Expand Up @@ -327,6 +352,7 @@ pub fn generate_parameters<E, C>(
// Worker
worker: &Worker
)

{
// Sanity check
assert_eq!(a.len(), at.len());
Expand Down Expand Up @@ -408,7 +434,7 @@ pub fn generate_parameters<E, C>(
E::G2::batch_normalization(b_g2);
E::G1::batch_normalization(ext);
});
}
};
});
}

Expand Down Expand Up @@ -448,6 +474,8 @@ pub fn generate_parameters<E, C>(
&worker
);

if verbose {eprintln!("evaluating polynomials done in {} s", start.to(PreciseTime::now()).num_milliseconds() as f64 / 1000.0);};

// Don't allow any elements be unconstrained, so that
// the L query is always fully dense.
for e in l.iter() {
Expand All @@ -469,6 +497,8 @@ pub fn generate_parameters<E, C>(
ic: ic.into_iter().map(|e| e.into_affine()).collect()
};

println!("Has generated {} points", a.len());

Ok(Parameters {
vk: vk,
h: Arc::new(h.into_iter().map(|e| e.into_affine()).collect()),
Expand Down
6 changes: 3 additions & 3 deletions src/groth16/mod.rs
Expand Up @@ -24,7 +24,7 @@ pub use self::generator::*;
pub use self::prover::*;
pub use self::verifier::*;

#[derive(Clone)]
#[derive(Debug, Clone)]
pub struct Proof<E: Engine> {
pub a: E::G1Affine,
pub b: E::G2Affine,
Expand Down Expand Up @@ -487,7 +487,7 @@ mod test_with_bls12_381 {
use {Circuit, SynthesisError, ConstraintSystem};

use rand::{Rand, thread_rng};
use pairing::{Field};
use ff::{Field};
use pairing::bls12_381::{Bls12, Fr};

#[test]
Expand Down Expand Up @@ -573,4 +573,4 @@ mod test_with_bls12_381 {
assert!(!verify_proof(&pvk, &proof, &[a]).unwrap());
}
}
}
}

0 comments on commit 29fd0a9

Please sign in to comment.