start restructuring to use groth16-similar types
This commit is contained in:
parent
cd00c4eaf7
commit
6059601518
@ -7,7 +7,6 @@ use pairing::{Engine};
|
||||
use crate::{SynthesisError};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
|
||||
mod lc;
|
||||
pub use self::lc::{Coeff, Variable, LinearCombination};
|
||||
|
||||
|
@ -141,74 +141,4 @@ impl<E: Engine> Batch<E> {
|
||||
(&neg_x_n_minus_d, &self.neg_x_n_minus_d_precomp),
|
||||
])).unwrap() == E::Fqk::one()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct VerifyingKey<E: Engine> {
|
||||
pub alpha_x: E::G2Affine,
|
||||
|
||||
pub alpha: E::G2Affine,
|
||||
|
||||
pub neg_h: E::G2Affine,
|
||||
|
||||
pub neg_x_n_minus_d: E::G2Affine,
|
||||
|
||||
pub k_map: Vec<usize>,
|
||||
|
||||
pub n: usize,
|
||||
|
||||
pub q: usize
|
||||
}
|
||||
|
||||
impl<E: Engine> VerifyingKey<E> {
|
||||
pub fn new<C: Circuit<E>, S: SynthesisDriver>(circuit: C, srs: &SRS<E>) -> Result<Self, SynthesisError> {
|
||||
struct Preprocess<E: Engine> {
|
||||
k_map: Vec<usize>,
|
||||
n: usize,
|
||||
q: usize,
|
||||
_marker: PhantomData<E>
|
||||
}
|
||||
|
||||
impl<'a, E: Engine> Backend<E> for &'a mut Preprocess<E> {
|
||||
fn new_k_power(&mut self, index: usize) {
|
||||
self.k_map.push(index);
|
||||
}
|
||||
|
||||
fn new_multiplication_gate(&mut self) {
|
||||
self.n += 1;
|
||||
}
|
||||
|
||||
fn new_linear_constraint(&mut self) {
|
||||
self.q += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let mut preprocess = Preprocess { k_map: vec![], n: 0, q: 0, _marker: PhantomData };
|
||||
|
||||
S::synthesize(&mut preprocess, &circuit)?;
|
||||
|
||||
Ok(Self {
|
||||
alpha_x: srs.h_positive_x_alpha[1],
|
||||
|
||||
alpha: srs.h_positive_x_alpha[0],
|
||||
|
||||
neg_h: {
|
||||
let mut tmp = srs.h_negative_x[0];
|
||||
tmp.negate();
|
||||
|
||||
tmp
|
||||
},
|
||||
|
||||
neg_x_n_minus_d: {
|
||||
let mut tmp = srs.h_negative_x[srs.d - preprocess.n];
|
||||
tmp.negate();
|
||||
|
||||
tmp
|
||||
},
|
||||
|
||||
k_map: preprocess.k_map,
|
||||
n: preprocess.n,
|
||||
q: preprocess.q
|
||||
})
|
||||
}
|
||||
}
|
800
src/sonic/helped/generator.rs
Normal file
800
src/sonic/helped/generator.rs
Normal file
@ -0,0 +1,800 @@
|
||||
use rand::Rng;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use pairing::{
|
||||
Engine,
|
||||
Wnaf,
|
||||
CurveProjective,
|
||||
CurveAffine
|
||||
};
|
||||
|
||||
use ff::{
|
||||
PrimeField,
|
||||
Field
|
||||
};
|
||||
|
||||
use super::{
|
||||
Parameters,
|
||||
VerifyingKey
|
||||
};
|
||||
|
||||
use ::{
|
||||
SynthesisError,
|
||||
Circuit,
|
||||
ConstraintSystem,
|
||||
LinearCombination,
|
||||
Variable,
|
||||
Index
|
||||
};
|
||||
|
||||
use crate::domain::{
|
||||
Scalar
|
||||
};
|
||||
|
||||
use ::multicore::{
|
||||
Worker
|
||||
};
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::sonic::cs::{Backend, Basic, SynthesisDriver};
|
||||
use crate::sonic::srs::SRS;
|
||||
use crate::sonic::cs::LinearCombination as SonicLinearCombination;
|
||||
use crate::sonic::cs::Circuit as SonicCircuit;
|
||||
use crate::sonic::cs::ConstraintSystem as SonicConstraintSystem;
|
||||
use crate::sonic::cs::Variable as SonicVariable;
|
||||
use crate::sonic::cs::Coeff;
|
||||
use crate::sonic::sonic::{AdaptorCircuit};
|
||||
|
||||
use crate::verbose_flag;
|
||||
|
||||
/// Generates a random common reference string for
|
||||
/// a circuit.
|
||||
pub fn generate_random_parameters<E, C, R>(
|
||||
circuit: C,
|
||||
rng: &mut R
|
||||
) -> Result<Parameters<E>, SynthesisError>
|
||||
where E: Engine, C: Circuit<E>, R: Rng
|
||||
{
|
||||
let alpha = rng.gen();
|
||||
let x = rng.gen();
|
||||
|
||||
generate_parameters::<E, C>(
|
||||
circuit,
|
||||
alpha,
|
||||
x
|
||||
)
|
||||
}
|
||||
|
||||
/// This is our assembly structure that we'll use to synthesize the
|
||||
/// circuit into
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CircuitParameters<E: Engine> {
|
||||
pub num_inputs: usize,
|
||||
pub num_aux: usize,
|
||||
pub num_constraints: usize,
|
||||
pub k_map: Vec<usize>,
|
||||
pub n: usize,
|
||||
pub q: usize,
|
||||
_marker: PhantomData<E>
|
||||
}
|
||||
|
||||
/// This is our assembly structure that we'll use to synthesize the
|
||||
/// circuit into
|
||||
struct GeneratorAssembly<'a, E: Engine, CS: SonicConstraintSystem<E> + 'a> {
|
||||
cs: &'a mut CS,
|
||||
num_inputs: usize,
|
||||
num_aux: usize,
|
||||
num_constraints: usize,
|
||||
_marker: PhantomData<E>
|
||||
}
|
||||
|
||||
impl<'a, E: Engine, CS: SonicConstraintSystem<E> + 'a> crate::ConstraintSystem<E>
|
||||
for GeneratorAssembly<'a, E, CS>
|
||||
{
|
||||
type Root = Self;
|
||||
|
||||
// this is an important change
|
||||
fn one() -> crate::Variable {
|
||||
crate::Variable::new_unchecked(crate::Index::Input(1))
|
||||
}
|
||||
|
||||
fn alloc<F, A, AR>(&mut self, _: A, f: F) -> Result<crate::Variable, crate::SynthesisError>
|
||||
where
|
||||
F: FnOnce() -> Result<E::Fr, crate::SynthesisError>,
|
||||
A: FnOnce() -> AR,
|
||||
AR: Into<String>,
|
||||
{
|
||||
self.num_aux += 1;
|
||||
|
||||
let var = self.cs.alloc(|| {
|
||||
f().map_err(|_| crate::SynthesisError::AssignmentMissing)
|
||||
}).map_err(|_| crate::SynthesisError::AssignmentMissing)?;
|
||||
|
||||
Ok(match var {
|
||||
SonicVariable::A(index) => crate::Variable::new_unchecked(crate::Index::Input(index)),
|
||||
SonicVariable::B(index) => crate::Variable::new_unchecked(crate::Index::Aux(index)),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
}
|
||||
|
||||
fn alloc_input<F, A, AR>(
|
||||
&mut self,
|
||||
_: A,
|
||||
f: F,
|
||||
) -> Result<crate::Variable, crate::SynthesisError>
|
||||
where
|
||||
F: FnOnce() -> Result<E::Fr, crate::SynthesisError>,
|
||||
A: FnOnce() -> AR,
|
||||
AR: Into<String>,
|
||||
{
|
||||
self.num_inputs += 1;
|
||||
|
||||
let var = self.cs.alloc_input(|| {
|
||||
f().map_err(|_| crate::SynthesisError::AssignmentMissing)
|
||||
}).map_err(|_| crate::SynthesisError::AssignmentMissing)?;
|
||||
|
||||
Ok(match var {
|
||||
SonicVariable::A(index) => crate::Variable::new_unchecked(crate::Index::Input(index)),
|
||||
SonicVariable::B(index) => crate::Variable::new_unchecked(crate::Index::Aux(index)),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
}
|
||||
|
||||
fn enforce<A, AR, LA, LB, LC>(&mut self, _: A, a: LA, b: LB, c: LC)
|
||||
where
|
||||
A: FnOnce() -> AR,
|
||||
AR: Into<String>,
|
||||
LA: FnOnce(crate::LinearCombination<E>) -> crate::LinearCombination<E>,
|
||||
LB: FnOnce(crate::LinearCombination<E>) -> crate::LinearCombination<E>,
|
||||
LC: FnOnce(crate::LinearCombination<E>) -> crate::LinearCombination<E>,
|
||||
{
|
||||
fn convert<E: Engine>(lc: crate::LinearCombination<E>) -> SonicLinearCombination<E> {
|
||||
let mut ret = SonicLinearCombination::zero();
|
||||
|
||||
for &(v, coeff) in lc.as_ref().iter() {
|
||||
let var = match v.get_unchecked() {
|
||||
crate::Index::Input(i) => SonicVariable::A(i),
|
||||
crate::Index::Aux(i) => SonicVariable::B(i),
|
||||
};
|
||||
|
||||
ret = ret + (Coeff::Full(coeff), var);
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
fn eval<E: Engine, CS: SonicConstraintSystem<E>>(
|
||||
lc: &SonicLinearCombination<E>,
|
||||
cs: &CS,
|
||||
) -> Option<E::Fr> {
|
||||
let mut ret = E::Fr::zero();
|
||||
|
||||
for &(v, coeff) in lc.as_ref().iter() {
|
||||
let mut tmp = match cs.get_value(v) {
|
||||
Ok(tmp) => tmp,
|
||||
Err(_) => return None,
|
||||
};
|
||||
coeff.multiply(&mut tmp);
|
||||
ret.add_assign(&tmp);
|
||||
}
|
||||
|
||||
Some(ret)
|
||||
}
|
||||
|
||||
self.num_constraints += 1;
|
||||
|
||||
let a_lc = convert(a(crate::LinearCombination::zero()));
|
||||
let a_value = eval(&a_lc, &*self.cs);
|
||||
let b_lc = convert(b(crate::LinearCombination::zero()));
|
||||
let b_value = eval(&b_lc, &*self.cs);
|
||||
let c_lc = convert(c(crate::LinearCombination::zero()));
|
||||
let c_value = eval(&c_lc, &*self.cs);
|
||||
|
||||
let (a, b, c) = self
|
||||
.cs
|
||||
.multiply(|| Ok((a_value.unwrap(), b_value.unwrap(), c_value.unwrap())))
|
||||
.unwrap();
|
||||
|
||||
self.cs.enforce_zero(a_lc - a);
|
||||
self.cs.enforce_zero(b_lc - b);
|
||||
self.cs.enforce_zero(c_lc - c);
|
||||
}
|
||||
|
||||
fn push_namespace<NR, N>(&mut self, _: N)
|
||||
where
|
||||
NR: Into<String>,
|
||||
N: FnOnce() -> NR,
|
||||
{
|
||||
// Do nothing; we don't care about namespaces in this context.
|
||||
}
|
||||
|
||||
fn pop_namespace(&mut self) {
|
||||
// Do nothing; we don't care about namespaces in this context.
|
||||
}
|
||||
|
||||
fn get_root(&mut self) -> &mut Self::Root {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Create parameters for a circuit, given some toxic waste.
|
||||
fn get_circuit_parameters<E, C>(
|
||||
circuit: C,
|
||||
) -> Result<CircuitParameters<E>, SynthesisError>
|
||||
where E: Engine, C: Circuit<E>
|
||||
|
||||
{
|
||||
struct NonassigningSynthesizer<E: Engine, B: Backend<E>> {
|
||||
backend: B,
|
||||
current_variable: Option<usize>,
|
||||
_marker: PhantomData<E>,
|
||||
q: usize,
|
||||
n: usize,
|
||||
}
|
||||
|
||||
impl<E: Engine, B: Backend<E>> SonicConstraintSystem<E> for NonassigningSynthesizer<E, B> {
|
||||
const ONE: SonicVariable = SonicVariable::A(1);
|
||||
|
||||
fn alloc<F>(&mut self, value: F) -> Result<SonicVariable, SynthesisError>
|
||||
where
|
||||
F: FnOnce() -> Result<E::Fr, SynthesisError>
|
||||
{
|
||||
match self.current_variable.take() {
|
||||
Some(index) => {
|
||||
let var_b = SonicVariable::B(index);
|
||||
|
||||
self.current_variable = None;
|
||||
|
||||
Ok(var_b)
|
||||
},
|
||||
None => {
|
||||
self.n += 1;
|
||||
let index = self.n;
|
||||
self.backend.new_multiplication_gate();
|
||||
|
||||
let var_a = SonicVariable::A(index);
|
||||
|
||||
self.current_variable = Some(index);
|
||||
|
||||
Ok(var_a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn alloc_input<F>(&mut self, value: F) -> Result<SonicVariable, SynthesisError>
|
||||
where
|
||||
F: FnOnce() -> Result<E::Fr, SynthesisError>
|
||||
{
|
||||
let input_var = self.alloc(value)?;
|
||||
|
||||
self.enforce_zero(SonicLinearCombination::zero() + input_var);
|
||||
self.backend.new_k_power(self.q);
|
||||
|
||||
Ok(input_var)
|
||||
}
|
||||
|
||||
fn enforce_zero(&mut self, lc: SonicLinearCombination<E>)
|
||||
{
|
||||
self.q += 1;
|
||||
self.backend.new_linear_constraint();
|
||||
|
||||
for (var, coeff) in lc.as_ref() {
|
||||
self.backend.insert_coefficient(*var, *coeff);
|
||||
}
|
||||
}
|
||||
|
||||
fn multiply<F>(&mut self, values: F) -> Result<(SonicVariable, SonicVariable, SonicVariable), SynthesisError>
|
||||
where
|
||||
F: FnOnce() -> Result<(E::Fr, E::Fr, E::Fr), SynthesisError>
|
||||
{
|
||||
self.n += 1;
|
||||
let index = self.n;
|
||||
self.backend.new_multiplication_gate();
|
||||
|
||||
let a = SonicVariable::A(index);
|
||||
let b = SonicVariable::B(index);
|
||||
let c = SonicVariable::C(index);
|
||||
|
||||
Ok((a, b, c))
|
||||
}
|
||||
|
||||
fn get_value(&self, var: SonicVariable) -> Result<E::Fr, ()> {
|
||||
self.backend.get_var(var).ok_or(())
|
||||
}
|
||||
}
|
||||
|
||||
struct Preprocess<E: Engine> {
|
||||
k_map: Vec<usize>,
|
||||
n: usize,
|
||||
q: usize,
|
||||
_marker: PhantomData<E>
|
||||
}
|
||||
|
||||
impl<'a, E: Engine> Backend<E> for &'a mut Preprocess<E> {
|
||||
fn new_k_power(&mut self, index: usize) {
|
||||
self.k_map.push(index);
|
||||
}
|
||||
|
||||
fn new_multiplication_gate(&mut self) {
|
||||
self.n += 1;
|
||||
}
|
||||
|
||||
fn new_linear_constraint(&mut self) {
|
||||
self.q += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let mut preprocess = Preprocess { k_map: vec![], n: 0, q: 0, _marker: PhantomData };
|
||||
|
||||
let (num_inputs, num_aux, num_constraints) = {
|
||||
|
||||
let mut cs: NonassigningSynthesizer<E, &'_ mut Preprocess<E>> = NonassigningSynthesizer {
|
||||
backend: &mut preprocess,
|
||||
current_variable: None,
|
||||
_marker: PhantomData,
|
||||
q: 0,
|
||||
n: 0,
|
||||
};
|
||||
|
||||
let one = cs.alloc_input(|| Ok(E::Fr::one())).expect("should have no issues");
|
||||
|
||||
match (one, <NonassigningSynthesizer<E, &'_ mut Preprocess<E>> as SonicConstraintSystem<E>>::ONE) {
|
||||
(SonicVariable::A(1), SonicVariable::A(1)) => {},
|
||||
_ => return Err(SynthesisError::UnconstrainedVariable)
|
||||
}
|
||||
|
||||
// let adapted_circuit = AdaptorCircuit(circuit);
|
||||
|
||||
|
||||
let mut assembly = GeneratorAssembly::<'_, E, _> {
|
||||
cs: &mut cs,
|
||||
num_inputs: 0,
|
||||
num_aux: 0,
|
||||
num_constraints: 0,
|
||||
_marker: PhantomData
|
||||
};
|
||||
|
||||
circuit.synthesize(&mut assembly)?;
|
||||
|
||||
(assembly.num_inputs, assembly.num_aux, assembly.num_constraints)
|
||||
};
|
||||
|
||||
Ok(CircuitParameters {
|
||||
num_inputs: num_inputs,
|
||||
num_aux: num_aux,
|
||||
num_constraints: num_constraints,
|
||||
k_map: preprocess.k_map,
|
||||
n: preprocess.n,
|
||||
q: preprocess.q,
|
||||
_marker: PhantomData
|
||||
})
|
||||
}
|
||||
|
||||
pub fn generate_parameters<E, C>(
|
||||
circuit: C,
|
||||
alpha: E::Fr,
|
||||
x: E::Fr
|
||||
) -> Result<Parameters<E>, SynthesisError>
|
||||
where E: Engine, C: Circuit<E>
|
||||
{
|
||||
let circuit_parameters = get_circuit_parameters::<E, C>(circuit)?;
|
||||
let min_d = circuit_parameters.n * 3;
|
||||
|
||||
let srs = generate_srs(alpha, x, min_d)?;
|
||||
|
||||
let parameters = generate_parameters_on_srs_and_information::<E>(&srs, circuit_parameters)?;
|
||||
|
||||
Ok(parameters)
|
||||
}
|
||||
|
||||
pub fn generate_parameters_on_srs<E, C>(
|
||||
circuit: C,
|
||||
srs: &SRS<E>,
|
||||
) -> Result<Parameters<E>, SynthesisError>
|
||||
where E: Engine, C: Circuit<E>
|
||||
{
|
||||
let circuit_parameters = get_circuit_parameters::<E, C>(circuit)?;
|
||||
let parameters = generate_parameters_on_srs_and_information(&srs, circuit_parameters)?;
|
||||
|
||||
Ok(parameters)
|
||||
}
|
||||
|
||||
pub fn generate_parameters_on_srs_and_information<E: Engine>(
|
||||
srs: &SRS<E>,
|
||||
information: CircuitParameters<E>
|
||||
) -> Result<Parameters<E>, SynthesisError>
|
||||
{
|
||||
assert!(srs.d >= information.n * 3);
|
||||
let min_d = information.n * 3;
|
||||
|
||||
let trimmed_srs: SRS<E> = SRS {
|
||||
d: min_d,
|
||||
g_negative_x: srs.g_negative_x[0..min_d+1].to_vec(),
|
||||
g_positive_x: srs.g_positive_x[0..min_d+1].to_vec().clone(),
|
||||
|
||||
h_negative_x: srs.h_negative_x[0..min_d+1].to_vec(),
|
||||
h_positive_x: srs.h_positive_x[0..min_d+1].to_vec(),
|
||||
|
||||
g_negative_x_alpha: srs.g_negative_x_alpha[0..min_d].to_vec(),
|
||||
g_positive_x_alpha: srs.g_positive_x_alpha[0..min_d].to_vec(),
|
||||
|
||||
h_negative_x_alpha: srs.h_negative_x_alpha[0..min_d+1].to_vec(),
|
||||
h_positive_x_alpha: srs.h_positive_x_alpha[0..min_d+1].to_vec(),
|
||||
|
||||
};
|
||||
|
||||
let vk = VerifyingKey {
|
||||
alpha_x: trimmed_srs.h_positive_x_alpha[1],
|
||||
|
||||
alpha: trimmed_srs.h_positive_x_alpha[0],
|
||||
|
||||
neg_h: {
|
||||
let mut tmp = trimmed_srs.h_negative_x[0];
|
||||
tmp.negate();
|
||||
|
||||
tmp
|
||||
},
|
||||
|
||||
neg_x_n_minus_d: {
|
||||
let mut tmp = trimmed_srs.h_negative_x[trimmed_srs.d - information.n];
|
||||
tmp.negate();
|
||||
|
||||
tmp
|
||||
},
|
||||
|
||||
k_map: information.k_map,
|
||||
n: information.n,
|
||||
q: information.q
|
||||
};
|
||||
|
||||
Ok(Parameters{
|
||||
vk: vk,
|
||||
d: trimmed_srs.d,
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn generate_srs<E: Engine>(
|
||||
alpha: E::Fr,
|
||||
x: E::Fr,
|
||||
d: usize
|
||||
) -> Result<SRS<E>, SynthesisError> {
|
||||
let verbose = verbose_flag();
|
||||
|
||||
let g1 = E::G1Affine::one().into_projective();
|
||||
let g2 = E::G2Affine::one().into_projective();
|
||||
|
||||
// Compute G1 window table
|
||||
let mut g1_wnaf = Wnaf::new();
|
||||
let g1_wnaf = g1_wnaf.base(g1, 4*d);
|
||||
|
||||
// Compute G2 window table
|
||||
let mut g2_wnaf = Wnaf::new();
|
||||
let g2_wnaf = g2_wnaf.base(g2, 4*d);
|
||||
|
||||
let x_inverse = x.inverse().ok_or(SynthesisError::UnexpectedIdentity)?;
|
||||
|
||||
let worker = Worker::new();
|
||||
|
||||
let mut x_powers_positive = vec![Scalar::<E>(E::Fr::zero()); d];
|
||||
let mut x_powers_negative = vec![Scalar::<E>(E::Fr::zero()); d];
|
||||
{
|
||||
// Compute powers of tau
|
||||
if verbose {eprintln!("computing powers of tau...")};
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
{
|
||||
worker.scope(d, |scope, chunk| {
|
||||
for (i, x_powers) in x_powers_positive.chunks_mut(chunk).enumerate()
|
||||
{
|
||||
scope.spawn(move |_| {
|
||||
let mut current_power = x.pow(&[(i*chunk + 1) as u64]);
|
||||
|
||||
for p in x_powers {
|
||||
p.0 = current_power;
|
||||
current_power.mul_assign(&x);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
{
|
||||
worker.scope(d, |scope, chunk| {
|
||||
for (i, x_powers) in x_powers_negative.chunks_mut(chunk).enumerate()
|
||||
{
|
||||
scope.spawn(move |_| {
|
||||
let mut current_power = x_inverse.pow(&[(i*chunk + 1) as u64]);
|
||||
|
||||
for p in x_powers {
|
||||
p.0 = current_power;
|
||||
current_power.mul_assign(&x_inverse);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if verbose {eprintln!("powers of x done in {} s", start.elapsed().as_millis() as f64 / 1000.0);};
|
||||
}
|
||||
|
||||
// we will later add zero powers to g_x, h_x, h_x_alpha
|
||||
let mut g_negative_x = vec![E::G1::one(); d];
|
||||
let mut g_positive_x = vec![E::G1::one(); d];
|
||||
|
||||
let mut h_negative_x = vec![E::G2::one(); d];
|
||||
let mut h_positive_x = vec![E::G2::one(); d];
|
||||
|
||||
let mut g_negative_x_alpha = vec![E::G1::one(); d];
|
||||
let mut g_positive_x_alpha = vec![E::G1::one(); d];
|
||||
|
||||
let mut h_negative_x_alpha = vec![E::G2::one(); d];
|
||||
let mut h_positive_x_alpha = vec![E::G2::one(); d];
|
||||
|
||||
fn eval<E: Engine>(
|
||||
// wNAF window tables
|
||||
g1_wnaf: &Wnaf<usize, &[E::G1], &mut Vec<i64>>,
|
||||
g2_wnaf: &Wnaf<usize, &[E::G2], &mut Vec<i64>>,
|
||||
|
||||
powers_of_x: &[Scalar<E>],
|
||||
|
||||
g_x: &mut [E::G1],
|
||||
g_x_alpha: &mut [E::G1],
|
||||
h_x: &mut [E::G2],
|
||||
h_x_alpha: &mut [E::G2],
|
||||
|
||||
// Trapdoors
|
||||
alpha: &E::Fr,
|
||||
|
||||
// Worker
|
||||
worker: &Worker
|
||||
)
|
||||
|
||||
{
|
||||
// Sanity check
|
||||
assert_eq!(g_x.len(), powers_of_x.len());
|
||||
assert_eq!(g_x.len(), g_x_alpha.len());
|
||||
assert_eq!(g_x.len(), h_x.len());
|
||||
assert_eq!(g_x.len(), h_x_alpha.len());
|
||||
|
||||
// Evaluate polynomials in multiple threads
|
||||
worker.scope(g_x.len(), |scope, chunk| {
|
||||
for ((((x, g_x), g_x_alpha), h_x), h_x_alpha) in powers_of_x.chunks(chunk)
|
||||
.zip(g_x.chunks_mut(chunk))
|
||||
.zip(g_x_alpha.chunks_mut(chunk))
|
||||
.zip(h_x.chunks_mut(chunk))
|
||||
.zip(h_x_alpha.chunks_mut(chunk))
|
||||
{
|
||||
let mut g1_wnaf = g1_wnaf.shared();
|
||||
let mut g2_wnaf = g2_wnaf.shared();
|
||||
|
||||
scope.spawn(move |_| {
|
||||
for ((((x, g_x), g_x_alpha), h_x), h_x_alpha) in x.iter()
|
||||
.zip(g_x.iter_mut())
|
||||
.zip(g_x_alpha.iter_mut())
|
||||
.zip(h_x.iter_mut())
|
||||
.zip(h_x_alpha.iter_mut())
|
||||
{
|
||||
let mut x_alpha = x.0;
|
||||
x_alpha.mul_assign(&alpha);
|
||||
|
||||
*g_x = g1_wnaf.scalar(x.0.into_repr());
|
||||
*h_x = g2_wnaf.scalar(x.0.into_repr());
|
||||
|
||||
*g_x_alpha = g1_wnaf.scalar(x_alpha.into_repr());
|
||||
*h_x_alpha = g2_wnaf.scalar(x_alpha.into_repr());
|
||||
}
|
||||
|
||||
// Batch normalize
|
||||
E::G1::batch_normalization(g_x);
|
||||
E::G1::batch_normalization(g_x_alpha);
|
||||
E::G2::batch_normalization(h_x);
|
||||
E::G2::batch_normalization(h_x_alpha);
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
// Evaluate for positive powers.
|
||||
eval(
|
||||
&g1_wnaf,
|
||||
&g2_wnaf,
|
||||
&x_powers_positive,
|
||||
&mut g_positive_x[..],
|
||||
&mut g_positive_x_alpha[..],
|
||||
&mut h_positive_x[..],
|
||||
&mut h_positive_x_alpha[..],
|
||||
&alpha,
|
||||
&worker
|
||||
);
|
||||
|
||||
// Evaluate for auxillary variables.
|
||||
eval(
|
||||
&g1_wnaf,
|
||||
&g2_wnaf,
|
||||
&x_powers_negative,
|
||||
&mut g_negative_x[..],
|
||||
&mut g_negative_x_alpha[..],
|
||||
&mut h_negative_x[..],
|
||||
&mut h_negative_x_alpha[..],
|
||||
&alpha,
|
||||
&worker
|
||||
);
|
||||
|
||||
if verbose {eprintln!("evaluating points done in {} s", start.elapsed().as_millis() as f64 / 1000.0);};
|
||||
|
||||
let g1 = g1.into_affine();
|
||||
let g2 = g2.into_affine();
|
||||
|
||||
let h_alpha = g2.mul(alpha.into_repr()).into_affine();
|
||||
|
||||
let g_negative_x = {
|
||||
let mut tmp = vec![g1];
|
||||
tmp.extend(g_negative_x.into_iter().map(|e| e.into_affine()));
|
||||
|
||||
tmp
|
||||
};
|
||||
let g_positive_x = {
|
||||
let mut tmp = vec![g1];
|
||||
tmp.extend(g_positive_x.into_iter().map(|e| e.into_affine()));
|
||||
|
||||
tmp
|
||||
};
|
||||
|
||||
let h_negative_x = {
|
||||
let mut tmp = vec![g2];
|
||||
tmp.extend(h_negative_x.into_iter().map(|e| e.into_affine()));
|
||||
|
||||
tmp
|
||||
};
|
||||
let h_positive_x = {
|
||||
let mut tmp = vec![g2];
|
||||
tmp.extend(h_positive_x.into_iter().map(|e| e.into_affine()));
|
||||
|
||||
tmp
|
||||
};
|
||||
|
||||
let g_negative_x_alpha = g_negative_x_alpha.into_iter().map(|e| e.into_affine()).collect();
|
||||
let g_positive_x_alpha = g_positive_x_alpha.into_iter().map(|e| e.into_affine()).collect();
|
||||
|
||||
let h_negative_x_alpha = {
|
||||
let mut tmp = vec![h_alpha];
|
||||
tmp.extend(h_negative_x_alpha.into_iter().map(|e| e.into_affine()));
|
||||
|
||||
tmp
|
||||
};
|
||||
let h_positive_x_alpha = {
|
||||
let mut tmp = vec![h_alpha];
|
||||
tmp.extend(h_positive_x_alpha.into_iter().map(|e| e.into_affine()));
|
||||
|
||||
tmp
|
||||
};
|
||||
|
||||
Ok(SRS {
|
||||
d: d,
|
||||
g_negative_x: g_negative_x,
|
||||
g_positive_x: g_positive_x,
|
||||
|
||||
h_negative_x: h_negative_x,
|
||||
h_positive_x: h_positive_x,
|
||||
|
||||
g_negative_x_alpha: g_negative_x_alpha,
|
||||
g_positive_x_alpha: g_positive_x_alpha,
|
||||
|
||||
h_negative_x_alpha: h_negative_x_alpha,
|
||||
h_positive_x_alpha: h_positive_x_alpha,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parameters_generation() {
|
||||
use pairing::bls12_381::{Bls12, Fr};
|
||||
struct MySillyCircuit<E: Engine> {
|
||||
a: Option<E::Fr>,
|
||||
b: Option<E::Fr>
|
||||
}
|
||||
|
||||
impl<E: Engine> Circuit<E> for MySillyCircuit<E> {
|
||||
fn synthesize<CS: ConstraintSystem<E>>(
|
||||
self,
|
||||
cs: &mut CS
|
||||
) -> Result<(), SynthesisError>
|
||||
{
|
||||
let a = cs.alloc(|| "a", || self.a.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
let b = cs.alloc(|| "b", || self.b.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
let c = cs.alloc_input(|| "c", || {
|
||||
let mut a = self.a.ok_or(SynthesisError::AssignmentMissing)?;
|
||||
let b = self.b.ok_or(SynthesisError::AssignmentMissing)?;
|
||||
|
||||
a.mul_assign(&b);
|
||||
Ok(a)
|
||||
})?;
|
||||
|
||||
cs.enforce(
|
||||
|| "a*b=c",
|
||||
|lc| lc + a,
|
||||
|lc| lc + b,
|
||||
|lc| lc + c
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
use rand::{Rand, thread_rng};
|
||||
|
||||
let info = get_circuit_parameters::<Bls12, _>(MySillyCircuit { a: None, b: None }).expect("Must get circuit info");
|
||||
|
||||
let rng = &mut thread_rng();
|
||||
|
||||
let x: Fr = rng.gen();
|
||||
let alpha: Fr = rng.gen();
|
||||
|
||||
let params = generate_parameters::<Bls12, _>(MySillyCircuit { a: None, b: None }, alpha, x).unwrap();
|
||||
let srs = generate_srs::<Bls12>(alpha, x, info.n * 100).unwrap();
|
||||
let naive_srs = SRS::<Bls12>::new(
|
||||
info.n * 100,
|
||||
x,
|
||||
alpha,
|
||||
);
|
||||
|
||||
assert!(srs == naive_srs);
|
||||
|
||||
let params_on_srs = generate_parameters_on_srs_and_information::<Bls12>(&srs, info.clone()).unwrap();
|
||||
|
||||
assert!(params == params_on_srs);
|
||||
|
||||
{
|
||||
let mut v = vec![];
|
||||
|
||||
params.write(&mut v).unwrap();
|
||||
|
||||
let de_params = Parameters::read(&v[..], true).unwrap();
|
||||
assert!(params == de_params);
|
||||
|
||||
let de_params = Parameters::read(&v[..], false).unwrap();
|
||||
assert!(params == de_params);
|
||||
}
|
||||
|
||||
// let pvk = prepare_verifying_key::<Bls12>(¶ms.vk);
|
||||
|
||||
// for _ in 0..100 {
|
||||
// let a = Fr::rand(rng);
|
||||
// let b = Fr::rand(rng);
|
||||
// let mut c = a;
|
||||
// c.mul_assign(&b);
|
||||
|
||||
// let proof = create_random_proof(
|
||||
// MySillyCircuit {
|
||||
// a: Some(a),
|
||||
// b: Some(b)
|
||||
// },
|
||||
// ¶ms,
|
||||
// rng
|
||||
// ).unwrap();
|
||||
|
||||
// let mut v = vec![];
|
||||
// proof.write(&mut v).unwrap();
|
||||
|
||||
// assert_eq!(v.len(), 192);
|
||||
|
||||
// let de_proof = Proof::read(&v[..]).unwrap();
|
||||
// assert!(proof == de_proof);
|
||||
|
||||
// assert!(verify_proof(&pvk, &proof, &[c]).unwrap());
|
||||
// assert!(!verify_proof(&pvk, &proof, &[a]).unwrap());
|
||||
// }
|
||||
}
|
@ -10,25 +10,11 @@ mod prover;
|
||||
mod batch;
|
||||
mod poly;
|
||||
mod helper;
|
||||
mod parameters;
|
||||
mod generator;
|
||||
|
||||
pub use self::batch::{Batch, VerifyingKey};
|
||||
pub use self::batch::{Batch};
|
||||
pub use self::helper::{Aggregate, create_aggregate};
|
||||
pub use self::verifier::{MultiVerifier};
|
||||
pub use self::prover::{create_proof, create_advice};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SxyAdvice<E: Engine> {
|
||||
pub s: E::G1Affine,
|
||||
pub opening: E::G1Affine,
|
||||
pub szy: E::Fr,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Proof<E: Engine> {
|
||||
pub r: E::G1Affine,
|
||||
pub t: E::G1Affine,
|
||||
pub rz: E::Fr,
|
||||
pub rzy: E::Fr,
|
||||
pub z_opening: E::G1Affine,
|
||||
pub zy_opening: E::G1Affine
|
||||
}
|
||||
pub use self::parameters::{Proof, SxyAdvice, Parameters, VerifyingKey, PreparedVerifyingKey};
|
689
src/sonic/helped/parameters.rs
Normal file
689
src/sonic/helped/parameters.rs
Normal file
@ -0,0 +1,689 @@
|
||||
use ff::{
|
||||
Field,
|
||||
PrimeField,
|
||||
PrimeFieldRepr
|
||||
};
|
||||
|
||||
use pairing::{
|
||||
Engine,
|
||||
CurveAffine,
|
||||
EncodedPoint
|
||||
};
|
||||
|
||||
use ::{
|
||||
SynthesisError
|
||||
};
|
||||
|
||||
use multiexp::SourceBuilder;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::sync::Arc;
|
||||
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct SxyAdvice<E: Engine> {
|
||||
pub s: E::G1Affine,
|
||||
pub opening: E::G1Affine,
|
||||
pub szy: E::Fr,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Proof<E: Engine> {
|
||||
pub r: E::G1Affine,
|
||||
pub t: E::G1Affine,
|
||||
pub rz: E::Fr,
|
||||
pub rzy: E::Fr,
|
||||
pub z_opening: E::G1Affine,
|
||||
pub zy_opening: E::G1Affine
|
||||
}
|
||||
|
||||
impl<E: Engine> Proof<E> {
|
||||
pub fn write<W: Write>(
|
||||
&self,
|
||||
mut writer: W
|
||||
) -> io::Result<()>
|
||||
{
|
||||
use ff::{PrimeField, PrimeFieldRepr};
|
||||
writer.write_all(self.r.into_compressed().as_ref())?;
|
||||
writer.write_all(self.t.into_compressed().as_ref())?;
|
||||
let mut buffer = vec![];
|
||||
self.rz.into_repr().write_be(&mut buffer)?;
|
||||
writer.write_all(&buffer[..])?;
|
||||
self.rzy.into_repr().write_be(&mut buffer)?;
|
||||
writer.write_all(&buffer[..])?;
|
||||
writer.write_all(self.z_opening.into_compressed().as_ref())?;
|
||||
writer.write_all(self.zy_opening.into_compressed().as_ref())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read<R: Read>(
|
||||
mut reader: R
|
||||
) -> io::Result<Self>
|
||||
{
|
||||
let mut g1_repr = <E::G1Affine as CurveAffine>::Compressed::empty();
|
||||
let mut fr_repr = E::Fr::zero().into_repr();
|
||||
|
||||
reader.read_exact(g1_repr.as_mut())?;
|
||||
let r = g1_repr
|
||||
.into_affine()
|
||||
.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)
|
||||
})?;
|
||||
|
||||
reader.read_exact(g1_repr.as_mut())?;
|
||||
let t = g1_repr
|
||||
.into_affine()
|
||||
.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)
|
||||
})?;
|
||||
|
||||
fr_repr.read_be(&mut reader)?;
|
||||
let rz = E::Fr::from_repr(fr_repr)
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
|
||||
.and_then(|e| if e.is_zero() {
|
||||
Err(io::Error::new(io::ErrorKind::InvalidData, "field element is zero"))
|
||||
} else {
|
||||
Ok(e)
|
||||
})?;
|
||||
|
||||
fr_repr.read_be(&mut reader)?;
|
||||
let rzy = E::Fr::from_repr(fr_repr)
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
|
||||
.and_then(|e| if e.is_zero() {
|
||||
Err(io::Error::new(io::ErrorKind::InvalidData, "field element is zero"))
|
||||
} else {
|
||||
Ok(e)
|
||||
})?;
|
||||
|
||||
|
||||
reader.read_exact(g1_repr.as_mut())?;
|
||||
let z_opening = g1_repr
|
||||
.into_affine()
|
||||
.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)
|
||||
})?;
|
||||
|
||||
reader.read_exact(g1_repr.as_mut())?;
|
||||
let zy_opening = g1_repr
|
||||
.into_affine()
|
||||
.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)
|
||||
})?;
|
||||
|
||||
Ok(Proof {
|
||||
r: r,
|
||||
t: t,
|
||||
rz: rz,
|
||||
rzy: rzy,
|
||||
z_opening: z_opening,
|
||||
zy_opening: zy_opening
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq)]
|
||||
pub struct VerifyingKey<E: Engine> {
|
||||
pub alpha_x: E::G2Affine,
|
||||
|
||||
pub alpha: E::G2Affine,
|
||||
|
||||
pub neg_h: E::G2Affine,
|
||||
|
||||
pub neg_x_n_minus_d: E::G2Affine,
|
||||
|
||||
pub k_map: Vec<usize>,
|
||||
|
||||
pub n: usize,
|
||||
|
||||
pub q: usize
|
||||
}
|
||||
|
||||
impl<E: Engine> PartialEq for VerifyingKey<E> {
|
||||
fn eq(&self, other: &VerifyingKey<E>) -> bool {
|
||||
self.alpha_x == other.alpha_x &&
|
||||
self.alpha == other.alpha &&
|
||||
self.neg_h == other.neg_h &&
|
||||
self.neg_x_n_minus_d == other.neg_x_n_minus_d &&
|
||||
self.k_map == other.k_map &&
|
||||
self.n == other.n &&
|
||||
self.q == other.q
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> VerifyingKey<E> {
|
||||
pub fn write<W: Write>(
|
||||
&self,
|
||||
mut writer: W
|
||||
) -> io::Result<()>
|
||||
{
|
||||
writer.write_all(self.alpha_x.into_uncompressed().as_ref())?;
|
||||
writer.write_all(self.alpha.into_uncompressed().as_ref())?;
|
||||
writer.write_all(self.neg_h.into_uncompressed().as_ref())?;
|
||||
writer.write_all(self.neg_x_n_minus_d.into_uncompressed().as_ref())?;
|
||||
|
||||
writer.write_u32::<BigEndian>(self.k_map.len() as u32)?;
|
||||
for k in &self.k_map {
|
||||
writer.write_u32::<BigEndian>(*k as u32)?;
|
||||
}
|
||||
writer.write_u32::<BigEndian>(self.n as u32)?;
|
||||
writer.write_u32::<BigEndian>(self.q as u32)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read<R: Read>(
|
||||
mut reader: R
|
||||
) -> io::Result<Self>
|
||||
{
|
||||
let mut g2_repr = <E::G2Affine as CurveAffine>::Uncompressed::empty();
|
||||
|
||||
reader.read_exact(g2_repr.as_mut())?;
|
||||
let alpha_x = g2_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
||||
|
||||
reader.read_exact(g2_repr.as_mut())?;
|
||||
let alpha = g2_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
||||
|
||||
reader.read_exact(g2_repr.as_mut())?;
|
||||
let neg_h = g2_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
||||
|
||||
reader.read_exact(g2_repr.as_mut())?;
|
||||
let neg_x_n_minus_d = g2_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
||||
|
||||
let k_map_len = reader.read_u32::<BigEndian>()? as usize;
|
||||
|
||||
let mut k_map = vec![];
|
||||
|
||||
for _ in 0..k_map_len {
|
||||
let k = reader.read_u32::<BigEndian>()? as usize;
|
||||
|
||||
k_map.push(k);
|
||||
}
|
||||
|
||||
let n = reader.read_u32::<BigEndian>()? as usize;
|
||||
|
||||
let q = reader.read_u32::<BigEndian>()? as usize;
|
||||
|
||||
Ok(VerifyingKey {
|
||||
alpha_x: alpha_x,
|
||||
alpha: alpha,
|
||||
neg_h: neg_h,
|
||||
neg_x_n_minus_d: neg_x_n_minus_d,
|
||||
k_map: k_map,
|
||||
n: n,
|
||||
q: q
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
use crate::sonic::cs::{Backend, Basic, SynthesisDriver};
|
||||
use crate::sonic::srs::SRS;
|
||||
use crate::sonic::cs::Circuit as SonicCircuit;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
impl<E: Engine> VerifyingKey<E> {
|
||||
pub fn new<C: SonicCircuit<E>, S: SynthesisDriver>(circuit: C, srs: &SRS<E>) -> Result<Self, SynthesisError> {
|
||||
struct Preprocess<E: Engine> {
|
||||
k_map: Vec<usize>,
|
||||
n: usize,
|
||||
q: usize,
|
||||
_marker: PhantomData<E>
|
||||
}
|
||||
|
||||
impl<'a, E: Engine> Backend<E> for &'a mut Preprocess<E> {
|
||||
fn new_k_power(&mut self, index: usize) {
|
||||
self.k_map.push(index);
|
||||
}
|
||||
|
||||
fn new_multiplication_gate(&mut self) {
|
||||
self.n += 1;
|
||||
}
|
||||
|
||||
fn new_linear_constraint(&mut self) {
|
||||
self.q += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let mut preprocess = Preprocess { k_map: vec![], n: 0, q: 0, _marker: PhantomData };
|
||||
|
||||
S::synthesize(&mut preprocess, &circuit)?;
|
||||
|
||||
Ok(Self {
|
||||
alpha_x: srs.h_positive_x_alpha[1],
|
||||
|
||||
alpha: srs.h_positive_x_alpha[0],
|
||||
|
||||
neg_h: {
|
||||
let mut tmp = srs.h_negative_x[0];
|
||||
tmp.negate();
|
||||
|
||||
tmp
|
||||
},
|
||||
|
||||
neg_x_n_minus_d: {
|
||||
let mut tmp = srs.h_negative_x[srs.d - preprocess.n];
|
||||
tmp.negate();
|
||||
|
||||
tmp
|
||||
},
|
||||
|
||||
k_map: preprocess.k_map,
|
||||
n: preprocess.n,
|
||||
q: preprocess.q
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PreparedVerifyingKey<E: Engine> {
|
||||
alpha_x: <E::G2Affine as CurveAffine>::Prepared,
|
||||
alpha: <E::G2Affine as CurveAffine>::Prepared,
|
||||
neg_h: <E::G2Affine as CurveAffine>::Prepared,
|
||||
neg_x_n_minus_d: <E::G2Affine as CurveAffine>::Prepared,
|
||||
k_map: Vec<usize>,
|
||||
n: usize,
|
||||
q: usize
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq)]
|
||||
pub struct Parameters<E: Engine> {
|
||||
pub vk: VerifyingKey<E>,
|
||||
|
||||
pub d: usize,
|
||||
|
||||
// g^{x^0}, g^{x^{-1}}, g^{x^{-2}}, ..., g^{x^{-d}}
|
||||
pub g_negative_x: Arc<Vec<E::G1Affine>>,
|
||||
|
||||
// g^{x^0}, g^{x^{1}}, g^{x^{2}}, ..., g^{x^{d}}
|
||||
pub g_positive_x: Arc<Vec<E::G1Affine>>,
|
||||
|
||||
// g^{x^0}, g^{x^{-1}}, g^{x^{-2}}, ..., g^{x^{-d}}
|
||||
pub h_negative_x: Arc<Vec<E::G2Affine>>,
|
||||
|
||||
// g^{x^0}, g^{x^{1}}, g^{x^{2}}, ..., g^{x^{d}}
|
||||
pub h_positive_x: Arc<Vec<E::G2Affine>>,
|
||||
|
||||
// alpha*(g^{x^{-1}}, g^{x^{-2}}, ..., g^{x^{-d}})
|
||||
pub g_negative_x_alpha: Arc<Vec<E::G1Affine>>,
|
||||
|
||||
// alpha*(g^{x^{1}}, g^{x^{2}}, ..., g^{x^{d}})
|
||||
pub g_positive_x_alpha: Arc<Vec<E::G1Affine>>,
|
||||
|
||||
// alpha*(h^{x^0}, h^{x^{-1}}, g^{x^{-2}}, ..., g^{x^{-d}})
|
||||
pub h_negative_x_alpha: Arc<Vec<E::G2Affine>>,
|
||||
|
||||
// alpha*(h^{x^0}, g^{x^{1}}, g^{x^{2}}, ..., g^{x^{d}})
|
||||
pub h_positive_x_alpha: Arc<Vec<E::G2Affine>>,
|
||||
}
|
||||
|
||||
impl<E: Engine> PartialEq for Parameters<E> {
|
||||
fn eq(&self, other: &Parameters<E>) -> bool {
|
||||
self.vk == other.vk &&
|
||||
self.d == other.d &&
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> Parameters<E> {
|
||||
pub fn write<W: Write>(
|
||||
&self,
|
||||
mut writer: W
|
||||
) -> io::Result<()>
|
||||
{
|
||||
self.vk.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(())
|
||||
}
|
||||
|
||||
pub fn read<R: Read>(
|
||||
mut reader: R,
|
||||
checked: bool
|
||||
) -> 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 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 {
|
||||
vk: vk,
|
||||
d: d,
|
||||
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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// pub trait ParameterSource<E: Engine> {
|
||||
// type G1Builder: SourceBuilder<E::G1Affine>;
|
||||
// type G2Builder: SourceBuilder<E::G2Affine>;
|
||||
|
||||
// fn get_vk(
|
||||
// &mut self,
|
||||
// num_ic: usize
|
||||
// ) -> Result<VerifyingKey<E>, SynthesisError>;
|
||||
// fn get_h(
|
||||
// &mut self,
|
||||
// num_h: usize
|
||||
// ) -> Result<Self::G1Builder, SynthesisError>;
|
||||
// fn get_l(
|
||||
// &mut self,
|
||||
// num_l: usize
|
||||
// ) -> Result<Self::G1Builder, SynthesisError>;
|
||||
// fn get_a(
|
||||
// &mut self,
|
||||
// num_inputs: usize,
|
||||
// num_aux: usize
|
||||
// ) -> Result<(Self::G1Builder, Self::G1Builder), SynthesisError>;
|
||||
// fn get_b_g1(
|
||||
// &mut self,
|
||||
// num_inputs: usize,
|
||||
// num_aux: usize
|
||||
// ) -> Result<(Self::G1Builder, Self::G1Builder), SynthesisError>;
|
||||
// fn get_b_g2(
|
||||
// &mut self,
|
||||
// num_inputs: usize,
|
||||
// num_aux: usize
|
||||
// ) -> Result<(Self::G2Builder, Self::G2Builder), SynthesisError>;
|
||||
// }
|
||||
|
||||
// impl<'a, E: Engine> ParameterSource<E> for &'a Parameters<E> {
|
||||
// type G1Builder = (Arc<Vec<E::G1Affine>>, usize);
|
||||
// type G2Builder = (Arc<Vec<E::G2Affine>>, usize);
|
||||
|
||||
// fn get_vk(
|
||||
// &mut self,
|
||||
// _: usize
|
||||
// ) -> Result<VerifyingKey<E>, SynthesisError>
|
||||
// {
|
||||
// Ok(self.vk.clone())
|
||||
// }
|
||||
|
||||
// fn get_h(
|
||||
// &mut self,
|
||||
// _: usize
|
||||
// ) -> Result<Self::G1Builder, SynthesisError>
|
||||
// {
|
||||
// Ok((self.h.clone(), 0))
|
||||
// }
|
||||
|
||||
// fn get_l(
|
||||
// &mut self,
|
||||
// _: usize
|
||||
// ) -> Result<Self::G1Builder, SynthesisError>
|
||||
// {
|
||||
// Ok((self.l.clone(), 0))
|
||||
// }
|
||||
|
||||
// fn get_a(
|
||||
// &mut self,
|
||||
// num_inputs: usize,
|
||||
// _: usize
|
||||
// ) -> Result<(Self::G1Builder, Self::G1Builder), SynthesisError>
|
||||
// {
|
||||
// Ok(((self.a.clone(), 0), (self.a.clone(), num_inputs)))
|
||||
// }
|
||||
|
||||
// fn get_b_g1(
|
||||
// &mut self,
|
||||
// num_inputs: usize,
|
||||
// _: usize
|
||||
// ) -> Result<(Self::G1Builder, Self::G1Builder), SynthesisError>
|
||||
// {
|
||||
// Ok(((self.b_g1.clone(), 0), (self.b_g1.clone(), num_inputs)))
|
||||
// }
|
||||
|
||||
// fn get_b_g2(
|
||||
// &mut self,
|
||||
// num_inputs: usize,
|
||||
// _: usize
|
||||
// ) -> Result<(Self::G2Builder, Self::G2Builder), SynthesisError>
|
||||
// {
|
||||
// Ok(((self.b_g2.clone(), 0), (self.b_g2.clone(), num_inputs)))
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[cfg(test)]
|
||||
// mod test_with_bls12_381 {
|
||||
// use super::*;
|
||||
// use {Circuit, SynthesisError, ConstraintSystem};
|
||||
|
||||
// use rand::{Rand, thread_rng};
|
||||
// use ff::{Field};
|
||||
// use pairing::bls12_381::{Bls12, Fr};
|
||||
|
||||
// #[test]
|
||||
// fn serialization() {
|
||||
// struct MySillyCircuit<E: Engine> {
|
||||
// a: Option<E::Fr>,
|
||||
// b: Option<E::Fr>
|
||||
// }
|
||||
|
||||
// impl<E: Engine> Circuit<E> for MySillyCircuit<E> {
|
||||
// fn synthesize<CS: ConstraintSystem<E>>(
|
||||
// self,
|
||||
// cs: &mut CS
|
||||
// ) -> Result<(), SynthesisError>
|
||||
// {
|
||||
// let a = cs.alloc(|| "a", || self.a.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
// let b = cs.alloc(|| "b", || self.b.ok_or(SynthesisError::AssignmentMissing))?;
|
||||
// let c = cs.alloc_input(|| "c", || {
|
||||
// let mut a = self.a.ok_or(SynthesisError::AssignmentMissing)?;
|
||||
// let b = self.b.ok_or(SynthesisError::AssignmentMissing)?;
|
||||
|
||||
// a.mul_assign(&b);
|
||||
// Ok(a)
|
||||
// })?;
|
||||
|
||||
// cs.enforce(
|
||||
// || "a*b=c",
|
||||
// |lc| lc + a,
|
||||
// |lc| lc + b,
|
||||
// |lc| lc + c
|
||||
// );
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
// }
|
||||
|
||||
// let rng = &mut thread_rng();
|
||||
|
||||
// let params = generate_random_parameters::<Bls12, _, _>(
|
||||
// MySillyCircuit { a: None, b: None },
|
||||
// rng
|
||||
// ).unwrap();
|
||||
|
||||
// {
|
||||
// let mut v = vec![];
|
||||
|
||||
// params.write(&mut v).unwrap();
|
||||
// assert_eq!(v.len(), 2136);
|
||||
|
||||
// let de_params = Parameters::read(&v[..], true).unwrap();
|
||||
// assert!(params == de_params);
|
||||
|
||||
// let de_params = Parameters::read(&v[..], false).unwrap();
|
||||
// assert!(params == de_params);
|
||||
// }
|
||||
|
||||
// let pvk = prepare_verifying_key::<Bls12>(¶ms.vk);
|
||||
|
||||
// for _ in 0..100 {
|
||||
// let a = Fr::rand(rng);
|
||||
// let b = Fr::rand(rng);
|
||||
// let mut c = a;
|
||||
// c.mul_assign(&b);
|
||||
|
||||
// let proof = create_random_proof(
|
||||
// MySillyCircuit {
|
||||
// a: Some(a),
|
||||
// b: Some(b)
|
||||
// },
|
||||
// ¶ms,
|
||||
// rng
|
||||
// ).unwrap();
|
||||
|
||||
// let mut v = vec![];
|
||||
// proof.write(&mut v).unwrap();
|
||||
|
||||
// assert_eq!(v.len(), 192);
|
||||
|
||||
// let de_proof = Proof::read(&v[..]).unwrap();
|
||||
// assert!(proof == de_proof);
|
||||
|
||||
// assert!(verify_proof(&pvk, &proof, &[c]).unwrap());
|
||||
// assert!(!verify_proof(&pvk, &proof, &[a]).unwrap());
|
||||
// }
|
||||
// }
|
||||
// }
|
@ -16,10 +16,9 @@ use crate::sonic::cs::Circuit as SonicCircuit;
|
||||
use crate::sonic::cs::ConstraintSystem as SonicConstraintSystem;
|
||||
use crate::sonic::cs::Variable as SonicVariable;
|
||||
use crate::sonic::cs::Coeff;
|
||||
// use crate::sonic::cs::synthesis::*;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
struct Adaptor<'a, E: Engine, CS: SonicConstraintSystem<E> + 'a> {
|
||||
pub struct Adaptor<'a, E: Engine, CS: SonicConstraintSystem<E> + 'a> {
|
||||
cs: &'a mut CS,
|
||||
_marker: PhantomData<E>,
|
||||
}
|
||||
@ -112,7 +111,7 @@ impl<'a, E: Engine, CS: SonicConstraintSystem<E> + 'a> crate::ConstraintSystem<E
|
||||
|
||||
Some(ret)
|
||||
}
|
||||
|
||||
|
||||
let a_lc = convert(a(crate::LinearCombination::zero()));
|
||||
let a_value = eval(&a_lc, &*self.cs);
|
||||
let b_lc = convert(b(crate::LinearCombination::zero()));
|
||||
|
@ -3,4 +3,4 @@ extern crate pairing;
|
||||
|
||||
mod adaptor;
|
||||
|
||||
pub use self::adaptor::{AdaptorCircuit};
|
||||
pub use self::adaptor::{Adaptor, AdaptorCircuit};
|
@ -1,6 +1,11 @@
|
||||
use ff::{Field, PrimeField};
|
||||
use pairing::{CurveAffine, CurveProjective, Engine, Wnaf};
|
||||
|
||||
use std::io::{self, Read, Write};
|
||||
use std::sync::Arc;
|
||||
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
|
||||
|
||||
#[derive(Clone, Eq)]
|
||||
pub struct SRS<E: Engine> {
|
||||
pub d: usize,
|
||||
|
||||
@ -29,6 +34,20 @@ pub struct SRS<E: Engine> {
|
||||
pub h_positive_x_alpha: Vec<E::G2Affine>,
|
||||
}
|
||||
|
||||
impl<E: Engine> PartialEq for SRS<E> {
|
||||
fn eq(&self, other: &SRS<E>) -> bool {
|
||||
self.d == other.d &&
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> SRS<E> {
|
||||
pub fn dummy(d: usize, _: E::Fr, _: E::Fr) -> Self {
|
||||
SRS {
|
||||
@ -93,3 +112,163 @@ impl<E: Engine> SRS<E> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> SRS<E> {
|
||||
pub fn write<W: Write>(
|
||||
&self,
|
||||
mut writer: W
|
||||
) -> io::Result<()>
|
||||
{
|
||||
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(())
|
||||
}
|
||||
|
||||
pub fn read<R: Read>(
|
||||
mut reader: R,
|
||||
checked: bool
|
||||
) -> io::Result<Self>
|
||||
{
|
||||
use pairing::EncodedPoint;
|
||||
|
||||
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 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(Self {
|
||||
d: d,
|
||||
g_negative_x: g_negative_x,
|
||||
g_positive_x: g_positive_x,
|
||||
h_negative_x: h_negative_x,
|
||||
h_positive_x: h_positive_x,
|
||||
g_negative_x_alpha: g_negative_x_alpha,
|
||||
g_positive_x_alpha: g_positive_x_alpha,
|
||||
h_negative_x_alpha: h_negative_x_alpha,
|
||||
h_positive_x_alpha: h_positive_x_alpha
|
||||
})
|
||||
}
|
||||
}
|
@ -634,11 +634,24 @@ fn test_inputs_into_sonic_mimc() {
|
||||
}
|
||||
println!("done in {:?}", start.elapsed());
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
let mut verifier = MultiVerifier::<Bn256, _, Basic>::new(AdaptorCircuit(circuit.clone()), &srs).unwrap();
|
||||
println!("verifying 100 proofs with advice");
|
||||
let start = Instant::now();
|
||||
{
|
||||
for _ in 0..samples {
|
||||
verifier.add_proof_with_advice(&proof, &[image], &advice);
|
||||
}
|
||||
assert_eq!(verifier.check_all(), true); // TODO
|
||||
}
|
||||
println!("done in {:?}", start.elapsed());
|
||||
}
|
||||
|
||||
{
|
||||
let mut verifier = MultiVerifier::<Bn256, _, Basic>::new(AdaptorCircuit(circuit.clone()), &srs).unwrap();
|
||||
println!("verifying 100 proofs with advice and aggregate");
|
||||
let start = Instant::now();
|
||||
{
|
||||
for (ref proof, ref advice) in &proofs {
|
||||
verifier.add_proof_with_advice(proof, &[image], advice);
|
||||
|
Loading…
Reference in New Issue
Block a user