implement parallelized polynomial evaluation
This commit is contained in:
parent
dc5e5ffe31
commit
056b7873cc
@ -35,6 +35,10 @@ impl Worker {
|
|||||||
log2_floor(self.cpus)
|
log2_floor(self.cpus)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn num_cpus(&self) -> usize {
|
||||||
|
self.cpus
|
||||||
|
}
|
||||||
|
|
||||||
pub fn compute<F, R>(
|
pub fn compute<F, R>(
|
||||||
&self, f: F
|
&self, f: F
|
||||||
) -> WorkerFuture<R::Item, R::Error>
|
) -> WorkerFuture<R::Item, R::Error>
|
||||||
|
@ -16,6 +16,8 @@ use crate::SynthesisError;
|
|||||||
use crate::sonic::cs::{Backend, SynthesisDriver};
|
use crate::sonic::cs::{Backend, SynthesisDriver};
|
||||||
use crate::sonic::cs::{Circuit};
|
use crate::sonic::cs::{Circuit};
|
||||||
|
|
||||||
|
use super::parameters::VerifyingKey;
|
||||||
|
|
||||||
use crate::sonic::srs::SRS;
|
use crate::sonic::srs::SRS;
|
||||||
use crate::sonic::util::multiexp;
|
use crate::sonic::util::multiexp;
|
||||||
|
|
||||||
@ -83,6 +85,25 @@ impl<E: Engine> Batch<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_from_key(vk: &VerifyingKey<E>) -> Self {
|
||||||
|
Batch {
|
||||||
|
alpha_x: vec![],
|
||||||
|
alpha_x_precomp: vk.alpha_x.prepare(),
|
||||||
|
|
||||||
|
alpha: vec![],
|
||||||
|
alpha_precomp: vk.alpha.prepare(),
|
||||||
|
|
||||||
|
neg_h: vec![],
|
||||||
|
neg_h_precomp: vk.neg_h.prepare(),
|
||||||
|
|
||||||
|
neg_x_n_minus_d: vec![],
|
||||||
|
neg_x_n_minus_d_precomp: vk.neg_x_n_minus_d.prepare(),
|
||||||
|
|
||||||
|
value: E::Fr::zero(),
|
||||||
|
g: E::G1Affine::one(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_opening(&mut self, p: E::G1Affine, mut r: E::Fr, point: E::Fr) {
|
pub fn add_opening(&mut self, p: E::G1Affine, mut r: E::Fr, point: E::Fr) {
|
||||||
self.alpha_x.push((p, r));
|
self.alpha_x.push((p, r));
|
||||||
r.mul_assign(&point);
|
r.mul_assign(&point);
|
||||||
|
@ -452,15 +452,7 @@ pub fn generate_parameters_on_srs_and_information<E: Engine>(
|
|||||||
|
|
||||||
Ok(Parameters{
|
Ok(Parameters{
|
||||||
vk: vk,
|
vk: vk,
|
||||||
d: trimmed_srs.d,
|
srs: trimmed_srs
|
||||||
g_negative_x: Arc::new(trimmed_srs.g_negative_x),
|
|
||||||
g_positive_x: Arc::new(trimmed_srs.g_positive_x),
|
|
||||||
h_negative_x: Arc::new(trimmed_srs.h_negative_x),
|
|
||||||
h_positive_x: Arc::new(trimmed_srs.h_positive_x),
|
|
||||||
g_negative_x_alpha: Arc::new(trimmed_srs.g_negative_x_alpha),
|
|
||||||
g_positive_x_alpha: Arc::new(trimmed_srs.g_positive_x_alpha),
|
|
||||||
h_negative_x_alpha: Arc::new(trimmed_srs.h_negative_x_alpha),
|
|
||||||
h_positive_x_alpha: Arc::new(trimmed_srs.h_positive_x_alpha)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,13 @@ mod generator;
|
|||||||
pub use self::batch::{Batch};
|
pub use self::batch::{Batch};
|
||||||
pub use self::helper::{Aggregate, create_aggregate};
|
pub use self::helper::{Aggregate, create_aggregate};
|
||||||
pub use self::verifier::{MultiVerifier};
|
pub use self::verifier::{MultiVerifier};
|
||||||
pub use self::prover::{create_proof, create_advice};
|
pub use self::prover::{
|
||||||
|
create_advice,
|
||||||
|
create_advice_on_information_and_srs,
|
||||||
|
create_advice_on_srs,
|
||||||
|
create_proof
|
||||||
|
};
|
||||||
|
|
||||||
pub use self::generator::{
|
pub use self::generator::{
|
||||||
CircuitParameters,
|
CircuitParameters,
|
||||||
generate_parameters,
|
generate_parameters,
|
||||||
|
@ -300,45 +300,38 @@ pub struct PreparedVerifyingKey<E: Engine> {
|
|||||||
pub struct Parameters<E: Engine> {
|
pub struct Parameters<E: Engine> {
|
||||||
pub vk: VerifyingKey<E>,
|
pub vk: VerifyingKey<E>,
|
||||||
|
|
||||||
pub d: usize,
|
pub srs: SRS<E>,
|
||||||
|
// pub d: usize,
|
||||||
|
|
||||||
// g^{x^0}, g^{x^{-1}}, g^{x^{-2}}, ..., g^{x^{-d}}
|
// // g^{x^0}, g^{x^{-1}}, g^{x^{-2}}, ..., g^{x^{-d}}
|
||||||
pub g_negative_x: Arc<Vec<E::G1Affine>>,
|
// pub g_negative_x: Arc<Vec<E::G1Affine>>,
|
||||||
|
|
||||||
// g^{x^0}, g^{x^{1}}, g^{x^{2}}, ..., g^{x^{d}}
|
// // g^{x^0}, g^{x^{1}}, g^{x^{2}}, ..., g^{x^{d}}
|
||||||
pub g_positive_x: Arc<Vec<E::G1Affine>>,
|
// pub g_positive_x: Arc<Vec<E::G1Affine>>,
|
||||||
|
|
||||||
// g^{x^0}, g^{x^{-1}}, g^{x^{-2}}, ..., g^{x^{-d}}
|
// // g^{x^0}, g^{x^{-1}}, g^{x^{-2}}, ..., g^{x^{-d}}
|
||||||
pub h_negative_x: Arc<Vec<E::G2Affine>>,
|
// pub h_negative_x: Arc<Vec<E::G2Affine>>,
|
||||||
|
|
||||||
// g^{x^0}, g^{x^{1}}, g^{x^{2}}, ..., g^{x^{d}}
|
// // g^{x^0}, g^{x^{1}}, g^{x^{2}}, ..., g^{x^{d}}
|
||||||
pub h_positive_x: Arc<Vec<E::G2Affine>>,
|
// pub h_positive_x: Arc<Vec<E::G2Affine>>,
|
||||||
|
|
||||||
// alpha*(g^{x^{-1}}, g^{x^{-2}}, ..., g^{x^{-d}})
|
// // alpha*(g^{x^{-1}}, g^{x^{-2}}, ..., g^{x^{-d}})
|
||||||
pub g_negative_x_alpha: Arc<Vec<E::G1Affine>>,
|
// pub g_negative_x_alpha: Arc<Vec<E::G1Affine>>,
|
||||||
|
|
||||||
// alpha*(g^{x^{1}}, g^{x^{2}}, ..., g^{x^{d}})
|
// // alpha*(g^{x^{1}}, g^{x^{2}}, ..., g^{x^{d}})
|
||||||
pub g_positive_x_alpha: Arc<Vec<E::G1Affine>>,
|
// pub g_positive_x_alpha: Arc<Vec<E::G1Affine>>,
|
||||||
|
|
||||||
// alpha*(h^{x^0}, h^{x^{-1}}, g^{x^{-2}}, ..., g^{x^{-d}})
|
// // alpha*(h^{x^0}, h^{x^{-1}}, g^{x^{-2}}, ..., g^{x^{-d}})
|
||||||
pub h_negative_x_alpha: Arc<Vec<E::G2Affine>>,
|
// pub h_negative_x_alpha: Arc<Vec<E::G2Affine>>,
|
||||||
|
|
||||||
// alpha*(h^{x^0}, g^{x^{1}}, g^{x^{2}}, ..., g^{x^{d}})
|
// // alpha*(h^{x^0}, g^{x^{1}}, g^{x^{2}}, ..., g^{x^{d}})
|
||||||
pub h_positive_x_alpha: Arc<Vec<E::G2Affine>>,
|
// pub h_positive_x_alpha: Arc<Vec<E::G2Affine>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> PartialEq for Parameters<E> {
|
impl<E: Engine> PartialEq for Parameters<E> {
|
||||||
fn eq(&self, other: &Parameters<E>) -> bool {
|
fn eq(&self, other: &Parameters<E>) -> bool {
|
||||||
self.vk == other.vk &&
|
self.vk == other.vk &&
|
||||||
self.d == other.d &&
|
self.srs == other.srs
|
||||||
self.g_negative_x == other.g_negative_x &&
|
|
||||||
self.g_positive_x == other.g_positive_x &&
|
|
||||||
self.h_negative_x == other.h_negative_x &&
|
|
||||||
self.h_positive_x == other.h_positive_x &&
|
|
||||||
self.g_negative_x_alpha == other.g_negative_x_alpha &&
|
|
||||||
self.g_positive_x_alpha == other.g_positive_x_alpha &&
|
|
||||||
self.h_negative_x_alpha == other.h_negative_x_alpha &&
|
|
||||||
self.h_positive_x_alpha == other.h_positive_x_alpha
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,48 +342,7 @@ impl<E: Engine> Parameters<E> {
|
|||||||
) -> io::Result<()>
|
) -> io::Result<()>
|
||||||
{
|
{
|
||||||
self.vk.write(&mut writer)?;
|
self.vk.write(&mut writer)?;
|
||||||
|
self.srs.write(&mut writer)?;
|
||||||
assert_eq!(self.d + 1, self.g_negative_x.len());
|
|
||||||
assert_eq!(self.d + 1, self.g_positive_x.len());
|
|
||||||
|
|
||||||
assert_eq!(self.d + 1, self.h_negative_x.len());
|
|
||||||
assert_eq!(self.d + 1, self.h_positive_x.len());
|
|
||||||
|
|
||||||
assert_eq!(self.d, self.g_negative_x_alpha.len());
|
|
||||||
assert_eq!(self.d, self.g_positive_x_alpha.len());
|
|
||||||
|
|
||||||
assert_eq!(self.d + 1, self.h_negative_x_alpha.len());
|
|
||||||
assert_eq!(self.d + 1, self.h_positive_x_alpha.len());
|
|
||||||
|
|
||||||
writer.write_u32::<BigEndian>(self.d as u32)?;
|
|
||||||
|
|
||||||
for g in &self.g_negative_x[..] {
|
|
||||||
writer.write_all(g.into_uncompressed().as_ref())?;
|
|
||||||
}
|
|
||||||
for g in &self.g_positive_x[..] {
|
|
||||||
writer.write_all(g.into_uncompressed().as_ref())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
for g in &self.h_negative_x[..] {
|
|
||||||
writer.write_all(g.into_uncompressed().as_ref())?;
|
|
||||||
}
|
|
||||||
for g in &self.h_positive_x[..] {
|
|
||||||
writer.write_all(g.into_uncompressed().as_ref())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
for g in &self.g_negative_x_alpha[..] {
|
|
||||||
writer.write_all(g.into_uncompressed().as_ref())?;
|
|
||||||
}
|
|
||||||
for g in &self.g_positive_x_alpha[..] {
|
|
||||||
writer.write_all(g.into_uncompressed().as_ref())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
for g in &self.h_negative_x_alpha[..] {
|
|
||||||
writer.write_all(g.into_uncompressed().as_ref())?;
|
|
||||||
}
|
|
||||||
for g in &self.h_positive_x_alpha[..] {
|
|
||||||
writer.write_all(g.into_uncompressed().as_ref())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -400,107 +352,12 @@ impl<E: Engine> Parameters<E> {
|
|||||||
checked: bool
|
checked: bool
|
||||||
) -> io::Result<Self>
|
) -> io::Result<Self>
|
||||||
{
|
{
|
||||||
let read_g1 = |reader: &mut R| -> io::Result<E::G1Affine> {
|
|
||||||
let mut repr = <E::G1Affine as CurveAffine>::Uncompressed::empty();
|
|
||||||
reader.read_exact(repr.as_mut())?;
|
|
||||||
|
|
||||||
if checked {
|
|
||||||
repr
|
|
||||||
.into_affine()
|
|
||||||
} else {
|
|
||||||
repr
|
|
||||||
.into_affine_unchecked()
|
|
||||||
}
|
|
||||||
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
|
|
||||||
.and_then(|e| if e.is_zero() {
|
|
||||||
Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity"))
|
|
||||||
} else {
|
|
||||||
Ok(e)
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let read_g2 = |reader: &mut R| -> io::Result<E::G2Affine> {
|
|
||||||
let mut repr = <E::G2Affine as CurveAffine>::Uncompressed::empty();
|
|
||||||
reader.read_exact(repr.as_mut())?;
|
|
||||||
|
|
||||||
if checked {
|
|
||||||
repr
|
|
||||||
.into_affine()
|
|
||||||
} else {
|
|
||||||
repr
|
|
||||||
.into_affine_unchecked()
|
|
||||||
}
|
|
||||||
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
|
|
||||||
.and_then(|e| if e.is_zero() {
|
|
||||||
Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity"))
|
|
||||||
} else {
|
|
||||||
Ok(e)
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let vk = VerifyingKey::<E>::read(&mut reader)?;
|
let vk = VerifyingKey::<E>::read(&mut reader)?;
|
||||||
|
let srs = SRS::<E>::read(&mut reader, checked)?;
|
||||||
|
|
||||||
let mut g_negative_x = vec![];
|
|
||||||
let mut g_positive_x = vec![];
|
|
||||||
|
|
||||||
let mut h_negative_x = vec![];
|
|
||||||
let mut h_positive_x = vec![];
|
|
||||||
|
|
||||||
let mut g_negative_x_alpha = vec![];
|
|
||||||
let mut g_positive_x_alpha = vec![];
|
|
||||||
|
|
||||||
let mut h_negative_x_alpha = vec![];
|
|
||||||
let mut h_positive_x_alpha = vec![];
|
|
||||||
|
|
||||||
let d = reader.read_u32::<BigEndian>()? as usize;
|
|
||||||
|
|
||||||
{
|
|
||||||
for _ in 0..(d+1) {
|
|
||||||
g_negative_x.push(read_g1(&mut reader)?);
|
|
||||||
}
|
|
||||||
for _ in 0..(d+1) {
|
|
||||||
g_positive_x.push(read_g1(&mut reader)?);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
for _ in 0..(d+1) {
|
|
||||||
h_negative_x.push(read_g2(&mut reader)?);
|
|
||||||
}
|
|
||||||
for _ in 0..(d+1) {
|
|
||||||
h_positive_x.push(read_g2(&mut reader)?);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
for _ in 0..d {
|
|
||||||
g_negative_x_alpha.push(read_g1(&mut reader)?);
|
|
||||||
}
|
|
||||||
for _ in 0..d {
|
|
||||||
g_positive_x_alpha.push(read_g1(&mut reader)?);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
for _ in 0..(d+1) {
|
|
||||||
h_negative_x_alpha.push(read_g2(&mut reader)?);
|
|
||||||
}
|
|
||||||
for _ in 0..(d+1) {
|
|
||||||
h_positive_x_alpha.push(read_g2(&mut reader)?);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Parameters {
|
Ok(Parameters {
|
||||||
vk: vk,
|
vk: vk,
|
||||||
d: d,
|
srs: srs
|
||||||
g_negative_x: Arc::new(g_negative_x),
|
|
||||||
g_positive_x: Arc::new(g_positive_x),
|
|
||||||
h_negative_x: Arc::new(h_negative_x),
|
|
||||||
h_positive_x: Arc::new(h_positive_x),
|
|
||||||
g_negative_x_alpha: Arc::new(g_negative_x_alpha),
|
|
||||||
g_positive_x_alpha: Arc::new(g_positive_x_alpha),
|
|
||||||
h_negative_x_alpha: Arc::new(h_negative_x_alpha),
|
|
||||||
h_positive_x_alpha: Arc::new(h_positive_x_alpha)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ use std::marker::PhantomData;
|
|||||||
use super::{Proof, SxyAdvice};
|
use super::{Proof, SxyAdvice};
|
||||||
use super::batch::Batch;
|
use super::batch::Batch;
|
||||||
use super::poly::{SxEval, SyEval};
|
use super::poly::{SxEval, SyEval};
|
||||||
|
use super::parameters::{Parameters};
|
||||||
|
|
||||||
use crate::SynthesisError;
|
use crate::SynthesisError;
|
||||||
|
|
||||||
@ -14,31 +15,13 @@ use crate::sonic::cs::{Backend, SynthesisDriver};
|
|||||||
use crate::sonic::cs::{Circuit, Variable, Coeff};
|
use crate::sonic::cs::{Circuit, Variable, Coeff};
|
||||||
use crate::sonic::srs::SRS;
|
use crate::sonic::srs::SRS;
|
||||||
|
|
||||||
pub fn create_advice<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
pub fn create_advice_on_information_and_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
||||||
circuit: &C,
|
circuit: &C,
|
||||||
proof: &Proof<E>,
|
proof: &Proof<E>,
|
||||||
srs: &SRS<E>
|
srs: &SRS<E>,
|
||||||
|
n: usize
|
||||||
) -> SxyAdvice<E>
|
) -> SxyAdvice<E>
|
||||||
{
|
{
|
||||||
// annoying, but we need n to compute s(z, y), and this isn't
|
|
||||||
// precomputed anywhere yet
|
|
||||||
let n = {
|
|
||||||
struct CountN {
|
|
||||||
n: usize
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, E: Engine> Backend<E> for &'a mut CountN {
|
|
||||||
fn new_multiplication_gate(&mut self) {
|
|
||||||
self.n += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut tmp = CountN{n:0};
|
|
||||||
S::synthesize(&mut tmp, circuit).unwrap(); // TODO
|
|
||||||
|
|
||||||
tmp.n
|
|
||||||
};
|
|
||||||
|
|
||||||
let z: E::Fr;
|
let z: E::Fr;
|
||||||
let y: E::Fr;
|
let y: E::Fr;
|
||||||
{
|
{
|
||||||
@ -111,6 +94,44 @@ pub fn create_advice<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_advice<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
||||||
|
circuit: &C,
|
||||||
|
proof: &Proof<E>,
|
||||||
|
parameters: &Parameters<E>,
|
||||||
|
) -> SxyAdvice<E>
|
||||||
|
{
|
||||||
|
let n = parameters.vk.n;
|
||||||
|
create_advice_on_information_and_srs::<E, C, S>(circuit, proof, ¶meters.srs, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_advice_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
||||||
|
circuit: &C,
|
||||||
|
proof: &Proof<E>,
|
||||||
|
srs: &SRS<E>
|
||||||
|
) -> SxyAdvice<E>
|
||||||
|
{
|
||||||
|
// annoying, but we need n to compute s(z, y), and this isn't
|
||||||
|
// precomputed anywhere yet
|
||||||
|
let n = {
|
||||||
|
struct CountN {
|
||||||
|
n: usize
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, E: Engine> Backend<E> for &'a mut CountN {
|
||||||
|
fn new_multiplication_gate(&mut self) {
|
||||||
|
self.n += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut tmp = CountN{n:0};
|
||||||
|
S::synthesize(&mut tmp, circuit).unwrap(); // TODO
|
||||||
|
|
||||||
|
tmp.n
|
||||||
|
};
|
||||||
|
|
||||||
|
create_advice_on_information_and_srs::<E, C, S>(circuit, proof, srs, n)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_proof<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
pub fn create_proof<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
||||||
circuit: &C,
|
circuit: &C,
|
||||||
srs: &SRS<E>
|
srs: &SRS<E>
|
||||||
|
@ -71,6 +71,118 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern crate crossbeam;
|
||||||
|
use self::crossbeam::channel::{unbounded, RecvError};
|
||||||
|
|
||||||
|
pub fn evaluate_at_consequitive_powers<'a, F: Field> (
|
||||||
|
coeffs: &[F],
|
||||||
|
first_power: F,
|
||||||
|
base: F
|
||||||
|
) -> F
|
||||||
|
{
|
||||||
|
use crate::multicore::Worker;
|
||||||
|
|
||||||
|
let (s, r) = unbounded();
|
||||||
|
|
||||||
|
let worker = Worker::new();
|
||||||
|
|
||||||
|
worker.scope(coeffs.len(), |scope, chunk| {
|
||||||
|
for (i, coeffs) in coeffs.chunks(chunk).enumerate()
|
||||||
|
{
|
||||||
|
let s = s.clone();
|
||||||
|
scope.spawn(move |_| {
|
||||||
|
let mut current_power = base.pow(&[(i*chunk) as u64]);
|
||||||
|
current_power.mul_assign(&first_power);
|
||||||
|
|
||||||
|
let mut acc = F::zero();
|
||||||
|
|
||||||
|
for p in coeffs {
|
||||||
|
let mut tmp = *p;
|
||||||
|
tmp.mul_assign(¤t_power);
|
||||||
|
acc.add_assign(&tmp);
|
||||||
|
|
||||||
|
current_power.mul_assign(&base);
|
||||||
|
}
|
||||||
|
|
||||||
|
s.send(acc).expect("must send");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
drop(s);
|
||||||
|
|
||||||
|
// all threads in a scope have done working, so we can safely read
|
||||||
|
let mut result = F::zero();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let v = r.recv();
|
||||||
|
match v {
|
||||||
|
Ok(value) => {
|
||||||
|
result.add_assign(&value);
|
||||||
|
},
|
||||||
|
Err(RecvError) => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mut_evaluate_at_consequitive_powers<'a, F: Field> (
|
||||||
|
coeffs: &mut [F],
|
||||||
|
first_power: F,
|
||||||
|
base: F
|
||||||
|
) -> F
|
||||||
|
{
|
||||||
|
use crate::multicore::Worker;
|
||||||
|
|
||||||
|
let (s, r) = unbounded();
|
||||||
|
|
||||||
|
let worker = Worker::new();
|
||||||
|
|
||||||
|
worker.scope(coeffs.len(), |scope, chunk| {
|
||||||
|
for (i, coeffs) in coeffs.chunks_mut(chunk).enumerate()
|
||||||
|
{
|
||||||
|
let s = s.clone();
|
||||||
|
scope.spawn(move |_| {
|
||||||
|
let mut current_power = base.pow(&[(i*chunk) as u64]);
|
||||||
|
current_power.mul_assign(&first_power);
|
||||||
|
|
||||||
|
let mut acc = F::zero();
|
||||||
|
|
||||||
|
for mut p in coeffs {
|
||||||
|
p.mul_assign(¤t_power);
|
||||||
|
acc.add_assign(&p);
|
||||||
|
|
||||||
|
current_power.mul_assign(&base);
|
||||||
|
}
|
||||||
|
|
||||||
|
s.send(acc).expect("must send");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
drop(s);
|
||||||
|
|
||||||
|
// all threads in a scope have done working, so we can safely read
|
||||||
|
let mut result = F::zero();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let v = r.recv();
|
||||||
|
match v {
|
||||||
|
Ok(value) => {
|
||||||
|
result.add_assign(&value);
|
||||||
|
},
|
||||||
|
Err(RecvError) => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
pub fn multiexp<
|
pub fn multiexp<
|
||||||
'a,
|
'a,
|
||||||
G: CurveAffine,
|
G: CurveAffine,
|
||||||
@ -420,4 +532,69 @@ fn test_mul() {
|
|||||||
|
|
||||||
assert_eq!(serial_res.len(), parallel_res.len());
|
assert_eq!(serial_res.len(), parallel_res.len());
|
||||||
assert_eq!(serial_res, parallel_res);
|
assert_eq!(serial_res, parallel_res);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_eval_at_powers() {
|
||||||
|
use rand::{self, Rand, Rng};
|
||||||
|
use pairing::bls12_381::Bls12;
|
||||||
|
use pairing::bls12_381::Fr;
|
||||||
|
|
||||||
|
const SAMPLES: usize = 100000;
|
||||||
|
|
||||||
|
let rng = &mut rand::thread_rng();
|
||||||
|
let a = (0..SAMPLES).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||||
|
let x: Fr = rng.gen();
|
||||||
|
let n: u32 = rng.gen();
|
||||||
|
|
||||||
|
let mut acc = Fr::zero();
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut tmp = x.pow(&[n as u64]);
|
||||||
|
|
||||||
|
for coeff in a.iter() {
|
||||||
|
let mut c = *coeff;
|
||||||
|
c.mul_assign(&tmp);
|
||||||
|
acc.add_assign(&c);
|
||||||
|
tmp.mul_assign(&x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let first_power = x.pow(&[n as u64]);
|
||||||
|
let acc_parallel = evaluate_at_consequitive_powers(&a[..], first_power, x);
|
||||||
|
|
||||||
|
assert_eq!(acc_parallel, acc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mut_eval_at_powers() {
|
||||||
|
use rand::{self, Rand, Rng};
|
||||||
|
use pairing::bls12_381::Bls12;
|
||||||
|
use pairing::bls12_381::Fr;
|
||||||
|
|
||||||
|
const SAMPLES: usize = 100000;
|
||||||
|
|
||||||
|
let rng = &mut rand::thread_rng();
|
||||||
|
let mut a = (0..SAMPLES).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||||
|
let mut b = a.clone();
|
||||||
|
let x: Fr = rng.gen();
|
||||||
|
let n: u32 = rng.gen();
|
||||||
|
|
||||||
|
let mut acc = Fr::zero();
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut tmp = x.pow(&[n as u64]);
|
||||||
|
|
||||||
|
for mut coeff in a.iter_mut() {
|
||||||
|
coeff.mul_assign(&tmp);
|
||||||
|
acc.add_assign(&coeff);
|
||||||
|
tmp.mul_assign(&x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let first_power = x.pow(&[n as u64]);
|
||||||
|
let acc_parallel = mut_evaluate_at_consequitive_powers(&mut b[..], first_power, x);
|
||||||
|
|
||||||
|
assert_eq!(acc_parallel, acc);
|
||||||
|
assert!(a == b);
|
||||||
}
|
}
|
@ -479,7 +479,7 @@ fn test_sonic_mimc() {
|
|||||||
|
|
||||||
use bellman::sonic::cs::Basic;
|
use bellman::sonic::cs::Basic;
|
||||||
use bellman::sonic::sonic::AdaptorCircuit;
|
use bellman::sonic::sonic::AdaptorCircuit;
|
||||||
use bellman::sonic::helped::{create_proof, create_advice, create_aggregate, MultiVerifier};
|
use bellman::sonic::helped::{create_proof, create_advice, create_aggregate, MultiVerifier, create_advice_on_srs};
|
||||||
|
|
||||||
println!("creating proof");
|
println!("creating proof");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
@ -488,7 +488,7 @@ fn test_sonic_mimc() {
|
|||||||
|
|
||||||
println!("creating advice");
|
println!("creating advice");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let advice = create_advice::<Bls12, _, Basic>(&AdaptorCircuit(circuit.clone()), &proof, &srs);
|
let advice = create_advice_on_srs::<Bls12, _, Basic>(&AdaptorCircuit(circuit.clone()), &proof, &srs);
|
||||||
println!("done in {:?}", start.elapsed());
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
println!("creating aggregate for {} proofs", samples);
|
println!("creating aggregate for {} proofs", samples);
|
||||||
@ -578,7 +578,7 @@ fn test_inputs_into_sonic_mimc() {
|
|||||||
|
|
||||||
use bellman::sonic::cs::Basic;
|
use bellman::sonic::cs::Basic;
|
||||||
use bellman::sonic::sonic::AdaptorCircuit;
|
use bellman::sonic::sonic::AdaptorCircuit;
|
||||||
use bellman::sonic::helped::{create_proof, get_circuit_parameters, create_advice, create_aggregate, MultiVerifier};
|
use bellman::sonic::helped::{create_proof, get_circuit_parameters, create_advice, create_aggregate, MultiVerifier, create_advice_on_srs};
|
||||||
|
|
||||||
let info = get_circuit_parameters::<Bn256, _>(circuit.clone()).expect("Must get circuit info");
|
let info = get_circuit_parameters::<Bn256, _>(circuit.clone()).expect("Must get circuit info");
|
||||||
println!("{:?}", info);
|
println!("{:?}", info);
|
||||||
@ -590,7 +590,7 @@ fn test_inputs_into_sonic_mimc() {
|
|||||||
|
|
||||||
println!("creating advice");
|
println!("creating advice");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let advice = create_advice::<Bn256, _, Basic>(&AdaptorCircuit(circuit.clone()), &proof, &srs);
|
let advice = create_advice_on_srs::<Bn256, _, Basic>(&AdaptorCircuit(circuit.clone()), &proof, &srs);
|
||||||
println!("done in {:?}", start.elapsed());
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
println!("creating aggregate for {} proofs", samples);
|
println!("creating aggregate for {} proofs", samples);
|
||||||
|
Loading…
Reference in New Issue
Block a user