introduce high-level verifier api
This commit is contained in:
parent
2327a4527b
commit
f98b6eaaf4
@ -28,7 +28,7 @@ use super::{
|
|||||||
use super::multicore::Worker;
|
use super::multicore::Worker;
|
||||||
pub use super::group::*;
|
pub use super::group::*;
|
||||||
|
|
||||||
#[feature(not(singlecore))]
|
#[cfg(not(feature = "singlecore"))]
|
||||||
use super::parallel_fft::*;
|
use super::parallel_fft::*;
|
||||||
|
|
||||||
pub struct EvaluationDomain<E: Engine, G: Group<E>> {
|
pub struct EvaluationDomain<E: Engine, G: Group<E>> {
|
||||||
|
102
src/sonic/helped/adapted_verifier.rs
Normal file
102
src/sonic/helped/adapted_verifier.rs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
use ff::{Field};
|
||||||
|
use pairing::{Engine, CurveProjective};
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use rand::{Rand, Rng};
|
||||||
|
|
||||||
|
use super::{Proof, SxyAdvice};
|
||||||
|
use super::batch::Batch;
|
||||||
|
use super::poly::{SxEval, SyEval};
|
||||||
|
use super::parameters::{Parameters};
|
||||||
|
use super::helper::{Aggregate};
|
||||||
|
|
||||||
|
use crate::SynthesisError;
|
||||||
|
|
||||||
|
use crate::sonic::transcript::{Transcript, TranscriptProtocol};
|
||||||
|
use crate::sonic::util::*;
|
||||||
|
use crate::sonic::cs::{Backend, SynthesisDriver};
|
||||||
|
use crate::{Circuit};
|
||||||
|
use crate::sonic::sonic::AdaptorCircuit;
|
||||||
|
use crate::sonic::srs::SRS;
|
||||||
|
use crate::sonic::cs::Nonassigning;
|
||||||
|
use super::verifier::verify_aggregate_on_srs as verify_aggregate_on_srs_sonic_circuit;
|
||||||
|
use super::verifier::verify_proofs_on_srs as verify_proofs_on_srs_sonic_circuit;
|
||||||
|
|
||||||
|
pub fn verify_proofs<E: Engine, C: Circuit<E> + Clone, R: Rng>(
|
||||||
|
proofs: &[Proof<E>],
|
||||||
|
inputs: &[Vec<E::Fr>],
|
||||||
|
circuit: C,
|
||||||
|
rng: R,
|
||||||
|
params: &Parameters<E>,
|
||||||
|
) -> Result<bool, SynthesisError>
|
||||||
|
{
|
||||||
|
let adapted_circuit = AdaptorCircuit(circuit);
|
||||||
|
|
||||||
|
verify_proofs_on_srs_sonic_circuit::<_, _, Nonassigning, _>(proofs, inputs, adapted_circuit, rng, ¶ms.srs)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check multiple proofs with aggregation. Verifier's work is
|
||||||
|
/// not succint due to `S(X, Y)` evaluation
|
||||||
|
pub fn verify_aggregate<E: Engine, C: Circuit<E> + Clone, R: Rng>(
|
||||||
|
proofs: &[(Proof<E>, SxyAdvice<E>)],
|
||||||
|
aggregate: &Aggregate<E>,
|
||||||
|
inputs: &[Vec<E::Fr>],
|
||||||
|
circuit: C,
|
||||||
|
rng: R,
|
||||||
|
params: &Parameters<E>,
|
||||||
|
) -> Result<bool, SynthesisError> {
|
||||||
|
let adapted_circuit = AdaptorCircuit(circuit);
|
||||||
|
|
||||||
|
verify_aggregate_on_srs_sonic_circuit::<_, _, Nonassigning, _>(proofs, aggregate, inputs, adapted_circuit, rng, ¶ms.srs)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
// fn my_fun_circuit_test() {
|
||||||
|
// use ff::PrimeField;
|
||||||
|
// use pairing::bls12_381::{Bls12, Fr};
|
||||||
|
// use super::*;
|
||||||
|
// use crate::sonic::cs::{Basic, ConstraintSystem, LinearCombination};
|
||||||
|
|
||||||
|
// struct MyCircuit;
|
||||||
|
|
||||||
|
// impl<E: Engine> Circuit<E> for MyCircuit {
|
||||||
|
// fn synthesize<CS: ConstraintSystem<E>>(&self, cs: &mut CS) -> Result<(), SynthesisError> {
|
||||||
|
// let (a, b, _) = cs.multiply(|| {
|
||||||
|
// Ok((
|
||||||
|
// E::Fr::from_str("10").unwrap(),
|
||||||
|
// E::Fr::from_str("20").unwrap(),
|
||||||
|
// E::Fr::from_str("200").unwrap(),
|
||||||
|
// ))
|
||||||
|
// })?;
|
||||||
|
|
||||||
|
// cs.enforce_zero(LinearCombination::from(a) + a - b);
|
||||||
|
|
||||||
|
// //let multiplier = cs.alloc_input(|| Ok(E::Fr::from_str("20").unwrap()))?;
|
||||||
|
|
||||||
|
// //cs.enforce_zero(LinearCombination::from(b) - multiplier);
|
||||||
|
|
||||||
|
// Ok(())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let srs = SRS::<Bls12>::new(
|
||||||
|
// 20,
|
||||||
|
// Fr::from_str("22222").unwrap(),
|
||||||
|
// Fr::from_str("33333333").unwrap(),
|
||||||
|
// );
|
||||||
|
// let proof = create_proof_on_srs::<Bls12, _, Basic>(&MyCircuit, &srs).unwrap();
|
||||||
|
|
||||||
|
// use std::time::{Instant};
|
||||||
|
// let start = Instant::now();
|
||||||
|
// let mut batch = MultiVerifier::<Bls12, _, Basic>::new(MyCircuit, &srs).unwrap();
|
||||||
|
|
||||||
|
// for _ in 0..1 {
|
||||||
|
// batch.add_proof(&proof, &[/*Fr::from_str("20").unwrap()*/], |_, _| None);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// assert!(batch.check_all());
|
||||||
|
|
||||||
|
// let elapsed = start.elapsed();
|
||||||
|
// println!("time to verify: {:?}", elapsed);
|
||||||
|
// }
|
@ -482,7 +482,7 @@ pub fn generate_srs<E: Engine>(
|
|||||||
let mut x_powers_negative = vec![Scalar::<E>(E::Fr::zero()); d];
|
let mut x_powers_negative = vec![Scalar::<E>(E::Fr::zero()); d];
|
||||||
{
|
{
|
||||||
// Compute powers of tau
|
// Compute powers of tau
|
||||||
if verbose {eprintln!("computing powers of tau...")};
|
if verbose {eprintln!("computing powers of x...")};
|
||||||
|
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ mod helper;
|
|||||||
mod parameters;
|
mod parameters;
|
||||||
mod generator;
|
mod generator;
|
||||||
mod adapted_prover;
|
mod adapted_prover;
|
||||||
|
mod adapted_verifier;
|
||||||
|
|
||||||
pub mod prover;
|
pub mod prover;
|
||||||
|
|
||||||
@ -36,3 +37,8 @@ pub use self::adapted_prover::{
|
|||||||
create_proof,
|
create_proof,
|
||||||
create_proof_on_srs,
|
create_proof_on_srs,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub use self::adapted_verifier::{
|
||||||
|
verify_proofs,
|
||||||
|
verify_aggregate
|
||||||
|
};
|
@ -382,6 +382,7 @@ fn my_fun_circuit_test() {
|
|||||||
use pairing::bls12_381::{Bls12, Fr};
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::sonic::cs::{Basic, ConstraintSystem, LinearCombination};
|
use crate::sonic::cs::{Basic, ConstraintSystem, LinearCombination};
|
||||||
|
use rand::{thread_rng};
|
||||||
|
|
||||||
struct MyCircuit;
|
struct MyCircuit;
|
||||||
|
|
||||||
@ -414,7 +415,8 @@ fn my_fun_circuit_test() {
|
|||||||
|
|
||||||
use std::time::{Instant};
|
use std::time::{Instant};
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let mut batch = MultiVerifier::<Bls12, _, Basic>::new(MyCircuit, &srs).unwrap();
|
let rng = thread_rng();
|
||||||
|
let mut batch = MultiVerifier::<Bls12, _, Basic, _>::new(MyCircuit, &srs, rng).unwrap();
|
||||||
|
|
||||||
for _ in 0..1 {
|
for _ in 0..1 {
|
||||||
batch.add_proof(&proof, &[/*Fr::from_str("20").unwrap()*/], |_, _| None);
|
batch.add_proof(&proof, &[/*Fr::from_str("20").unwrap()*/], |_, _| None);
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use ff::{Field};
|
use ff::{Field};
|
||||||
use pairing::{Engine, CurveProjective};
|
use pairing::{Engine, CurveProjective};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use rand::{Rand, Rng};
|
||||||
|
|
||||||
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::helper::Aggregate;
|
use super::helper::Aggregate;
|
||||||
|
use super::parameters::{Parameters};
|
||||||
|
|
||||||
use crate::SynthesisError;
|
use crate::SynthesisError;
|
||||||
|
|
||||||
@ -15,17 +17,19 @@ 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 struct MultiVerifier<E: Engine, C: Circuit<E>, S: SynthesisDriver> {
|
pub struct MultiVerifier<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> {
|
||||||
circuit: C,
|
circuit: C,
|
||||||
batch: Batch<E>,
|
batch: Batch<E>,
|
||||||
k_map: Vec<usize>,
|
k_map: Vec<usize>,
|
||||||
n: usize,
|
n: usize,
|
||||||
q: usize,
|
q: usize,
|
||||||
|
randomness_source: R,
|
||||||
_marker: PhantomData<(E, S)>
|
_marker: PhantomData<(E, S)>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine, C: Circuit<E>, S: SynthesisDriver> MultiVerifier<E, C, S> {
|
impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> MultiVerifier<E, C, S, R> {
|
||||||
pub fn new(circuit: C, srs: &SRS<E>) -> Result<Self, SynthesisError> {
|
// This constructor consumes randomness source cause it's later used internally
|
||||||
|
pub fn new(circuit: C, srs: &SRS<E>, rng: R) -> Result<Self, SynthesisError> {
|
||||||
struct Preprocess<E: Engine> {
|
struct Preprocess<E: Engine> {
|
||||||
k_map: Vec<usize>,
|
k_map: Vec<usize>,
|
||||||
n: usize,
|
n: usize,
|
||||||
@ -57,6 +61,7 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver> MultiVerifier<E, C, S> {
|
|||||||
k_map: preprocess.k_map,
|
k_map: preprocess.k_map,
|
||||||
n: preprocess.n,
|
n: preprocess.n,
|
||||||
q: preprocess.q,
|
q: preprocess.q,
|
||||||
|
randomness_source: rng,
|
||||||
_marker: PhantomData
|
_marker: PhantomData
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -93,10 +98,7 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver> MultiVerifier<E, C, S> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
// TODO: like everything else doing this, this isn't really random
|
let random: E::Fr = self.randomness_source.gen();
|
||||||
let random: E::Fr;
|
|
||||||
let mut transcript = transcript.clone();
|
|
||||||
random = transcript.get_challenge_scalar();
|
|
||||||
|
|
||||||
self.batch.add_opening(aggregate.opening, random, w);
|
self.batch.add_opening(aggregate.opening, random, w);
|
||||||
self.batch.add_commitment(aggregate.c, random);
|
self.batch.add_commitment(aggregate.c, random);
|
||||||
@ -104,20 +106,14 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver> MultiVerifier<E, C, S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for ((opening, value), &y) in aggregate.c_openings.iter().zip(y_values.iter()) {
|
for ((opening, value), &y) in aggregate.c_openings.iter().zip(y_values.iter()) {
|
||||||
let random: E::Fr;
|
let random: E::Fr = self.randomness_source.gen();
|
||||||
let mut transcript = transcript.clone();
|
|
||||||
random = transcript.get_challenge_scalar();
|
|
||||||
|
|
||||||
self.batch.add_opening(*opening, random, y);
|
self.batch.add_opening(*opening, random, y);
|
||||||
self.batch.add_commitment(aggregate.c, random);
|
self.batch.add_commitment(aggregate.c, random);
|
||||||
self.batch.add_opening_value(*value, random);
|
self.batch.add_opening_value(*value, random);
|
||||||
}
|
}
|
||||||
|
|
||||||
let random: E::Fr;
|
let random: E::Fr = self.randomness_source.gen();
|
||||||
{
|
|
||||||
let mut transcript = transcript.clone();
|
|
||||||
random = transcript.get_challenge_scalar();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut expected_value = E::Fr::zero();
|
let mut expected_value = E::Fr::zero();
|
||||||
for ((_, advice), c_opening) in proofs.iter().zip(aggregate.c_openings.iter()) {
|
for ((_, advice), c_opening) in proofs.iter().zip(aggregate.c_openings.iter()) {
|
||||||
@ -139,6 +135,7 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver> MultiVerifier<E, C, S> {
|
|||||||
self.batch.add_opening(aggregate.s_opening, random, z);
|
self.batch.add_opening(aggregate.s_opening, random, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Caller must ensure to add aggregate after adding a proof
|
||||||
pub fn add_proof_with_advice(
|
pub fn add_proof_with_advice(
|
||||||
&mut self,
|
&mut self,
|
||||||
proof: &Proof<E>,
|
proof: &Proof<E>,
|
||||||
@ -160,7 +157,7 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver> MultiVerifier<E, C, S> {
|
|||||||
transcript.commit_point(&advice.opening);
|
transcript.commit_point(&advice.opening);
|
||||||
transcript.commit_point(&advice.s);
|
transcript.commit_point(&advice.s);
|
||||||
transcript.commit_scalar(&advice.szy);
|
transcript.commit_scalar(&advice.szy);
|
||||||
let random: E::Fr = transcript.get_challenge_scalar();
|
let random: E::Fr = self.randomness_source.gen();
|
||||||
|
|
||||||
self.batch.add_opening(advice.opening, random, z);
|
self.batch.add_opening(advice.opening, random, z);
|
||||||
self.batch.add_commitment(advice.s, random);
|
self.batch.add_commitment(advice.s, random);
|
||||||
@ -196,7 +193,7 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver> MultiVerifier<E, C, S> {
|
|||||||
// First, the easy one. Let's open up proof.r at zy, using proof.zy_opening
|
// First, the easy one. Let's open up proof.r at zy, using proof.zy_opening
|
||||||
// as the evidence and proof.rzy as the opening.
|
// as the evidence and proof.rzy as the opening.
|
||||||
{
|
{
|
||||||
let random = transcript.get_challenge_scalar();
|
let random: E::Fr = self.randomness_source.gen();
|
||||||
let mut zy = z;
|
let mut zy = z;
|
||||||
zy.mul_assign(&y);
|
zy.mul_assign(&y);
|
||||||
self.batch.add_opening(proof.zy_opening, random, zy);
|
self.batch.add_opening(proof.zy_opening, random, zy);
|
||||||
@ -235,7 +232,7 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver> MultiVerifier<E, C, S> {
|
|||||||
// We open these both at the same time by keeping their commitments
|
// We open these both at the same time by keeping their commitments
|
||||||
// linearly independent (using r1).
|
// linearly independent (using r1).
|
||||||
{
|
{
|
||||||
let mut random = transcript.get_challenge_scalar();
|
let mut random: E::Fr = self.randomness_source.gen();
|
||||||
|
|
||||||
self.batch.add_opening(proof.z_opening, random, z);
|
self.batch.add_opening(proof.z_opening, random, z);
|
||||||
self.batch.add_opening_value(tzy, random);
|
self.batch.add_opening_value(tzy, random);
|
||||||
@ -264,3 +261,73 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver> MultiVerifier<E, C, S> {
|
|||||||
self.batch.check_all()
|
self.batch.check_all()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check multiple proofs without aggregation. Verifier's work is
|
||||||
|
/// not succint due to `S(X, Y)` evaluation
|
||||||
|
pub fn verify_proofs<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng>(
|
||||||
|
proofs: &[Proof<E>],
|
||||||
|
inputs: &[Vec<E::Fr>],
|
||||||
|
circuit: C,
|
||||||
|
rng: R,
|
||||||
|
params: &Parameters<E>,
|
||||||
|
) -> Result<bool, SynthesisError> {
|
||||||
|
verify_proofs_on_srs::<E, C, S, R>(proofs, inputs, circuit, rng, ¶ms.srs)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check multiple proofs without aggregation. Verifier's work is
|
||||||
|
/// not succint due to `S(X, Y)` evaluation
|
||||||
|
pub fn verify_proofs_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng>(
|
||||||
|
proofs: &[Proof<E>],
|
||||||
|
inputs: &[Vec<E::Fr>],
|
||||||
|
circuit: C,
|
||||||
|
rng: R,
|
||||||
|
srs: &SRS<E>,
|
||||||
|
) -> Result<bool, SynthesisError> {
|
||||||
|
let mut verifier = MultiVerifier::<E, C, S, R>::new(circuit, srs, rng)?;
|
||||||
|
let expected_inputs_size = verifier.get_k_map().len() - 1;
|
||||||
|
for (proof, inputs) in proofs.iter().zip(inputs.iter()) {
|
||||||
|
if inputs.len() != expected_inputs_size {
|
||||||
|
return Err(SynthesisError::Unsatisfiable);
|
||||||
|
}
|
||||||
|
verifier.add_proof(proof, &inputs, |_, _| None);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(verifier.check_all())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check multiple proofs with aggregation. Verifier's work is
|
||||||
|
/// not succint due to `S(X, Y)` evaluation
|
||||||
|
pub fn verify_aggregate<E: Engine, C: Circuit<E>, S: SynthesisDriver,R: Rng>(
|
||||||
|
proofs: &[(Proof<E>, SxyAdvice<E>)],
|
||||||
|
aggregate: &Aggregate<E>,
|
||||||
|
inputs: &[Vec<E::Fr>],
|
||||||
|
circuit: C,
|
||||||
|
rng: R,
|
||||||
|
params: &Parameters<E>,
|
||||||
|
) -> Result<bool, SynthesisError> {
|
||||||
|
verify_aggregate_on_srs::<E, C, S, R>(proofs, aggregate, inputs, circuit, rng, ¶ms.srs)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check multiple proofs with aggregation. Verifier's work is
|
||||||
|
/// not succint due to `S(X, Y)` evaluation
|
||||||
|
pub fn verify_aggregate_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng>(
|
||||||
|
proofs: &[(Proof<E>, SxyAdvice<E>)],
|
||||||
|
aggregate: &Aggregate<E>,
|
||||||
|
inputs: &[Vec<E::Fr>],
|
||||||
|
circuit: C,
|
||||||
|
rng: R,
|
||||||
|
srs: &SRS<E>,
|
||||||
|
) -> Result<bool, SynthesisError> {
|
||||||
|
let mut verifier = MultiVerifier::<E, C, S, R>::new(circuit, srs, rng)?;
|
||||||
|
let expected_inputs_size = verifier.get_k_map().len() - 1;
|
||||||
|
for ((proof, advice), inputs) in proofs.iter().zip(inputs.iter()) {
|
||||||
|
if inputs.len() != expected_inputs_size {
|
||||||
|
return Err(SynthesisError::Unsatisfiable);
|
||||||
|
}
|
||||||
|
verifier.add_proof_with_advice(proof, &inputs, &advice);
|
||||||
|
}
|
||||||
|
verifier.add_aggregate(proofs, aggregate);
|
||||||
|
|
||||||
|
Ok(verifier.check_all())
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -499,7 +499,8 @@ fn test_sonic_mimc() {
|
|||||||
println!("done in {:?}", start.elapsed());
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut verifier = MultiVerifier::<Bls12, _, Basic>::new(AdaptorCircuit(circuit.clone()), &srs).unwrap();
|
let rng = thread_rng();
|
||||||
|
let mut verifier = MultiVerifier::<Bls12, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
println!("verifying 1 proof without advice");
|
println!("verifying 1 proof without advice");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
{
|
{
|
||||||
@ -512,7 +513,8 @@ fn test_sonic_mimc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut verifier = MultiVerifier::<Bls12, _, Basic>::new(AdaptorCircuit(circuit.clone()), &srs).unwrap();
|
let rng = thread_rng();
|
||||||
|
let mut verifier = MultiVerifier::<Bls12, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
println!("verifying {} proofs without advice", samples);
|
println!("verifying {} proofs without advice", samples);
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
{
|
{
|
||||||
@ -525,7 +527,8 @@ fn test_sonic_mimc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut verifier = MultiVerifier::<Bls12, _, Basic>::new(AdaptorCircuit(circuit.clone()), &srs).unwrap();
|
let rng = thread_rng();
|
||||||
|
let mut verifier = MultiVerifier::<Bls12, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
println!("verifying 100 proofs with advice");
|
println!("verifying 100 proofs with advice");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
{
|
{
|
||||||
@ -602,7 +605,8 @@ fn test_inputs_into_sonic_mimc() {
|
|||||||
println!("done in {:?}", start.elapsed());
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut verifier = MultiVerifier::<Bn256, _, Basic>::new(AdaptorCircuit(circuit.clone()), &srs).unwrap();
|
let rng = thread_rng();
|
||||||
|
let mut verifier = MultiVerifier::<Bn256, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
println!("verifying 1 proof without advice");
|
println!("verifying 1 proof without advice");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
{
|
{
|
||||||
@ -615,7 +619,8 @@ fn test_inputs_into_sonic_mimc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut verifier = MultiVerifier::<Bn256, _, Basic>::new(AdaptorCircuit(circuit.clone()), &srs).unwrap();
|
let rng = thread_rng();
|
||||||
|
let mut verifier = MultiVerifier::<Bn256, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
println!("verifying {} proofs without advice", samples);
|
println!("verifying {} proofs without advice", samples);
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
{
|
{
|
||||||
@ -628,7 +633,8 @@ fn test_inputs_into_sonic_mimc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut verifier = MultiVerifier::<Bn256, _, Basic>::new(AdaptorCircuit(circuit.clone()), &srs).unwrap();
|
let rng = thread_rng();
|
||||||
|
let mut verifier = MultiVerifier::<Bn256, _, Basic, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
println!("verifying 100 proofs with advice and aggregate");
|
println!("verifying 100 proofs with advice and aggregate");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
{
|
{
|
||||||
@ -642,3 +648,84 @@ fn test_inputs_into_sonic_mimc() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_high_level_sonic_api() {
|
||||||
|
use ff::{Field, PrimeField};
|
||||||
|
use pairing::{Engine, CurveAffine, CurveProjective};
|
||||||
|
use pairing::bn256::{Bn256, Fr};
|
||||||
|
use std::time::{Instant};
|
||||||
|
use bellman::sonic::helped::{generate_random_parameters,
|
||||||
|
verify_aggregate,
|
||||||
|
verify_proofs,
|
||||||
|
create_proof,
|
||||||
|
create_advice,
|
||||||
|
create_aggregate
|
||||||
|
};
|
||||||
|
use bellman::sonic::cs::Basic;
|
||||||
|
use bellman::sonic::sonic::AdaptorCircuit;
|
||||||
|
|
||||||
|
{
|
||||||
|
// This may not be cryptographically safe, use
|
||||||
|
// `OsRng` (for example) in production software.
|
||||||
|
let mut rng = &mut thread_rng();
|
||||||
|
|
||||||
|
// Generate the MiMC round constants
|
||||||
|
let constants = (0..MIMC_ROUNDS).map(|_| rng.gen()).collect::<Vec<_>>();
|
||||||
|
let samples: usize = 100;
|
||||||
|
|
||||||
|
let xl = rng.gen();
|
||||||
|
let xr = rng.gen();
|
||||||
|
let image = mimc::<Bn256>(xl, xr, &constants);
|
||||||
|
|
||||||
|
// Create an instance of our circuit (with the
|
||||||
|
// witness)
|
||||||
|
let circuit = MiMCDemo {
|
||||||
|
xl: Some(xl),
|
||||||
|
xr: Some(xr),
|
||||||
|
constants: &constants
|
||||||
|
};
|
||||||
|
|
||||||
|
let params = generate_random_parameters(circuit.clone(), &mut rng).unwrap();
|
||||||
|
|
||||||
|
println!("creating proof");
|
||||||
|
let start = Instant::now();
|
||||||
|
let proof = create_proof(circuit.clone(), ¶ms).unwrap();
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
println!("creating advice");
|
||||||
|
let start = Instant::now();
|
||||||
|
let advice = create_advice(circuit.clone(), &proof, ¶ms).unwrap();
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
println!("creating aggregate for {} proofs", samples);
|
||||||
|
let start = Instant::now();
|
||||||
|
let proofs: Vec<_> = (0..samples).map(|_| (proof.clone(), advice.clone())).collect();
|
||||||
|
let aggregate = create_aggregate::<Bn256, _, Basic>(&AdaptorCircuit(circuit.clone()), &proofs, ¶ms.srs);
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
|
{
|
||||||
|
println!("verifying 1 proof without advice");
|
||||||
|
let rng = thread_rng();
|
||||||
|
let start = Instant::now();
|
||||||
|
assert_eq!(verify_proofs(&vec![proof.clone()], &vec![vec![image.clone()]], circuit.clone(), rng, ¶ms).unwrap(), true);
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
println!("verifying {} proofs without advice", samples);
|
||||||
|
let rng = thread_rng();
|
||||||
|
let start = Instant::now();
|
||||||
|
assert_eq!(verify_proofs(&vec![proof.clone(); 100], &vec![vec![image.clone()]; 100], circuit.clone(), rng, ¶ms).unwrap(), true);
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
println!("verifying 100 proofs with advice and aggregate");
|
||||||
|
let rng = thread_rng();
|
||||||
|
let start = Instant::now();
|
||||||
|
assert_eq!(verify_aggregate(&vec![(proof.clone(), advice.clone()); 100], &aggregate, &vec![vec![image.clone()]; 100], circuit.clone(), rng, ¶ms).unwrap(), true);
|
||||||
|
println!("done in {:?}", start.elapsed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user