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" path = "src/lib.rs"
[[bin]] [[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]] [[bench]]
name = "spartan"
name = "snark"
harness = false harness = false
[[bench]] [[bench]]
name = "sumcheck"
name = "nizk"
harness = false harness = false
[features] [features]

+ 3
- 3
NOTICE.md

@ -1,6 +1,6 @@
This repository includes the following third-party open-source code. 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. 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 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. 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. 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. 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 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 rand;
extern crate sha3; extern crate sha3;
use libspartan::dense_mlpoly::EqPolynomial;
use libspartan::math::Math;
use libspartan::r1csinstance::R1CSInstance; 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 merlin::Transcript;
use rand::rngs::OsRng;
use criterion::*; use criterion::*;
fn prove_benchmark(c: &mut Criterion) {
fn nizk_prove_benchmark(c: &mut Criterion) {
for &s in [10, 12, 16].iter() { for &s in [10, 12, 16].iter() {
let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic); 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); 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_cons = num_vars;
let num_inputs = 10; let num_inputs = 10;
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs); let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
let n = inst.get_num_vars(); 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| { group.bench_function(&name, move |b| {
b.iter(|| { b.iter(|| {
let mut random_tape = RandomTape::new(b"proof");
let mut prover_transcript = Transcript::new(b"example"); let mut prover_transcript = Transcript::new(b"example");
R1CSProof::prove(
NIZK::prove(
black_box(&inst), black_box(&inst),
black_box(vars.clone()), black_box(vars.clone()),
black_box(&input), black_box(&input),
black_box(&gens), black_box(&gens),
black_box(&mut prover_transcript), black_box(&mut prover_transcript),
black_box(&mut random_tape),
)
);
}); });
}); });
group.finish(); 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 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); 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_cons = num_vars;
let num_inputs = 10; let num_inputs = 10;
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs); let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
let n = inst.get_num_vars(); 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| { group.bench_function(&name, move |b| {
b.iter(|| { b.iter(|| {
let mut verifier_transcript = Transcript::new(b"example"); let mut verifier_transcript = Transcript::new(b"example");
assert!(proof assert!(proof
.verify( .verify(
black_box(num_vars),
black_box(num_cons),
black_box(&inst),
black_box(&input), black_box(&input),
black_box(&inst_evals),
black_box(&mut verifier_transcript), black_box(&mut verifier_transcript),
black_box(&gens) black_box(&gens)
) )
@ -102,13 +83,12 @@ fn verify_benchmark(c: &mut Criterion) {
fn set_duration() -> Criterion { fn set_duration() -> Criterion {
Criterion::default().sample_size(10) Criterion::default().sample_size(10)
// .measurement_time(Duration::new(0, 50000000))
} }
criterion_group! { criterion_group! {
name = benches_r1cs;
name = benches_nizk;
config = set_duration(); 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 { pub struct IdentityPolynomial {
size_point: usize, size_point: usize,
} }
@ -456,48 +421,6 @@ impl PolyEvalProof {
.verify(R.len(), &gens.gens, transcript, &R, &C_LZ, C_Zr) .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( pub fn verify_plain(
&self, &self,
gens: &PolyCommitmentGens, gens: &PolyCommitmentGens,
@ -511,23 +434,6 @@ impl PolyEvalProof {
self.verify(gens, transcript, r, &C_Zr, comm) 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)] #[cfg(test)]

+ 10
- 10
src/lib.rs

@ -11,20 +11,20 @@ extern crate rayon;
extern crate sha3; extern crate sha3;
extern crate test; extern crate test;
pub mod commitments;
pub mod dense_mlpoly;
mod commitments;
mod dense_mlpoly;
mod errors; mod errors;
mod group; mod group;
pub mod math;
pub mod nizk;
mod math;
mod nizk;
mod product_tree; mod product_tree;
pub mod r1csinstance; 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 spartan;
pub mod sumcheck;
mod sumcheck;
pub mod timer; pub mod timer;
pub mod transcript;
mod transcript;
mod unipoly; 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 { pub struct R1CSInstanceSize {
num_cons: usize,
num_vars: usize,
num_inputs: usize,
size_A: SparseMatPolynomialSize, size_A: SparseMatPolynomialSize,
size_B: SparseMatPolynomialSize, size_B: SparseMatPolynomialSize,
size_C: 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 { pub struct R1CSCommitmentGens {
gens: SparseMatPolyCommitmentGens, gens: SparseMatPolyCommitmentGens,
} }
@ -124,6 +141,9 @@ impl R1CSInstance {
pub fn size(&self) -> R1CSInstanceSize { pub fn size(&self) -> R1CSInstanceSize {
R1CSInstanceSize { R1CSInstanceSize {
num_cons: self.num_cons,
num_vars: self.num_vars,
num_inputs: self.num_inputs,
size_A: self.A.size(), size_A: self.A.size(),
size_B: self.B.size(), size_B: self.B.size(),
size_C: self.C.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::errors::ProofVerifyError;
use super::r1csinstance::{ use super::r1csinstance::{
R1CSCommitment, R1CSCommitmentGens, R1CSDecommitment, R1CSEvalProof, R1CSInstance, R1CSCommitment, R1CSCommitmentGens, R1CSDecommitment, R1CSEvalProof, R1CSInstance,
R1CSInstanceEvals,
R1CSInstanceEvals, R1CSInstanceSize,
}; };
use super::r1csproof::{R1CSGens, R1CSProof}; use super::r1csproof::{R1CSGens, R1CSProof};
use super::random::RandomTape; use super::random::RandomTape;
@ -18,7 +18,9 @@ pub struct SNARKGens {
} }
impl 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 { SNARKGens {
gens_r1cs_sat, gens_r1cs_sat,
gens_r1cs_eval, gens_r1cs_eval,
@ -39,11 +41,8 @@ impl SNARK {
} }
/// A public computation to create a commitment to an R1CS instance /// 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 /// A method to produce a proof of the satisfiability of an R1CS instance
@ -158,7 +157,8 @@ pub struct NIZKGens {
} }
impl 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 } NIZKGens { gens_r1cs_sat }
} }
} }
@ -261,19 +261,19 @@ mod tests {
let num_cons = num_vars; let num_cons = num_vars;
let num_inputs = 10; let num_inputs = 10;
let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs); let (inst, vars, input) = R1CSInstance::produce_synthetic_r1cs(num_cons, num_vars, num_inputs);
let r1cs_size = inst.size(); 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 mut prover_transcript = Transcript::new(b"example");
let proof = SNARK::prove(&inst, &decomm, vars, &input, &gens, &mut prover_transcript); let proof = SNARK::prove(&inst, &decomm, vars, &input, &gens, &mut prover_transcript);
// verify the proof
let mut verifier_transcript = Transcript::new(b"example"); let mut verifier_transcript = Transcript::new(b"example");
assert!(proof assert!(proof
.verify(&comm, &input, &mut verifier_transcript, &gens) .verify(&comm, &input, &mut verifier_transcript, &gens)

+ 0
- 131
src/sumcheck.rs

@ -176,59 +176,6 @@ impl ZKSumcheckInstanceProof {
} }
impl SumcheckInstanceProof { 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>( pub fn prove_cubic<F>(
claim: &Scalar, claim: &Scalar,
num_rounds: usize, 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>( pub fn prove_cubic_batched<F>(
claim: &Scalar, claim: &Scalar,
num_rounds: usize, num_rounds: usize,

Loading…
Cancel
Save