commit
219929ee33
@ -16,6 +16,7 @@ crate-type = ["cdylib", "lib", "staticlib"]
|
||||
rand = "0.4"
|
||||
bit-vec = "0.4.4"
|
||||
futures = "0.1"
|
||||
cfg-if = "0.1.7"
|
||||
|
||||
pairing = { git = 'https://github.com/matterinc/pairing', tag = "0.16.2" }
|
||||
#pairing = { path = "../pairing" }
|
||||
@ -26,6 +27,7 @@ num_cpus = {version = "1", optional = true}
|
||||
crossbeam = {version = "0.7.1", optional = true}
|
||||
|
||||
tiny-keccak = {version = "1.4.2", optional = true}
|
||||
web-sys = {version = "0.3.17", optional = true, features = ["console", "Performance", "Window"]}
|
||||
|
||||
[dependencies.blake2-rfc]
|
||||
git = "https://github.com/gtank/blake2-rfc"
|
||||
@ -34,8 +36,8 @@ rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9"
|
||||
[features]
|
||||
default = ["multicore"]
|
||||
#default = ["multicore", "gm17", "sonic"]
|
||||
#default = ["singlecore"]
|
||||
#default = ["wasm"]
|
||||
multicore = ["futures-cpupool", "num_cpus", "crossbeam"]
|
||||
sonic = ["tiny-keccak"]
|
||||
gm17 = []
|
||||
singlecore = []
|
||||
wasm = ["web-sys"]
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::super::verbose_flag;
|
||||
use crate::log::Stopwatch;
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
@ -187,8 +187,6 @@ 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,
|
||||
@ -217,7 +215,7 @@ pub fn generate_parameters<E, C>(
|
||||
);
|
||||
}
|
||||
|
||||
if verbose {eprintln!("Making {} powers of tau", assembly.num_constraints)};
|
||||
elog_verbose!("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)?;
|
||||
@ -250,9 +248,9 @@ 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...")};
|
||||
elog_verbose!("computing powers of tau...");
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
{
|
||||
let powers_of_tau = powers_of_tau.as_mut();
|
||||
@ -270,15 +268,15 @@ pub fn generate_parameters<E, C>(
|
||||
}
|
||||
});
|
||||
}
|
||||
if verbose {eprintln!("powers of tau stage 1 done in {} s", start.elapsed().as_millis() as f64 / 1000.0);};
|
||||
elog_verbose!("powers of tau stage 1 done in {} s", stopwatch.elapsed());
|
||||
|
||||
// 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...")};
|
||||
elog_verbose!("computing the H query with multiple threads...");
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
// Compute the H query with multiple threads
|
||||
worker.scope(h.len(), |scope, chunk| {
|
||||
@ -302,27 +300,26 @@ pub fn generate_parameters<E, C>(
|
||||
});
|
||||
}
|
||||
});
|
||||
if verbose {eprintln!("computing the H query done in {} s", start.elapsed().as_millis() as f64 / 1000.0);};
|
||||
elog_verbose!("computing the H query done in {} s", stopwatch.elapsed());
|
||||
}
|
||||
|
||||
if verbose {eprintln!("using inverse FFT to convert powers of tau to Lagrange coefficients...")};
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
elog_verbose!("using inverse FFT to convert powers of tau to Lagrange coefficients...");
|
||||
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
// 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.elapsed().as_millis() as f64 / 1000.0)};
|
||||
|
||||
elog_verbose!("powers of tau stage 2 done in {} s", stopwatch.elapsed());
|
||||
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 = std::time::Instant::now();
|
||||
elog_verbose!("evaluating polynomials...");
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
fn eval<E: Engine>(
|
||||
// wNAF window tables
|
||||
@ -475,7 +472,7 @@ pub fn generate_parameters<E, C>(
|
||||
&worker
|
||||
);
|
||||
|
||||
if verbose {eprintln!("evaluating polynomials done in {} s", start.elapsed().as_millis() as f64 / 1000.0);};
|
||||
elog_verbose!("evaluating polynomials done in {} s", stopwatch.elapsed());
|
||||
|
||||
// Don't allow any elements be unconstrained, so that
|
||||
// the L query is always fully dense.
|
||||
@ -498,7 +495,7 @@ pub fn generate_parameters<E, C>(
|
||||
ic: ic.into_iter().map(|e| e.into_affine()).collect()
|
||||
};
|
||||
|
||||
println!("Has generated {} points", a.len());
|
||||
log!("Has generated {} points", a.len());
|
||||
|
||||
Ok(Parameters {
|
||||
vk: vk,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::super::verbose_flag;
|
||||
use crate::log::Stopwatch;
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
@ -164,20 +164,18 @@ impl<E:Engine> PreparedProver<E> {
|
||||
s: E::Fr
|
||||
) -> Result<Proof<E>, SynthesisError>
|
||||
{
|
||||
let verbose = verbose_flag();
|
||||
|
||||
let prover = self.assignment.clone();
|
||||
let worker = Worker::new();
|
||||
|
||||
let vk = params.get_vk(self.assignment.input_assignment.len())?;
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
let h = {
|
||||
let mut a = EvaluationDomain::from_coeffs(prover.a)?;
|
||||
let mut b = EvaluationDomain::from_coeffs(prover.b)?;
|
||||
let mut c = EvaluationDomain::from_coeffs(prover.c)?;
|
||||
if verbose {eprintln!("H query domain size is {}", a.as_ref().len())};
|
||||
elog_verbose!("H query domain size is {}", a.as_ref().len());
|
||||
|
||||
// here a coset is a domain where denominator (z) does not vanish
|
||||
// inverse FFT is an interpolation
|
||||
@ -209,9 +207,9 @@ impl<E:Engine> PreparedProver<E> {
|
||||
multiexp(&worker, params.get_h(a.len())?, FullDensity, a)
|
||||
};
|
||||
|
||||
if verbose {eprintln!("{} seconds for prover for H evaluation (mostly FFT)", start.elapsed().as_millis() as f64 / 1000.0)};
|
||||
elog_verbose!("{} seconds for prover for H evaluation (mostly FFT)", stopwatch.elapsed());
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
// TODO: Check that difference in operations for different chunks is small
|
||||
|
||||
@ -222,9 +220,8 @@ impl<E:Engine> PreparedProver<E> {
|
||||
|
||||
let input_len = input_assignment.len();
|
||||
let aux_len = aux_assignment.len();
|
||||
if verbose {eprintln!("H query is dense in G1,\nOther queries are {} elements in G1 and {} elements in G2",
|
||||
2*(input_len + aux_len) + aux_len, input_len + aux_len)
|
||||
};
|
||||
elog_verbose!("H query is dense in G1,\nOther queries are {} elements in G1 and {} elements in G2",
|
||||
2*(input_len + aux_len) + aux_len, input_len + aux_len);
|
||||
|
||||
// Run a dedicated process for dense vector
|
||||
let l = multiexp(&worker, params.get_l(aux_assignment.len())?, FullDensity, aux_assignment.clone());
|
||||
@ -287,7 +284,7 @@ impl<E:Engine> PreparedProver<E> {
|
||||
g_c.add_assign(&h.wait()?);
|
||||
g_c.add_assign(&l.wait()?);
|
||||
|
||||
if verbose {eprintln!("{} seconds for prover for point multiplication", start.elapsed().as_millis() as f64 / 1000.0)};
|
||||
elog_verbose!("{} seconds for prover for point multiplication", stopwatch.elapsed());
|
||||
|
||||
Ok(Proof {
|
||||
a: g_a.into_affine(),
|
||||
@ -411,8 +408,6 @@ pub fn create_proof<E, C, P: ParameterSource<E>>(
|
||||
) -> Result<Proof<E>, SynthesisError>
|
||||
where E: Engine, C: Circuit<E>
|
||||
{
|
||||
let verbose = verbose_flag();
|
||||
|
||||
let mut prover = ProvingAssignment {
|
||||
a_aux_density: DensityTracker::new(),
|
||||
b_input_density: DensityTracker::new(),
|
||||
@ -440,13 +435,13 @@ pub fn create_proof<E, C, P: ParameterSource<E>>(
|
||||
|
||||
let vk = params.get_vk(prover.input_assignment.len())?;
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
let h = {
|
||||
let mut a = EvaluationDomain::from_coeffs(prover.a)?;
|
||||
let mut b = EvaluationDomain::from_coeffs(prover.b)?;
|
||||
let mut c = EvaluationDomain::from_coeffs(prover.c)?;
|
||||
if verbose {eprintln!("H query domain size is {}", a.as_ref().len())};
|
||||
elog_verbose!("H query domain size is {}", a.as_ref().len());
|
||||
// here a coset is a domain where denominator (z) does not vanish
|
||||
// inverse FFT is an interpolation
|
||||
a.ifft(&worker);
|
||||
@ -477,9 +472,9 @@ pub fn create_proof<E, C, P: ParameterSource<E>>(
|
||||
multiexp(&worker, params.get_h(a.len())?, FullDensity, a)
|
||||
};
|
||||
|
||||
if verbose {eprintln!("{} seconds for prover for H evaluation (mostly FFT)", start.elapsed().as_millis() as f64 / 1000.0)};
|
||||
elog_verbose!("{} seconds for prover for H evaluation (mostly FFT)", stopwatch.elapsed());
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let stopwatch = Stopwatch::new();
|
||||
|
||||
// TODO: Check that difference in operations for different chunks is small
|
||||
|
||||
@ -549,7 +544,7 @@ pub fn create_proof<E, C, P: ParameterSource<E>>(
|
||||
g_c.add_assign(&h.wait()?);
|
||||
g_c.add_assign(&l.wait()?);
|
||||
|
||||
if verbose {eprintln!("{} seconds for prover for point multiplication", start.elapsed().as_millis() as f64 / 1000.0)};
|
||||
elog_verbose!("{} seconds for prover for point multiplication", stopwatch.elapsed());
|
||||
|
||||
Ok(Proof {
|
||||
a: g_a.into_affine(),
|
||||
|
32
src/lib.rs
32
src/lib.rs
@ -1,10 +1,16 @@
|
||||
#![allow(unused_imports)]
|
||||
#![allow(unused_macros)]
|
||||
#[macro_use]
|
||||
|
||||
extern crate cfg_if;
|
||||
extern crate pairing as pairing_import;
|
||||
extern crate rand;
|
||||
extern crate bit_vec;
|
||||
extern crate byteorder;
|
||||
|
||||
#[macro_use]
|
||||
mod log;
|
||||
|
||||
pub mod domain;
|
||||
pub mod groth16;
|
||||
|
||||
@ -20,18 +26,21 @@ mod multiexp;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[cfg(feature = "multicore")]
|
||||
mod multicore;
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "multicore")] {
|
||||
#[cfg(feature = "wasm")]
|
||||
compile_error!("Multicore feature is not yet compatible with wasm target arch");
|
||||
|
||||
#[cfg(feature = "singlecore")]
|
||||
mod singlecore;
|
||||
|
||||
mod worker {
|
||||
#[cfg(feature = "multicore")]
|
||||
pub use crate::multicore::*;
|
||||
|
||||
#[cfg(feature = "singlecore")]
|
||||
pub use crate::singlecore::*;
|
||||
mod multicore;
|
||||
mod worker {
|
||||
pub use crate::multicore::*;
|
||||
}
|
||||
} else {
|
||||
mod singlecore;
|
||||
mod worker {
|
||||
pub use crate::singlecore::*;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod pairing {
|
||||
@ -41,6 +50,7 @@ pub mod pairing {
|
||||
mod cs;
|
||||
pub use self::cs::*;
|
||||
|
||||
// todo move to log module after removing all references
|
||||
static mut VERBOSE_SWITCH: i8 = -1;
|
||||
|
||||
use std::str::FromStr;
|
||||
|
70
src/log.rs
Normal file
70
src/log.rs
Normal file
@ -0,0 +1,70 @@
|
||||
#[allow(unused_macros)]
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "wasm")] {
|
||||
use web_sys;
|
||||
use web_sys::Performance;
|
||||
|
||||
macro_rules! log {
|
||||
($($t:tt)*) => (web_sys::console::log_1(&format_args!($($t)*).to_string().into()))
|
||||
}
|
||||
|
||||
macro_rules! elog {
|
||||
($($t:tt)*) => (web_sys::console::log_1(&format_args!($($t)*).to_string().into()))
|
||||
}
|
||||
|
||||
macro_rules! log_verbose {
|
||||
($($t:tt)*) => (if $crate::verbose_flag() { web_sys::console::log_1(&format_args!($($t)*).to_string().into()) })
|
||||
}
|
||||
|
||||
macro_rules! elog_verbose {
|
||||
($($t:tt)*) => (if $crate::verbose_flag() { web_sys::console::log_1(&format_args!($($t)*).to_string().into()) })
|
||||
}
|
||||
|
||||
pub struct Stopwatch {
|
||||
start: f64,
|
||||
perf: Performance
|
||||
}
|
||||
|
||||
impl Stopwatch {
|
||||
pub fn new() -> Stopwatch {
|
||||
let perf = web_sys::window().unwrap().performance().unwrap();
|
||||
Stopwatch { start: perf.now(), perf }
|
||||
}
|
||||
|
||||
pub fn elapsed(&self) -> f64 {
|
||||
(self.perf.now() - self.start) / 1000.0
|
||||
}
|
||||
}
|
||||
} else {
|
||||
macro_rules! log {
|
||||
($($t:tt)*) => (println!($($t)*))
|
||||
}
|
||||
|
||||
macro_rules! elog {
|
||||
($($t:tt)*) => (eprintln!($($t)*))
|
||||
}
|
||||
|
||||
macro_rules! log_verbose {
|
||||
($($t:tt)*) => (if $crate::verbose_flag() { println!($($t)*) })
|
||||
}
|
||||
|
||||
macro_rules! elog_verbose {
|
||||
($($t:tt)*) => (if $crate::verbose_flag() { eprintln!($($t)*) })
|
||||
}
|
||||
|
||||
pub struct Stopwatch {
|
||||
start: std::time::Instant
|
||||
}
|
||||
|
||||
impl Stopwatch {
|
||||
pub fn new() -> Stopwatch {
|
||||
Stopwatch { start: std::time::Instant::now() }
|
||||
}
|
||||
|
||||
pub fn elapsed(&self) -> f64 {
|
||||
self.start.elapsed().as_millis() as f64 / 1000.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ impl Worker {
|
||||
// We don't expose this outside the library so that
|
||||
// all `Worker` instances have the same number of
|
||||
// CPUs configured.
|
||||
pub(crate) fn new_with_cpus(cpus: usize) -> Worker {
|
||||
pub(crate) fn new_with_cpus(_cpus: usize) -> Worker {
|
||||
Worker {
|
||||
cpus: 1,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user