Browse Source

Pub (#14)

limit public APIs
master
Srinath Setty 4 years ago
parent
commit
eb969d5dcf
17 changed files with 313 additions and 1090 deletions
  1. +7
    -19
      Cargo.toml
  2. +3
    -3
      NOTICE.md
  3. +0
    -47
      benches/commitments.rs
  4. +0
    -85
      benches/dotproduct.rs
  5. +22
    -42
      benches/nizk.rs
  6. +0
    -191
      benches/polycommit.rs
  7. +130
    -0
      benches/snark.rs
  8. +0
    -206
      benches/spartan.rs
  9. +0
    -152
      benches/sumcheck.rs
  10. +51
    -0
      profiler/nizk.rs
  11. +56
    -0
      profiler/snark.rs
  12. +0
    -94
      src/dense_mlpoly.rs
  13. +10
    -10
      src/lib.rs
  14. +0
    -96
      src/profiler.rs
  15. +20
    -0
      src/r1csinstance.rs
  16. +14
    -14
      src/spartan.rs
  17. +0
    -131
      src/sumcheck.rs

+ 7
- 19
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"
[[bench]]
name = "commitments"
harness = false
[[bench]]
name = "dotproduct"
harness = false
[[bench]]
name = "polycommit"
harness = false
[[bench]]
name = "r1csproof"
harness = false
[[bin]]
name = "nizk"
path = "profiler/nizk.rs"
[[bench]]
name = "spartan"
name = "snark"
harness = false
[[bench]]
name = "sumcheck"
name = "nizk"
harness = false
[features]

+ 3
- 3
NOTICE.md

@ -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

+ 0
- 47
benches/commitments.rs

@ -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);

+ 0
- 85
benches/dotproduct.rs

@ -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);

benches/r1csproof.rs → benches/nizk.rs

@ -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 mut prover_transcript = Transcript::new(b"example");
let (proof, rx, ry) = R1CSProof::prove(
&inst,
vars,
&input,
&gens,
&mut prover_transcript,
&mut random_tape,
);
let gens = NIZKGens::new(num_cons, num_vars);
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);
// 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!("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);

+ 0
- 191
benches/polycommit.rs

@ -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);

+ 130
- 0
benches/snark.rs

@ -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);

+ 0
- 206
benches/spartan.rs

@ -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);

+ 0
- 152
benches/sumcheck.rs

@ -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);

+ 51
- 0
profiler/nizk.rs

@ -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!();
}
}

+ 56
- 0
profiler/snark.rs

@ -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!();
}
}

+ 0
- 94
src/dense_mlpoly.rs

@ -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)]

+ 10
- 10
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;

+ 0
- 96
src/profiler.rs

@ -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!();
}
}

+ 20
- 0
src/r1csinstance.rs

@ -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(),

+ 14
- 14
src/spartan.rs

@ -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");
// create a commitment to R1CSInstance
let (comm, decomm) = SNARK::encode(&inst, &gens_r1cs_eval);
// produce public generators
let gens = SNARKGens::new(&r1cs_size);
let gens_r1cs_sat = R1CSGens::new(num_cons, num_vars, b"gens_r1cs_sat");
let gens = SNARKGens::new(gens_r1cs_sat, gens_r1cs_eval);
// create a commitment to R1CSInstance
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)

+ 0
- 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,

Loading…
Cancel
Save