Родитель
290bbc0897
Коммит
eb969d5dcf
28
Cargo.toml
28
Cargo.toml
|
@ -29,31 +29,19 @@ name = "libspartan"
|
|||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "profiler"
|
||||
path = "src/profiler.rs"
|
||||
name = "snark"
|
||||
path = "profiler/snark.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "nizk"
|
||||
path = "profiler/nizk.rs"
|
||||
|
||||
[[bench]]
|
||||
name = "commitments"
|
||||
name = "snark"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "dotproduct"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "polycommit"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "r1csproof"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "spartan"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "sumcheck"
|
||||
name = "nizk"
|
||||
harness = false
|
||||
|
||||
[features]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
This repository includes the following third-party open-source code.
|
||||
|
||||
* The code in scalar_25519.rs is derived from [bls12-381](https://github.com/zkcrypto/bls12_381).
|
||||
* The code in src/scalar/ristretto255.rs is derived from [bls12-381](https://github.com/zkcrypto/bls12_381).
|
||||
Specifically, from [src/bls12_381/scalar.rs](https://github.com/zkcrypto/bls12_381/blob/master/src/scalar.rs) and [src/bls12_381/util.rs](https://github.com/zkcrypto/bls12_381/blob/master/src/util.rs), which has the following copyright and license.
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
|
@ -28,7 +28,7 @@ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
* The invert and batch_invert methods in src/scalar_25519.rs is from [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek), which has the following copyright and license.
|
||||
* The invert and batch_invert methods in src/scalar/ristretto255.rs is from [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek), which has the following copyright and license.
|
||||
|
||||
Copyright (c) 2016-2019 Isis Agora Lovecruft, Henry de Valence. All rights reserved.
|
||||
|
||||
|
@ -96,7 +96,7 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
* The bullet.rs is derived from [bulletproofs](https://github.com/dalek-cryptography/bulletproofs/), which has the following license:
|
||||
* The src/nizk/bullet.rs is derived from [bulletproofs](https://github.com/dalek-cryptography/bulletproofs/), which has the following license:
|
||||
|
||||
MIT License
|
||||
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
extern crate byteorder;
|
||||
extern crate core;
|
||||
extern crate criterion;
|
||||
extern crate digest;
|
||||
extern crate libspartan;
|
||||
extern crate merlin;
|
||||
extern crate rand;
|
||||
extern crate sha3;
|
||||
|
||||
use libspartan::commitments::{Commitments, MultiCommitGens};
|
||||
use libspartan::math::Math;
|
||||
use libspartan::scalar::Scalar;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
use criterion::*;
|
||||
|
||||
fn commitment_benchmark(c: &mut Criterion) {
|
||||
let mut rng = OsRng;
|
||||
for &s in [20].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("commitment_bools");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let n = (s as usize).pow2();
|
||||
let gens = MultiCommitGens::new(n, b"test-m");
|
||||
let blind = Scalar::random(&mut rng);
|
||||
let vec: Vec<bool> = vec![true; n];
|
||||
let name = format!("commitment_bools_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| vec.commit(black_box(&blind), black_box(&gens)));
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn set_duration() -> Criterion {
|
||||
Criterion::default().sample_size(10)
|
||||
// .measurement_time(Duration::new(0, 50000000))
|
||||
}
|
||||
|
||||
criterion_group! {
|
||||
name = benches_commitment;
|
||||
config = set_duration();
|
||||
targets = commitment_benchmark
|
||||
}
|
||||
|
||||
criterion_main!(benches_commitment);
|
|
@ -1,85 +0,0 @@
|
|||
extern crate byteorder;
|
||||
extern crate core;
|
||||
extern crate criterion;
|
||||
extern crate digest;
|
||||
extern crate libspartan;
|
||||
extern crate merlin;
|
||||
extern crate rand;
|
||||
extern crate sha3;
|
||||
|
||||
use libspartan::math::Math;
|
||||
use libspartan::nizk::DotProductProof;
|
||||
use libspartan::scalar::Scalar;
|
||||
use libspartan::scalar::ScalarBytes;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
use criterion::*;
|
||||
|
||||
fn dotproduct_benchmark_dalek(c: &mut Criterion) {
|
||||
let mut csprng: OsRng = OsRng;
|
||||
|
||||
for &s in [20].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("dotproduct_benchmark_dalek");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let n = (s as usize).pow2();
|
||||
let vec_a = (0..n)
|
||||
.map(|_i| ScalarBytes::random(&mut csprng))
|
||||
.collect::<Vec<ScalarBytes>>();
|
||||
let vec_b = (0..n)
|
||||
.map(|_i| ScalarBytes::random(&mut csprng))
|
||||
.collect::<Vec<ScalarBytes>>();
|
||||
|
||||
let name = format!("dotproduct_dalek_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| compute_dotproduct(black_box(&vec_a), black_box(&vec_b)));
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_dotproduct(a: &Vec<ScalarBytes>, b: &Vec<ScalarBytes>) -> ScalarBytes {
|
||||
let mut res = ScalarBytes::zero();
|
||||
for i in 0..a.len() {
|
||||
res = &res + &a[i] * &b[i];
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
fn dotproduct_benchmark_opt(c: &mut Criterion) {
|
||||
let mut csprng: OsRng = OsRng;
|
||||
|
||||
for &s in [20].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("dotproduct_benchmark_opt");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let n = (s as usize).pow2();
|
||||
let vec_a = (0..n)
|
||||
.map(|_i| Scalar::random(&mut csprng))
|
||||
.collect::<Vec<Scalar>>();
|
||||
let vec_b = (0..n)
|
||||
.map(|_i| Scalar::random(&mut csprng))
|
||||
.collect::<Vec<Scalar>>();
|
||||
|
||||
let name = format!("dotproduct_opt_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| DotProductProof::compute_dotproduct(black_box(&vec_a), black_box(&vec_b)));
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn set_duration() -> Criterion {
|
||||
Criterion::default().sample_size(10)
|
||||
// .measurement_time(Duration::new(0, 50000000))
|
||||
}
|
||||
|
||||
criterion_group! {
|
||||
name = benches_dotproduct;
|
||||
config = set_duration();
|
||||
targets = dotproduct_benchmark_dalek, dotproduct_benchmark_opt
|
||||
}
|
||||
|
||||
criterion_main!(benches_dotproduct);
|
|
@ -7,89 +7,70 @@ extern crate merlin;
|
|||
extern crate rand;
|
||||
extern crate sha3;
|
||||
|
||||
use libspartan::dense_mlpoly::EqPolynomial;
|
||||
use libspartan::math::Math;
|
||||
use libspartan::r1csinstance::R1CSInstance;
|
||||
use libspartan::r1csproof::{R1CSGens, R1CSProof};
|
||||
use libspartan::random::RandomTape;
|
||||
use libspartan::scalar::Scalar;
|
||||
use libspartan::transcript::ProofTranscript;
|
||||
use libspartan::spartan::{NIZKGens, NIZK};
|
||||
use merlin::Transcript;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
use criterion::*;
|
||||
|
||||
fn prove_benchmark(c: &mut Criterion) {
|
||||
fn nizk_prove_benchmark(c: &mut Criterion) {
|
||||
for &s in [10, 12, 16].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("r1cs_prove_benchmark");
|
||||
let mut group = c.benchmark_group("NIZK_prove_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let num_vars = s.pow2();
|
||||
let num_vars = (2 as usize).pow(s as u32);
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
|
||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
let n = inst.get_num_vars();
|
||||
|
||||
let gens = R1CSGens::new(num_cons, num_vars, b"test-m");
|
||||
let gens = NIZKGens::new(num_cons, num_vars);
|
||||
|
||||
let name = format!("r1cs_prove_{}", n);
|
||||
let name = format!("NIZK_prove_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
let mut random_tape = RandomTape::new(b"proof");
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
R1CSProof::prove(
|
||||
NIZK::prove(
|
||||
black_box(&inst),
|
||||
black_box(vars.clone()),
|
||||
black_box(&input),
|
||||
black_box(&gens),
|
||||
black_box(&mut prover_transcript),
|
||||
black_box(&mut random_tape),
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_benchmark(c: &mut Criterion) {
|
||||
for &s in [10, 12, 16, 20].iter() {
|
||||
fn nizk_verify_benchmark(c: &mut Criterion) {
|
||||
for &s in [10, 12, 16].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("r1cs_verify_benchmark");
|
||||
let mut group = c.benchmark_group("NIZK_verify_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let num_vars = s.pow2();
|
||||
let num_vars = (2 as usize).pow(s as u32);
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
let n = inst.get_num_vars();
|
||||
let gens = R1CSGens::new(num_cons, num_vars, b"test-m");
|
||||
|
||||
let mut random_tape = RandomTape::new(b"proof");
|
||||
let gens = NIZKGens::new(num_cons, num_vars);
|
||||
|
||||
// produce a proof of satisfiability
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
let (proof, rx, ry) = R1CSProof::prove(
|
||||
&inst,
|
||||
vars,
|
||||
&input,
|
||||
&gens,
|
||||
&mut prover_transcript,
|
||||
&mut random_tape,
|
||||
);
|
||||
let proof = NIZK::prove(&inst, vars, &input, &gens, &mut prover_transcript);
|
||||
|
||||
let eval_table_rx = EqPolynomial::new(rx.clone()).evals();
|
||||
let eval_table_ry = EqPolynomial::new(ry.clone()).evals();
|
||||
let inst_evals = inst.evaluate_with_tables(&eval_table_rx, &eval_table_ry);
|
||||
|
||||
let name = format!("r1cs_verify_{}", n);
|
||||
let name = format!("NIZK_verify_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
let mut verifier_transcript = Transcript::new(b"example");
|
||||
assert!(proof
|
||||
.verify(
|
||||
black_box(num_vars),
|
||||
black_box(num_cons),
|
||||
black_box(&inst),
|
||||
black_box(&input),
|
||||
black_box(&inst_evals),
|
||||
black_box(&mut verifier_transcript),
|
||||
black_box(&gens)
|
||||
)
|
||||
|
@ -102,13 +83,12 @@ fn verify_benchmark(c: &mut Criterion) {
|
|||
|
||||
fn set_duration() -> Criterion {
|
||||
Criterion::default().sample_size(10)
|
||||
// .measurement_time(Duration::new(0, 50000000))
|
||||
}
|
||||
|
||||
criterion_group! {
|
||||
name = benches_r1cs;
|
||||
name = benches_nizk;
|
||||
config = set_duration();
|
||||
targets = prove_benchmark, verify_benchmark
|
||||
targets = nizk_prove_benchmark, nizk_verify_benchmark
|
||||
}
|
||||
|
||||
criterion_main!(benches_r1cs);
|
||||
criterion_main!(benches_nizk);
|
|
@ -1,191 +0,0 @@
|
|||
extern crate byteorder;
|
||||
extern crate core;
|
||||
extern crate criterion;
|
||||
extern crate digest;
|
||||
extern crate libspartan;
|
||||
extern crate merlin;
|
||||
extern crate rand;
|
||||
extern crate sha3;
|
||||
|
||||
use criterion::*;
|
||||
use libspartan::dense_mlpoly::{DensePolynomial, PolyCommitmentGens, PolyEvalProof};
|
||||
use libspartan::math::Math;
|
||||
use libspartan::random::RandomTape;
|
||||
use libspartan::scalar::Scalar;
|
||||
use libspartan::transcript::ProofTranscript;
|
||||
use merlin::Transcript;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
fn commit_benchmark(c: &mut Criterion) {
|
||||
let mut csprng: OsRng = OsRng;
|
||||
|
||||
for &s in [4, 8, 12, 14, 16, 20].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("commit_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let n = (s as usize).pow2();
|
||||
let m = n.square_root();
|
||||
let z = (0..n)
|
||||
.map(|_i| Scalar::random(&mut csprng))
|
||||
.collect::<Vec<Scalar>>();
|
||||
assert_eq!(m * m, z.len()); // check if Z's size if a perfect square
|
||||
|
||||
let poly = DensePolynomial::new(z);
|
||||
let gens = PolyCommitmentGens::new(s, b"test-m");
|
||||
let name = format!("polycommit_commit_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| poly.commit(black_box(false), black_box(&gens), black_box(None)));
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_benchmark(c: &mut Criterion) {
|
||||
let mut csprng: OsRng = OsRng;
|
||||
|
||||
for &s in [4, 8, 12, 14, 16, 20].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("eval_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let n = (s as usize).pow2();
|
||||
let m = n.square_root();
|
||||
let mut z: Vec<Scalar> = Vec::new();
|
||||
for _ in 0..n {
|
||||
z.push(Scalar::random(&mut csprng));
|
||||
}
|
||||
assert_eq!(m * m, z.len()); // check if Z's size if a perfect square
|
||||
|
||||
let poly = DensePolynomial::new(z);
|
||||
|
||||
let mut r: Vec<Scalar> = Vec::new();
|
||||
for _ in 0..s {
|
||||
r.push(Scalar::random(&mut csprng));
|
||||
}
|
||||
|
||||
let name = format!("polycommit_eval_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| poly.evaluate(black_box(&r)));
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn evalproof_benchmark(c: &mut Criterion) {
|
||||
let mut csprng: OsRng = OsRng;
|
||||
|
||||
for &s in [4, 8, 12, 14, 16, 20].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("evalproof_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let n = (s as usize).pow2();
|
||||
let m = n.square_root();
|
||||
let mut z: Vec<Scalar> = Vec::new();
|
||||
for _ in 0..n {
|
||||
z.push(Scalar::random(&mut csprng));
|
||||
}
|
||||
assert_eq!(m * m, z.len()); // check if Z's size if a perfect square
|
||||
|
||||
let poly = DensePolynomial::new(z);
|
||||
|
||||
let gens = PolyCommitmentGens::new(s, b"test-m");
|
||||
|
||||
let mut r: Vec<Scalar> = Vec::new();
|
||||
for _ in 0..s {
|
||||
r.push(Scalar::random(&mut csprng));
|
||||
}
|
||||
|
||||
let eval = poly.evaluate(&r);
|
||||
|
||||
let name = format!("polycommit_evalproof_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
let mut random_tape = RandomTape::new(b"proof");
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
PolyEvalProof::prove(
|
||||
black_box(&poly),
|
||||
black_box(None),
|
||||
black_box(&r),
|
||||
black_box(&eval),
|
||||
black_box(None),
|
||||
black_box(&gens),
|
||||
black_box(&mut prover_transcript),
|
||||
black_box(&mut random_tape),
|
||||
)
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn evalproofverify_benchmark(c: &mut Criterion) {
|
||||
let mut csprng: OsRng = OsRng;
|
||||
|
||||
for &s in [4, 8, 12, 14, 16, 20].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("evalproofverify_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let n = s.pow2();
|
||||
let m = n.square_root();
|
||||
let mut z: Vec<Scalar> = Vec::new();
|
||||
for _ in 0..n {
|
||||
z.push(Scalar::random(&mut csprng));
|
||||
}
|
||||
assert_eq!(m * m, z.len()); // check if Z's size if a perfect square
|
||||
|
||||
let poly = DensePolynomial::new(z);
|
||||
let gens = PolyCommitmentGens::new(s, b"test-m");
|
||||
|
||||
let mut r: Vec<Scalar> = Vec::new();
|
||||
for _ in 0..s {
|
||||
r.push(Scalar::random(&mut csprng));
|
||||
}
|
||||
|
||||
let (poly_commitment, blinds) = poly.commit(false, &gens, None);
|
||||
let eval = poly.evaluate(&r);
|
||||
|
||||
let mut random_tape = RandomTape::new(b"proof");
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
let (proof, c_zr) = PolyEvalProof::prove(
|
||||
black_box(&poly),
|
||||
black_box(Some(&blinds)),
|
||||
black_box(&r),
|
||||
black_box(&eval),
|
||||
black_box(None),
|
||||
black_box(&gens),
|
||||
black_box(&mut prover_transcript),
|
||||
black_box(&mut random_tape),
|
||||
);
|
||||
let name = format!("polycommit_evalproofverify_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
let mut verifier_transcript = Transcript::new(b"example");
|
||||
|
||||
proof.verify(
|
||||
black_box(&gens),
|
||||
black_box(&mut verifier_transcript),
|
||||
black_box(&r),
|
||||
black_box(&c_zr),
|
||||
black_box(&poly_commitment),
|
||||
)
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn set_duration() -> Criterion {
|
||||
Criterion::default().sample_size(10)
|
||||
// .measurement_time(Duration::new(0, 50000000))
|
||||
}
|
||||
|
||||
criterion_group! {
|
||||
name = benches_polycommit;
|
||||
config = set_duration();
|
||||
targets = commit_benchmark, eval_benchmark, evalproof_benchmark, evalproofverify_benchmark
|
||||
}
|
||||
|
||||
criterion_main!(benches_polycommit);
|
|
@ -0,0 +1,130 @@
|
|||
extern crate byteorder;
|
||||
extern crate core;
|
||||
extern crate criterion;
|
||||
extern crate digest;
|
||||
extern crate libspartan;
|
||||
extern crate merlin;
|
||||
extern crate rand;
|
||||
extern crate sha3;
|
||||
|
||||
use libspartan::r1csinstance::R1CSInstance;
|
||||
use libspartan::spartan::{SNARKGens, SNARK};
|
||||
use merlin::Transcript;
|
||||
|
||||
use criterion::*;
|
||||
|
||||
fn snark_encode_benchmark(c: &mut Criterion) {
|
||||
for &s in [10, 12, 16].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("SNARK_encode_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let num_vars = (2 as usize).pow(s as u32);
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
let (inst, _vars, _input) =
|
||||
R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
let n = inst.get_num_vars();
|
||||
|
||||
// produce public parameters
|
||||
let gens = SNARKGens::new(&inst.size());
|
||||
|
||||
let name = format!("SNARK_encode_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
SNARK::encode(black_box(&inst), black_box(&gens));
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn snark_prove_benchmark(c: &mut Criterion) {
|
||||
for &s in [10, 12, 16].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("SNARK_prove_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let num_vars = (2 as usize).pow(s as u32);
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
|
||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
let n = inst.get_num_vars();
|
||||
|
||||
// produce public parameters
|
||||
let gens = SNARKGens::new(&inst.size());
|
||||
|
||||
// encode the R1CS instance
|
||||
let (_comm, decomm) = SNARK::encode(&inst, &gens);
|
||||
|
||||
// produce a proof
|
||||
let name = format!("SNARK_prove_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
SNARK::prove(
|
||||
black_box(&inst),
|
||||
black_box(&decomm),
|
||||
black_box(vars.clone()),
|
||||
black_box(&input),
|
||||
black_box(&gens),
|
||||
black_box(&mut prover_transcript),
|
||||
);
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn snark_verify_benchmark(c: &mut Criterion) {
|
||||
for &s in [10, 12, 16].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("SNARK_verify_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let num_vars = (2 as usize).pow(s as u32);
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
let n = inst.get_num_vars();
|
||||
|
||||
// produce public parameters
|
||||
let gens = SNARKGens::new(&inst.size());
|
||||
|
||||
// encode the R1CS instance
|
||||
let (comm, decomm) = SNARK::encode(&inst, &gens);
|
||||
|
||||
// produce a proof of satisfiability
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
let proof = SNARK::prove(&inst, &decomm, vars, &input, &gens, &mut prover_transcript);
|
||||
|
||||
let name = format!("SNARK_verify_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
let mut verifier_transcript = Transcript::new(b"example");
|
||||
assert!(proof
|
||||
.verify(
|
||||
black_box(&comm),
|
||||
black_box(&input),
|
||||
black_box(&mut verifier_transcript),
|
||||
black_box(&gens)
|
||||
)
|
||||
.is_ok());
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn set_duration() -> Criterion {
|
||||
Criterion::default().sample_size(10)
|
||||
}
|
||||
|
||||
criterion_group! {
|
||||
name = benches_snark;
|
||||
config = set_duration();
|
||||
targets = snark_encode_benchmark, snark_prove_benchmark, snark_verify_benchmark
|
||||
}
|
||||
|
||||
criterion_main!(benches_snark);
|
|
@ -1,206 +0,0 @@
|
|||
extern crate byteorder;
|
||||
extern crate core;
|
||||
extern crate criterion;
|
||||
extern crate digest;
|
||||
extern crate libspartan;
|
||||
extern crate merlin;
|
||||
extern crate rand;
|
||||
extern crate sha3;
|
||||
|
||||
use libspartan::math::Math;
|
||||
use libspartan::r1csinstance::{R1CSCommitmentGens, R1CSInstance};
|
||||
use libspartan::r1csproof::R1CSGens;
|
||||
use libspartan::spartan::{NIZKGens, SNARKGens, NIZK, SNARK};
|
||||
use merlin::Transcript;
|
||||
|
||||
use criterion::*;
|
||||
|
||||
fn snark_encode_benchmark(c: &mut Criterion) {
|
||||
for &s in [10, 12, 16].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("SNARK_encode_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let num_vars = s.pow2();
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
let (inst, _vars, _input) =
|
||||
R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
let n = inst.get_num_vars();
|
||||
let r1cs_size = inst.size();
|
||||
let gens_r1cs = R1CSCommitmentGens::new(&r1cs_size, b"gens_r1cs");
|
||||
|
||||
let name = format!("SNARK_encode_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
SNARK::encode(black_box(&inst), black_box(&gens_r1cs));
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn snark_prove_benchmark(c: &mut Criterion) {
|
||||
for &s in [10, 12, 16].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("SNARK_prove_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let num_vars = s.pow2();
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
|
||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
let n = inst.get_num_vars();
|
||||
|
||||
let r1cs_size = inst.size();
|
||||
let gens_r1cs_eval = R1CSCommitmentGens::new(&r1cs_size, b"gens_r1cs_eval");
|
||||
let gens_r1cs_sat = R1CSGens::new(num_cons, num_vars, b"gens_r1cs_sat");
|
||||
|
||||
// produce a proof of satisfiability
|
||||
let (_comm, decomm) = SNARK::encode(&inst, &gens_r1cs_eval);
|
||||
let gens = SNARKGens::new(gens_r1cs_sat, gens_r1cs_eval);
|
||||
|
||||
let name = format!("SNARK_prove_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
SNARK::prove(
|
||||
black_box(&inst),
|
||||
black_box(&decomm),
|
||||
black_box(vars.clone()),
|
||||
black_box(&input),
|
||||
black_box(&gens),
|
||||
black_box(&mut prover_transcript),
|
||||
);
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn snark_verify_benchmark(c: &mut Criterion) {
|
||||
for &s in [10, 12, 16].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("SNARK_verify_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let num_vars = s.pow2();
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
let n = inst.get_num_vars();
|
||||
|
||||
let r1cs_size = inst.size();
|
||||
let gens_r1cs_eval = R1CSCommitmentGens::new(&r1cs_size, b"gens_r1cs_eval");
|
||||
|
||||
// create a commitment to R1CSInstance
|
||||
let (comm, decomm) = SNARK::encode(&inst, &gens_r1cs_eval);
|
||||
|
||||
let gens_r1cs_sat = R1CSGens::new(num_cons, num_vars, b"gens_r1cs_sat");
|
||||
let gens = SNARKGens::new(gens_r1cs_sat, gens_r1cs_eval);
|
||||
|
||||
// produce a proof of satisfiability
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
let proof = SNARK::prove(&inst, &decomm, vars, &input, &gens, &mut prover_transcript);
|
||||
|
||||
let name = format!("SNARK_verify_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
let mut verifier_transcript = Transcript::new(b"example");
|
||||
assert!(proof
|
||||
.verify(
|
||||
black_box(&comm),
|
||||
black_box(&input),
|
||||
black_box(&mut verifier_transcript),
|
||||
black_box(&gens)
|
||||
)
|
||||
.is_ok());
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn nizk_prove_benchmark(c: &mut Criterion) {
|
||||
for &s in [10, 12, 16].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("NIZK_prove_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let num_vars = s.pow2();
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
|
||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
let n = inst.get_num_vars();
|
||||
|
||||
let gens_r1cs_sat = R1CSGens::new(num_cons, num_vars, b"gens_r1cs_sat");
|
||||
let gens = NIZKGens::new(gens_r1cs_sat);
|
||||
|
||||
let name = format!("NIZK_prove_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
NIZK::prove(
|
||||
black_box(&inst),
|
||||
black_box(vars.clone()),
|
||||
black_box(&input),
|
||||
black_box(&gens),
|
||||
black_box(&mut prover_transcript),
|
||||
);
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn nizk_verify_benchmark(c: &mut Criterion) {
|
||||
for &s in [10, 12, 16].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("NIZK_verify_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
let num_vars = s.pow2();
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
let n = inst.get_num_vars();
|
||||
|
||||
let gens_r1cs_sat = R1CSGens::new(num_cons, num_vars, b"gens_r1cs_sat");
|
||||
let gens = NIZKGens::new(gens_r1cs_sat);
|
||||
|
||||
// produce a proof of satisfiability
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
let proof = NIZK::prove(&inst, vars, &input, &gens, &mut prover_transcript);
|
||||
|
||||
let name = format!("NIZK_verify_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
let mut verifier_transcript = Transcript::new(b"example");
|
||||
assert!(proof
|
||||
.verify(
|
||||
black_box(&inst),
|
||||
black_box(&input),
|
||||
black_box(&mut verifier_transcript),
|
||||
black_box(&gens)
|
||||
)
|
||||
.is_ok());
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn set_duration() -> Criterion {
|
||||
Criterion::default().sample_size(10)
|
||||
// .measurement_time(Duration::new(0, 50000000))
|
||||
}
|
||||
|
||||
criterion_group! {
|
||||
name = benches_spartan;
|
||||
config = set_duration();
|
||||
targets = snark_encode_benchmark, snark_prove_benchmark, snark_verify_benchmark, nizk_prove_benchmark, nizk_verify_benchmark
|
||||
}
|
||||
|
||||
criterion_main!(benches_spartan);
|
|
@ -1,152 +0,0 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
extern crate byteorder;
|
||||
extern crate core;
|
||||
extern crate criterion;
|
||||
extern crate digest;
|
||||
extern crate libspartan;
|
||||
extern crate merlin;
|
||||
extern crate rand;
|
||||
extern crate sha3;
|
||||
|
||||
use libspartan::commitments::Commitments;
|
||||
use libspartan::commitments::MultiCommitGens;
|
||||
use libspartan::dense_mlpoly::DensePolynomial;
|
||||
use libspartan::math::Math;
|
||||
use libspartan::nizk::DotProductProof;
|
||||
use libspartan::random::RandomTape;
|
||||
use libspartan::scalar::Scalar;
|
||||
use libspartan::sumcheck::ZKSumcheckInstanceProof;
|
||||
use libspartan::transcript::ProofTranscript;
|
||||
use merlin::Transcript;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
use criterion::*;
|
||||
|
||||
fn prove_benchmark(c: &mut Criterion) {
|
||||
for &s in [10, 12, 16, 20].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("zksumcheck_prove_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
// produce tables
|
||||
let gens_n = MultiCommitGens::new(3, b"test-m");
|
||||
let gens_1 = MultiCommitGens::new(1, b"test-1");
|
||||
let num_rounds = s;
|
||||
let n = s.pow2();
|
||||
|
||||
let mut csprng: OsRng = OsRng;
|
||||
|
||||
let vec_A = (0..n)
|
||||
.map(|_i| Scalar::random(&mut csprng))
|
||||
.collect::<Vec<Scalar>>();
|
||||
let vec_B = (0..n)
|
||||
.map(|_i| Scalar::random(&mut csprng))
|
||||
.collect::<Vec<Scalar>>();
|
||||
let claim = DotProductProof::compute_dotproduct(&vec_A, &vec_B);
|
||||
let mut poly_A = DensePolynomial::new(vec_A);
|
||||
let mut poly_B = DensePolynomial::new(vec_B);
|
||||
|
||||
let blind_claim = Scalar::random(&mut csprng);
|
||||
let comb_func =
|
||||
|poly_A_comp: &Scalar, poly_B_comp: &Scalar| -> Scalar { poly_A_comp * poly_B_comp };
|
||||
|
||||
let name = format!("zksumcheck_prove_{}", n);
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
let mut random_tape = RandomTape::new(b"proof");
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
ZKSumcheckInstanceProof::prove_quad(
|
||||
black_box(&claim),
|
||||
black_box(&blind_claim),
|
||||
black_box(num_rounds),
|
||||
black_box(&mut poly_A),
|
||||
black_box(&mut poly_B),
|
||||
black_box(comb_func),
|
||||
black_box(&gens_1),
|
||||
black_box(&gens_n),
|
||||
black_box(&mut prover_transcript),
|
||||
black_box(&mut random_tape),
|
||||
)
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_benchmark(c: &mut Criterion) {
|
||||
for &s in [10, 12, 16, 20].iter() {
|
||||
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic);
|
||||
let mut group = c.benchmark_group("zksumcheck_verify_benchmark");
|
||||
group.plot_config(plot_config);
|
||||
|
||||
// produce tables
|
||||
let gens_n = MultiCommitGens::new(3, b"test-m");
|
||||
let gens_1 = MultiCommitGens::new(1, b"test-1");
|
||||
let num_rounds = s;
|
||||
let n = s.pow2();
|
||||
|
||||
let mut csprng: OsRng = OsRng;
|
||||
|
||||
let vec_A = (0..n)
|
||||
.map(|_i| Scalar::random(&mut csprng))
|
||||
.collect::<Vec<Scalar>>();
|
||||
let vec_B = (0..n)
|
||||
.map(|_i| Scalar::random(&mut csprng))
|
||||
.collect::<Vec<Scalar>>();
|
||||
let claim = DotProductProof::compute_dotproduct(&vec_A, &vec_B);
|
||||
let mut poly_A = DensePolynomial::new(vec_A);
|
||||
let mut poly_B = DensePolynomial::new(vec_B);
|
||||
let blind_claim = Scalar::random(&mut csprng);
|
||||
let comb_func =
|
||||
|poly_A_comp: &Scalar, poly_B_comp: &Scalar| -> Scalar { poly_A_comp * poly_B_comp };
|
||||
|
||||
let mut random_tape = RandomTape::new(b"proof");
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
let (proof, _r, _v, _blind_post_claim) = ZKSumcheckInstanceProof::prove_quad(
|
||||
&claim,
|
||||
&blind_claim,
|
||||
num_rounds,
|
||||
&mut poly_A,
|
||||
&mut poly_B,
|
||||
comb_func,
|
||||
&gens_1,
|
||||
&gens_n,
|
||||
&mut prover_transcript,
|
||||
&mut random_tape,
|
||||
);
|
||||
|
||||
let name = format!("zksumcheck_verify_{}", n);
|
||||
let degree_bound = 2;
|
||||
let comm_claim = claim.commit(&blind_claim, &gens_1).compress();
|
||||
group.bench_function(&name, move |b| {
|
||||
b.iter(|| {
|
||||
let mut verifier_transcript = Transcript::new(b"example");
|
||||
assert!(proof
|
||||
.verify(
|
||||
black_box(&comm_claim),
|
||||
black_box(num_rounds),
|
||||
black_box(degree_bound),
|
||||
black_box(&gens_1),
|
||||
black_box(&gens_n),
|
||||
black_box(&mut verifier_transcript)
|
||||
)
|
||||
.is_ok())
|
||||
});
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
}
|
||||
|
||||
fn set_duration() -> Criterion {
|
||||
Criterion::default().sample_size(10)
|
||||
// .measurement_time(Duration::new(0, 50000000))
|
||||
}
|
||||
|
||||
criterion_group! {
|
||||
name = benches_r1cs;
|
||||
config = set_duration();
|
||||
targets = verify_benchmark, prove_benchmark
|
||||
}
|
||||
|
||||
criterion_main!(benches_r1cs);
|
|
@ -0,0 +1,51 @@
|
|||
#![allow(non_snake_case)]
|
||||
extern crate flate2;
|
||||
extern crate libspartan;
|
||||
extern crate merlin;
|
||||
extern crate rand;
|
||||
|
||||
use flate2::{write::ZlibEncoder, Compression};
|
||||
use libspartan::r1csinstance::R1CSInstance;
|
||||
use libspartan::spartan::{NIZKGens, NIZK};
|
||||
use libspartan::timer::Timer;
|
||||
use merlin::Transcript;
|
||||
|
||||
pub fn main() {
|
||||
// the list of number of variables (and constraints) in an R1CS instance
|
||||
let inst_sizes = vec![12, 16, 20];
|
||||
|
||||
println!("Profiler:: NIZK");
|
||||
for &s in inst_sizes.iter() {
|
||||
let num_vars = (2 as usize).pow(s as u32);
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
|
||||
Timer::print(&format!("number_of_constraints {}", num_cons));
|
||||
|
||||
// produce public generators
|
||||
let gens = NIZKGens::new(num_cons, num_vars);
|
||||
|
||||
// produce a proof of satisfiability
|
||||
let timer_prove = Timer::new("NIZK::prove");
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
let proof = NIZK::prove(&inst, vars, &input, &gens, &mut prover_transcript);
|
||||
timer_prove.stop();
|
||||
|
||||
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
|
||||
bincode::serialize_into(&mut encoder, &proof).unwrap();
|
||||
let proof_encoded = encoder.finish().unwrap();
|
||||
let msg_proof_len = format!("NIZK::proof_compressed_len {:?}", proof_encoded.len());
|
||||
Timer::print(&msg_proof_len);
|
||||
|
||||
// verify the proof of satisfiability
|
||||
let timer_verify = Timer::new("NIZK::verify");
|
||||
let mut verifier_transcript = Transcript::new(b"example");
|
||||
assert!(proof
|
||||
.verify(&inst, &input, &mut verifier_transcript, &gens)
|
||||
.is_ok());
|
||||
timer_verify.stop();
|
||||
|
||||
println!();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
#![allow(non_snake_case)]
|
||||
extern crate flate2;
|
||||
extern crate libspartan;
|
||||
extern crate merlin;
|
||||
extern crate rand;
|
||||
|
||||
use flate2::{write::ZlibEncoder, Compression};
|
||||
use libspartan::r1csinstance::R1CSInstance;
|
||||
use libspartan::spartan::{SNARKGens, SNARK};
|
||||
use libspartan::timer::Timer;
|
||||
use merlin::Transcript;
|
||||
|
||||
pub fn main() {
|
||||
// the list of number of variables (and constraints) in an R1CS instance
|
||||
let inst_sizes = vec![12, 16, 20];
|
||||
|
||||
println!("Profiler:: SNARK");
|
||||
for &s in inst_sizes.iter() {
|
||||
let num_vars = (2 as usize).pow(s as u32);
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
|
||||
Timer::print(&format!("number_of_constraints {}", num_cons));
|
||||
|
||||
// produce public generators
|
||||
let gens = SNARKGens::new(&inst.size());
|
||||
|
||||
// create a commitment to R1CSInstance
|
||||
let timer_encode = Timer::new("SNARK::encode");
|
||||
let (comm, decomm) = SNARK::encode(&inst, &gens);
|
||||
timer_encode.stop();
|
||||
|
||||
// produce a proof of satisfiability
|
||||
let timer_prove = Timer::new("SNARK::prove");
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
let proof = SNARK::prove(&inst, &decomm, vars, &input, &gens, &mut prover_transcript);
|
||||
timer_prove.stop();
|
||||
|
||||
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
|
||||
bincode::serialize_into(&mut encoder, &proof).unwrap();
|
||||
let proof_encoded = encoder.finish().unwrap();
|
||||
let msg_proof_len = format!("SNARK::proof_compressed_len {:?}", proof_encoded.len());
|
||||
Timer::print(&msg_proof_len);
|
||||
|
||||
// verify the proof of satisfiability
|
||||
let timer_verify = Timer::new("SNARK::verify");
|
||||
let mut verifier_transcript = Transcript::new(b"example");
|
||||
assert!(proof
|
||||
.verify(&comm, &input, &mut verifier_transcript, &gens)
|
||||
.is_ok());
|
||||
timer_verify.stop();
|
||||
|
||||
println!();
|
||||
}
|
||||
}
|
|
@ -115,41 +115,6 @@ impl EqPolynomial {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ConstPolynomial {
|
||||
num_vars: usize,
|
||||
c: Scalar,
|
||||
}
|
||||
|
||||
impl ConstPolynomial {
|
||||
pub fn new(num_vars: usize, c: Scalar) -> Self {
|
||||
ConstPolynomial { num_vars, c }
|
||||
}
|
||||
|
||||
pub fn evaluate(&self, rx: &Vec<Scalar>) -> Scalar {
|
||||
assert_eq!(self.num_vars, rx.len());
|
||||
self.c
|
||||
}
|
||||
|
||||
pub fn get_num_vars(&self) -> usize {
|
||||
self.num_vars
|
||||
}
|
||||
|
||||
/// produces a binding commitment
|
||||
pub fn commit(&self, gens: &PolyCommitmentGens) -> PolyCommitment {
|
||||
let ell = self.get_num_vars();
|
||||
|
||||
let (left_num_vars, right_num_vars) = EqPolynomial::compute_factored_lens(ell);
|
||||
let L_size = left_num_vars.pow2();
|
||||
let R_size = right_num_vars.pow2();
|
||||
assert_eq!(L_size * R_size, ell.pow2());
|
||||
|
||||
let vec = vec![self.c; R_size];
|
||||
|
||||
let c = vec.commit(&Scalar::zero(), &gens.gens.gens_n).compress();
|
||||
PolyCommitment { C: vec![c; L_size] }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IdentityPolynomial {
|
||||
size_point: usize,
|
||||
}
|
||||
|
@ -456,48 +421,6 @@ impl PolyEvalProof {
|
|||
.verify(R.len(), &gens.gens, transcript, &R, &C_LZ, C_Zr)
|
||||
}
|
||||
|
||||
pub fn verify_batched(
|
||||
&self,
|
||||
gens: &PolyCommitmentGens,
|
||||
transcript: &mut Transcript,
|
||||
r: &Vec<Scalar>, // point at which the polynomial is evaluated
|
||||
C_Zr: &CompressedGroup, // commitment to \widetilde{Z}(r)
|
||||
comm: &[&PolyCommitment],
|
||||
coeff: &[&Scalar],
|
||||
) -> Result<(), ProofVerifyError> {
|
||||
transcript.append_protocol_name(PolyEvalProof::protocol_name());
|
||||
|
||||
// compute L and R
|
||||
let eq = EqPolynomial::new(r.to_vec());
|
||||
let (L, R) = eq.compute_factored_evals();
|
||||
|
||||
// compute a weighted sum of commitments and L
|
||||
let C_decompressed: Vec<Vec<GroupElement>> = (0..comm.len())
|
||||
.map(|i| {
|
||||
comm[i]
|
||||
.C
|
||||
.iter()
|
||||
.map(|pt| pt.decompress().unwrap())
|
||||
.collect()
|
||||
})
|
||||
.collect();
|
||||
|
||||
let C_LZ: Vec<GroupElement> = (0..comm.len())
|
||||
.map(|i| GroupElement::vartime_multiscalar_mul(&L, &C_decompressed[i]))
|
||||
.collect();
|
||||
|
||||
let C_LZ_combined: GroupElement = (0..C_LZ.len()).map(|i| C_LZ[i] * coeff[i]).sum();
|
||||
|
||||
self.proof.verify(
|
||||
R.len(),
|
||||
&gens.gens,
|
||||
transcript,
|
||||
&R,
|
||||
&C_LZ_combined.compress(),
|
||||
C_Zr,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn verify_plain(
|
||||
&self,
|
||||
gens: &PolyCommitmentGens,
|
||||
|
@ -511,23 +434,6 @@ impl PolyEvalProof {
|
|||
|
||||
self.verify(gens, transcript, r, &C_Zr, comm)
|
||||
}
|
||||
|
||||
pub fn verify_plain_batched(
|
||||
&self,
|
||||
gens: &PolyCommitmentGens,
|
||||
transcript: &mut Transcript,
|
||||
r: &Vec<Scalar>, // point at which the polynomial is evaluated
|
||||
Zr: &Scalar, // evaluation \widetilde{Z}(r)
|
||||
comm: &[&PolyCommitment],
|
||||
coeff: &[&Scalar],
|
||||
) -> Result<(), ProofVerifyError> {
|
||||
// compute a commitment to Zr with a blind of zero
|
||||
let C_Zr = Zr.commit(&Scalar::zero(), &gens.gens.gens_1).compress();
|
||||
|
||||
assert_eq!(comm.len(), coeff.len());
|
||||
|
||||
self.verify_batched(gens, transcript, r, &C_Zr, comm, coeff)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
20
src/lib.rs
20
src/lib.rs
|
@ -11,20 +11,20 @@ extern crate rayon;
|
|||
extern crate sha3;
|
||||
extern crate test;
|
||||
|
||||
pub mod commitments;
|
||||
pub mod dense_mlpoly;
|
||||
mod commitments;
|
||||
mod dense_mlpoly;
|
||||
mod errors;
|
||||
mod group;
|
||||
pub mod math;
|
||||
pub mod nizk;
|
||||
mod math;
|
||||
mod nizk;
|
||||
mod product_tree;
|
||||
pub mod r1csinstance;
|
||||
pub mod r1csproof;
|
||||
pub mod random;
|
||||
pub mod scalar;
|
||||
pub mod sparse_mlpoly;
|
||||
mod r1csproof;
|
||||
mod random;
|
||||
mod scalar;
|
||||
mod sparse_mlpoly;
|
||||
pub mod spartan;
|
||||
pub mod sumcheck;
|
||||
mod sumcheck;
|
||||
pub mod timer;
|
||||
pub mod transcript;
|
||||
mod transcript;
|
||||
mod unipoly;
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
#![allow(non_snake_case)]
|
||||
extern crate flate2;
|
||||
extern crate libspartan;
|
||||
extern crate merlin;
|
||||
extern crate rand;
|
||||
|
||||
use flate2::{write::ZlibEncoder, Compression};
|
||||
use libspartan::math::Math;
|
||||
use libspartan::r1csinstance::{R1CSCommitmentGens, R1CSInstance};
|
||||
use libspartan::r1csproof::R1CSGens;
|
||||
use libspartan::spartan::{NIZKGens, SNARKGens, NIZK, SNARK};
|
||||
use libspartan::timer::Timer;
|
||||
use merlin::Transcript;
|
||||
|
||||
pub fn main() {
|
||||
// the list of number of variables (and constraints) in an R1CS instance
|
||||
let inst_sizes = vec![12, 16, 20];
|
||||
|
||||
println!("Profiler:: SNARK");
|
||||
for &s in inst_sizes.iter() {
|
||||
let num_vars = (s as usize).pow2();
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
|
||||
Timer::print(&format!("number_of_constraints {}", num_cons));
|
||||
|
||||
let r1cs_size = inst.size();
|
||||
let gens_r1cs_eval = R1CSCommitmentGens::new(&r1cs_size, b"gens_r1cs_eval");
|
||||
|
||||
// create a commitment to R1CSInstance
|
||||
let timer_encode = Timer::new("SNARK::encode");
|
||||
let (comm, decomm) = SNARK::encode(&inst, &gens_r1cs_eval);
|
||||
timer_encode.stop();
|
||||
|
||||
let gens_r1cs_sat = R1CSGens::new(num_cons, num_vars, b"gens_r1cs_sat");
|
||||
let gens = SNARKGens::new(gens_r1cs_sat, gens_r1cs_eval);
|
||||
|
||||
// produce a proof of satisfiability
|
||||
let timer_prove = Timer::new("SNARK::prove");
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
let proof = SNARK::prove(&inst, &decomm, vars, &input, &gens, &mut prover_transcript);
|
||||
timer_prove.stop();
|
||||
|
||||
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
|
||||
bincode::serialize_into(&mut encoder, &proof).unwrap();
|
||||
let proof_encoded = encoder.finish().unwrap();
|
||||
let msg_proof_len = format!("SNARK::proof_compressed_len {:?}", proof_encoded.len());
|
||||
Timer::print(&msg_proof_len);
|
||||
|
||||
// verify the proof of satisfiability
|
||||
let timer_verify = Timer::new("SNARK::verify");
|
||||
let mut verifier_transcript = Transcript::new(b"example");
|
||||
assert!(proof
|
||||
.verify(&comm, &input, &mut verifier_transcript, &gens)
|
||||
.is_ok());
|
||||
timer_verify.stop();
|
||||
|
||||
println!();
|
||||
}
|
||||
|
||||
println!("Profiler:: NIZK");
|
||||
for &s in inst_sizes.iter() {
|
||||
let num_vars = (s as usize).pow2();
|
||||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
|
||||
Timer::print(&format!("number_of_constraints {}", num_cons));
|
||||
|
||||
let gens_r1cs_sat = R1CSGens::new(num_cons, num_vars, b"gens_r1cs_sat");
|
||||
let gens = NIZKGens::new(gens_r1cs_sat);
|
||||
|
||||
// produce a proof of satisfiability
|
||||
let timer_prove = Timer::new("NIZK::prove");
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
let proof = NIZK::prove(&inst, vars, &input, &gens, &mut prover_transcript);
|
||||
timer_prove.stop();
|
||||
|
||||
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
|
||||
bincode::serialize_into(&mut encoder, &proof).unwrap();
|
||||
let proof_encoded = encoder.finish().unwrap();
|
||||
let msg_proof_len = format!("NIZK::proof_compressed_len {:?}", proof_encoded.len());
|
||||
Timer::print(&msg_proof_len);
|
||||
|
||||
// verify the proof of satisfiability
|
||||
let timer_verify = Timer::new("NIZK::verify");
|
||||
let mut verifier_transcript = Transcript::new(b"example");
|
||||
assert!(proof
|
||||
.verify(&inst, &input, &mut verifier_transcript, &gens)
|
||||
.is_ok());
|
||||
timer_verify.stop();
|
||||
|
||||
println!();
|
||||
}
|
||||
}
|
|
@ -25,11 +25,28 @@ pub struct R1CSInstance {
|
|||
}
|
||||
|
||||
pub struct R1CSInstanceSize {
|
||||
num_cons: usize,
|
||||
num_vars: usize,
|
||||
num_inputs: usize,
|
||||
size_A: SparseMatPolynomialSize,
|
||||
size_B: SparseMatPolynomialSize,
|
||||
size_C: SparseMatPolynomialSize,
|
||||
}
|
||||
|
||||
impl R1CSInstanceSize {
|
||||
pub fn get_num_cons(&self) -> usize {
|
||||
self.num_cons
|
||||
}
|
||||
|
||||
pub fn get_num_vars(&self) -> usize {
|
||||
self.num_vars
|
||||
}
|
||||
|
||||
pub fn get_num_inputs(&self) -> usize {
|
||||
self.num_inputs
|
||||
}
|
||||
}
|
||||
|
||||
pub struct R1CSCommitmentGens {
|
||||
gens: SparseMatPolyCommitmentGens,
|
||||
}
|
||||
|
@ -124,6 +141,9 @@ impl R1CSInstance {
|
|||
|
||||
pub fn size(&self) -> R1CSInstanceSize {
|
||||
R1CSInstanceSize {
|
||||
num_cons: self.num_cons,
|
||||
num_vars: self.num_vars,
|
||||
num_inputs: self.num_inputs,
|
||||
size_A: self.A.size(),
|
||||
size_B: self.B.size(),
|
||||
size_C: self.C.size(),
|
||||
|
|
|
@ -2,7 +2,7 @@ use super::dense_mlpoly::EqPolynomial;
|
|||
use super::errors::ProofVerifyError;
|
||||
use super::r1csinstance::{
|
||||
R1CSCommitment, R1CSCommitmentGens, R1CSDecommitment, R1CSEvalProof, R1CSInstance,
|
||||
R1CSInstanceEvals,
|
||||
R1CSInstanceEvals, R1CSInstanceSize,
|
||||
};
|
||||
use super::r1csproof::{R1CSGens, R1CSProof};
|
||||
use super::random::RandomTape;
|
||||
|
@ -18,7 +18,9 @@ pub struct SNARKGens {
|
|||
}
|
||||
|
||||
impl SNARKGens {
|
||||
pub fn new(gens_r1cs_sat: R1CSGens, gens_r1cs_eval: R1CSCommitmentGens) -> Self {
|
||||
pub fn new(size: &R1CSInstanceSize) -> Self {
|
||||
let gens_r1cs_sat = R1CSGens::new(size.get_num_cons(), size.get_num_vars(), b"gens_r1cs_sat");
|
||||
let gens_r1cs_eval = R1CSCommitmentGens::new(size, b"gens_r1cs_eval");
|
||||
SNARKGens {
|
||||
gens_r1cs_sat,
|
||||
gens_r1cs_eval,
|
||||
|
@ -39,11 +41,8 @@ impl SNARK {
|
|||
}
|
||||
|
||||
/// A public computation to create a commitment to an R1CS instance
|
||||
pub fn encode(
|
||||
inst: &R1CSInstance,
|
||||
gens: &R1CSCommitmentGens,
|
||||
) -> (R1CSCommitment, R1CSDecommitment) {
|
||||
inst.commit(gens)
|
||||
pub fn encode(inst: &R1CSInstance, gens: &SNARKGens) -> (R1CSCommitment, R1CSDecommitment) {
|
||||
inst.commit(&gens.gens_r1cs_eval)
|
||||
}
|
||||
|
||||
/// A method to produce a proof of the satisfiability of an R1CS instance
|
||||
|
@ -158,7 +157,8 @@ pub struct NIZKGens {
|
|||
}
|
||||
|
||||
impl NIZKGens {
|
||||
pub fn new(gens_r1cs_sat: R1CSGens) -> Self {
|
||||
pub fn new(num_cons: usize, num_vars: usize) -> Self {
|
||||
let gens_r1cs_sat = R1CSGens::new(num_cons, num_vars, b"gens_r1cs_sat");
|
||||
NIZKGens { gens_r1cs_sat }
|
||||
}
|
||||
}
|
||||
|
@ -261,19 +261,19 @@ mod tests {
|
|||
let num_cons = num_vars;
|
||||
let num_inputs = 10;
|
||||
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
|
||||
|
||||
let r1cs_size = inst.size();
|
||||
let gens_r1cs_eval = R1CSCommitmentGens::new(&r1cs_size, b"gens_r1cs_eval");
|
||||
|
||||
// produce public generators
|
||||
let gens = SNARKGens::new(&r1cs_size);
|
||||
|
||||
// create a commitment to R1CSInstance
|
||||
let (comm, decomm) = SNARK::encode(&inst, &gens_r1cs_eval);
|
||||
|
||||
let gens_r1cs_sat = R1CSGens::new(num_cons, num_vars, b"gens_r1cs_sat");
|
||||
let gens = SNARKGens::new(gens_r1cs_sat, gens_r1cs_eval);
|
||||
let (comm, decomm) = SNARK::encode(&inst, &gens);
|
||||
|
||||
// produce a proof
|
||||
let mut prover_transcript = Transcript::new(b"example");
|
||||
let proof = SNARK::prove(&inst, &decomm, vars, &input, &gens, &mut prover_transcript);
|
||||
|
||||
// verify the proof
|
||||
let mut verifier_transcript = Transcript::new(b"example");
|
||||
assert!(proof
|
||||
.verify(&comm, &input, &mut verifier_transcript, &gens)
|
||||
|
|
131
src/sumcheck.rs
131
src/sumcheck.rs
|
@ -176,59 +176,6 @@ impl ZKSumcheckInstanceProof {
|
|||
}
|
||||
|
||||
impl SumcheckInstanceProof {
|
||||
pub fn prove_quad<F>(
|
||||
claim: &Scalar,
|
||||
num_rounds: usize,
|
||||
poly_A: &mut DensePolynomial,
|
||||
poly_B: &mut DensePolynomial,
|
||||
comb_func: F,
|
||||
transcript: &mut Transcript,
|
||||
) -> (Self, Vec<Scalar>, Vec<Scalar>)
|
||||
where
|
||||
F: Fn(&Scalar, &Scalar) -> Scalar,
|
||||
{
|
||||
let mut e = *claim;
|
||||
let mut r: Vec<Scalar> = Vec::new();
|
||||
let mut quad_polys: Vec<CompressedUniPoly> = Vec::new();
|
||||
for _j in 0..num_rounds {
|
||||
let mut eval_point_0 = Scalar::zero();
|
||||
let mut eval_point_2 = Scalar::zero();
|
||||
|
||||
let len = poly_A.len() / 2;
|
||||
for i in 0..len {
|
||||
// eval 0: bound_func is A(low)
|
||||
eval_point_0 = &eval_point_0 + comb_func(&poly_A[i], &poly_B[i]);
|
||||
|
||||
// eval 2: bound_func is -A(low) + 2*A(high)
|
||||
let poly_A_bound_point = &poly_A[len + i] + &poly_A[len + i] - &poly_A[i];
|
||||
let poly_B_bound_point = &poly_B[len + i] + &poly_B[len + i] - &poly_B[i];
|
||||
eval_point_2 = &eval_point_2 + comb_func(&poly_A_bound_point, &poly_B_bound_point);
|
||||
}
|
||||
|
||||
let evals = vec![eval_point_0, e - eval_point_0, eval_point_2];
|
||||
let poly = UniPoly::from_evals(&evals);
|
||||
|
||||
// append the prover's message to the transcript
|
||||
poly.append_to_transcript(b"poly", transcript);
|
||||
|
||||
//derive the verifier's challenge for the next round
|
||||
let r_j = transcript.challenge_scalar(b"challenge_nextround");
|
||||
r.push(r_j);
|
||||
// bound all tables to the verifier's challenege
|
||||
poly_A.bound_poly_var_top(&r_j);
|
||||
poly_B.bound_poly_var_top(&r_j);
|
||||
|
||||
e = poly.evaluate(&r_j);
|
||||
quad_polys.push(poly.compress());
|
||||
}
|
||||
|
||||
(
|
||||
SumcheckInstanceProof::new(quad_polys),
|
||||
r,
|
||||
vec![poly_A[0], poly_B[0]],
|
||||
)
|
||||
}
|
||||
|
||||
pub fn prove_cubic<F>(
|
||||
claim: &Scalar,
|
||||
num_rounds: usize,
|
||||
|
@ -302,84 +249,6 @@ impl SumcheckInstanceProof {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn prove_cubic_with_additive_term<F>(
|
||||
claim: &Scalar,
|
||||
num_rounds: usize,
|
||||
poly_A: &mut DensePolynomial,
|
||||
poly_B: &mut DensePolynomial,
|
||||
poly_C: &mut DensePolynomial,
|
||||
poly_D: &mut DensePolynomial,
|
||||
comb_func: F,
|
||||
transcript: &mut Transcript,
|
||||
) -> (Self, Vec<Scalar>, Vec<Scalar>)
|
||||
where
|
||||
F: Fn(&Scalar, &Scalar, &Scalar, &Scalar) -> Scalar,
|
||||
{
|
||||
let mut e = *claim;
|
||||
let mut r: Vec<Scalar> = Vec::new();
|
||||
let mut cubic_polys: Vec<CompressedUniPoly> = Vec::new();
|
||||
for _j in 0..num_rounds {
|
||||
let mut eval_point_0 = Scalar::zero();
|
||||
let mut eval_point_2 = Scalar::zero();
|
||||
let mut eval_point_3 = Scalar::zero();
|
||||
|
||||
let len = poly_A.len() / 2;
|
||||
for i in 0..len {
|
||||
// eval 0: bound_func is A(low)
|
||||
eval_point_0 = &eval_point_0 + comb_func(&poly_A[i], &poly_B[i], &poly_C[i], &poly_D[i]);
|
||||
|
||||
// eval 2: bound_func is -A(low) + 2*A(high)
|
||||
let poly_A_bound_point = &poly_A[len + i] + &poly_A[len + i] - &poly_A[i];
|
||||
let poly_B_bound_point = &poly_B[len + i] + &poly_B[len + i] - &poly_B[i];
|
||||
let poly_C_bound_point = &poly_C[len + i] + &poly_C[len + i] - &poly_C[i];
|
||||
let poly_D_bound_point = &poly_D[len + i] + &poly_D[len + i] - &poly_D[i];
|
||||
eval_point_2 = &eval_point_2
|
||||
+ comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
&poly_D_bound_point,
|
||||
);
|
||||
|
||||
// eval 3: bound_func is -2A(low) + 3A(high); computed incrementally with bound_func applied to eval(2)
|
||||
let poly_A_bound_point = &poly_A_bound_point + &poly_A[len + i] - &poly_A[i];
|
||||
let poly_B_bound_point = &poly_B_bound_point + &poly_B[len + i] - &poly_B[i];
|
||||
let poly_C_bound_point = &poly_C_bound_point + &poly_C[len + i] - &poly_C[i];
|
||||
let poly_D_bound_point = &poly_D_bound_point + &poly_D[len + i] - &poly_D[i];
|
||||
eval_point_3 = &eval_point_3
|
||||
+ comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
&poly_D_bound_point,
|
||||
);
|
||||
}
|
||||
|
||||
let evals = vec![eval_point_0, e - eval_point_0, eval_point_2, eval_point_3];
|
||||
let poly = UniPoly::from_evals(&evals);
|
||||
|
||||
// append the prover's message to the transcript
|
||||
poly.append_to_transcript(b"poly", transcript);
|
||||
|
||||
//derive the verifier's challenge for the next round
|
||||
let r_j = transcript.challenge_scalar(b"challenge_nextround");
|
||||
r.push(r_j);
|
||||
// bound all tables to the verifier's challenege
|
||||
poly_A.bound_poly_var_top(&r_j);
|
||||
poly_B.bound_poly_var_top(&r_j);
|
||||
poly_C.bound_poly_var_top(&r_j);
|
||||
poly_D.bound_poly_var_top(&r_j);
|
||||
e = poly.evaluate(&r_j);
|
||||
cubic_polys.push(poly.compress());
|
||||
}
|
||||
|
||||
(
|
||||
SumcheckInstanceProof::new(cubic_polys),
|
||||
r,
|
||||
vec![poly_A[0], poly_B[0], poly_C[0], poly_D[0]],
|
||||
)
|
||||
}
|
||||
|
||||
pub fn prove_cubic_batched<F>(
|
||||
claim: &Scalar,
|
||||
num_rounds: usize,
|
||||
|
|
Загрузка…
Ссылка в новой задаче