Browse Source

Transcript (#46)

* add items to transcript

* add additional items to transcript

* fix benches

* cargo fmt
master
Srinath Setty 2 years ago
committed by GitHub
parent
commit
cecc2f1b62
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 95 additions and 10 deletions
  1. +1
    -1
      Cargo.toml
  2. +2
    -1
      README.md
  3. +11
    -2
      benches/snark.rs
  4. +1
    -0
      examples/cubic.rs
  5. +9
    -1
      profiler/snark.rs
  6. +21
    -1
      src/lib.rs
  7. +6
    -0
      src/nizk/mod.rs
  8. +23
    -1
      src/r1csinstance.rs
  9. +4
    -0
      src/r1csproof.rs
  10. +16
    -2
      src/sparse_mlpoly.rs
  11. +1
    -1
      src/transcript.rs

+ 1
- 1
Cargo.toml

@ -1,6 +1,6 @@
[package]
name = "spartan"
version = "0.5.0"
version = "0.6.0"
authors = ["Srinath Setty <srinath@microsoft.com>"]
edition = "2018"
description = "High-speed zkSNARKs without trusted setup"

+ 2
- 1
README.md

@ -58,7 +58,7 @@ Some of our public APIs' style is inspired by the underlying crates we use.
// produce a proof of satisfiability
let mut prover_transcript = Transcript::new(b"snark_example");
let proof = SNARK::prove(&inst, &decomm, vars, &inputs, &gens, &mut prover_transcript);
let proof = SNARK::prove(&inst, &comm, &decomm, vars, &inputs, &gens, &mut prover_transcript);
// verify the proof of satisfiability
let mut verifier_transcript = Transcript::new(b"snark_example");
@ -132,6 +132,7 @@ Finally, we provide an example that specifies a custom R1CS instance instead of
let mut prover_transcript = Transcript::new(b"snark_example");
let proof = SNARK::prove(
&inst,
&comm,
&decomm,
assignment_vars,
&assignment_inputs,

+ 11
- 2
benches/snark.rs

@ -47,7 +47,7 @@ fn snark_prove_benchmark(c: &mut Criterion) {
let gens = SNARKGens::new(num_cons, num_vars, num_inputs, num_cons);
// produce a commitment to R1CS instance
let (_comm, decomm) = SNARK::encode(&inst, &gens);
let (comm, decomm) = SNARK::encode(&inst, &gens);
// produce a proof
let name = format!("SNARK_prove_{}", num_cons);
@ -56,6 +56,7 @@ fn snark_prove_benchmark(c: &mut Criterion) {
let mut prover_transcript = Transcript::new(b"example");
SNARK::prove(
black_box(&inst),
black_box(&comm),
black_box(&decomm),
black_box(vars.clone()),
black_box(&inputs),
@ -87,7 +88,15 @@ fn snark_verify_benchmark(c: &mut Criterion) {
// produce a proof of satisfiability
let mut prover_transcript = Transcript::new(b"example");
let proof = SNARK::prove(&inst, &decomm, vars, &inputs, &gens, &mut prover_transcript);
let proof = SNARK::prove(
&inst,
&comm,
&decomm,
vars,
&inputs,
&gens,
&mut prover_transcript,
);
// verify the proof
let name = format!("SNARK_verify_{}", num_cons);

+ 1
- 0
examples/cubic.rs

@ -128,6 +128,7 @@ fn main() {
let mut prover_transcript = Transcript::new(b"snark_example");
let proof = SNARK::prove(
&inst,
&comm,
&decomm,
assignment_vars,
&assignment_inputs,

+ 9
- 1
profiler/snark.rs

@ -33,7 +33,15 @@ pub fn main() {
// produce a proof of satisfiability
let mut prover_transcript = Transcript::new(b"snark_example");
let proof = SNARK::prove(&inst, &decomm, vars, &inputs, &gens, &mut prover_transcript);
let proof = SNARK::prove(
&inst,
&comm,
&decomm,
vars,
&inputs,
&gens,
&mut prover_transcript,
);
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
bincode::serialize_into(&mut encoder, &proof).unwrap();

+ 21
- 1
src/lib.rs

@ -336,6 +336,7 @@ impl SNARK {
/// A method to produce a SNARK proof of the satisfiability of an R1CS instance
pub fn prove(
inst: &Instance,
comm: &ComputationCommitment,
decomm: &ComputationDecommitment,
vars: VarsAssignment,
inputs: &InputsAssignment,
@ -347,7 +348,10 @@ impl SNARK {
// we create a Transcript object seeded with a random Scalar
// to aid the prover produce its randomness
let mut random_tape = RandomTape::new(b"proof");
transcript.append_protocol_name(SNARK::protocol_name());
comm.comm.append_to_transcript(b"comm", transcript);
let (r1cs_sat_proof, rx, ry) = {
let (proof, rx, ry) = {
// we might need to pad variables
@ -424,6 +428,9 @@ impl SNARK {
let timer_verify = Timer::new("SNARK::verify");
transcript.append_protocol_name(SNARK::protocol_name());
// append a commitment to the computation to the transcript
comm.comm.append_to_transcript(b"comm", transcript);
let timer_sat_proof = Timer::new("verify_sat_proof");
assert_eq!(input.assignment.len(), comm.comm.get_num_inputs());
let (rx, ry) = self.r1cs_sat_proof.verify(
@ -500,7 +507,10 @@ impl NIZK {
// we create a Transcript object seeded with a random Scalar
// to aid the prover produce its randomness
let mut random_tape = RandomTape::new(b"proof");
transcript.append_protocol_name(NIZK::protocol_name());
inst.inst.append_to_transcript(b"inst", transcript);
let (r1cs_sat_proof, rx, ry) = {
// we might need to pad variables
let padded_vars = {
@ -544,6 +554,7 @@ impl NIZK {
let timer_verify = Timer::new("NIZK::verify");
transcript.append_protocol_name(NIZK::protocol_name());
inst.inst.append_to_transcript(b"inst", transcript);
// We send evaluations of A, B, C at r = (rx, ry) as claims
// to enable the verifier complete the first sum-check
@ -594,7 +605,15 @@ mod tests {
// produce a proof
let mut prover_transcript = Transcript::new(b"example");
let proof = SNARK::prove(&inst, &decomm, vars, &inputs, &gens, &mut prover_transcript);
let proof = SNARK::prove(
&inst,
&comm,
&decomm,
vars,
&inputs,
&gens,
&mut prover_transcript,
);
// verify the proof
let mut verifier_transcript = Transcript::new(b"example");
@ -696,6 +715,7 @@ mod tests {
let mut prover_transcript = Transcript::new(b"snark_example");
let proof = SNARK::prove(
&inst,
&comm,
&decomm,
assignment_vars.clone(),
&assignment_inputs,

+ 6
- 0
src/nizk/mod.rs

@ -336,6 +336,8 @@ impl DotProductProof {
let Cy = y.commit(blind_y, gens_1).compress();
Cy.append_to_transcript(b"Cy", transcript);
a_vec.append_to_transcript(b"a", transcript);
let delta = d_vec.commit(&r_delta, gens_n).compress();
delta.append_to_transcript(b"delta", transcript);
@ -381,6 +383,7 @@ impl DotProductProof {
transcript.append_protocol_name(DotProductProof::protocol_name());
Cx.append_to_transcript(b"Cx", transcript);
Cy.append_to_transcript(b"Cy", transcript);
a.append_to_transcript(b"a", transcript);
self.delta.append_to_transcript(b"delta", transcript);
self.beta.append_to_transcript(b"beta", transcript);
@ -466,6 +469,8 @@ impl DotProductProofLog {
let Cy = y.commit(blind_y, &gens.gens_1).compress();
Cy.append_to_transcript(b"Cy", transcript);
a_vec.append_to_transcript(b"a", transcript);
let blind_Gamma = blind_x + blind_y;
let (bullet_reduction_proof, _Gamma_hat, x_hat, a_hat, g_hat, rhat_Gamma) =
BulletReductionProof::prove(
@ -526,6 +531,7 @@ impl DotProductProofLog {
transcript.append_protocol_name(DotProductProofLog::protocol_name());
Cx.append_to_transcript(b"Cx", transcript);
Cy.append_to_transcript(b"Cy", transcript);
a.append_to_transcript(b"a", transcript);
let Gamma = Cx.unpack()? + Cy.unpack()?;

+ 23
- 1
src/r1csinstance.rs

@ -1,3 +1,5 @@
use crate::transcript::AppendToTranscript;
use super::dense_mlpoly::DensePolynomial;
use super::errors::ProofVerifyError;
use super::math::Math;
@ -8,11 +10,12 @@ use super::sparse_mlpoly::{
SparseMatPolyCommitmentGens, SparseMatPolyEvalProof, SparseMatPolynomial,
};
use super::timer::Timer;
use flate2::{write::ZlibEncoder, Compression};
use merlin::Transcript;
use rand::rngs::OsRng;
use serde::{Deserialize, Serialize};
#[derive(Debug)]
#[derive(Debug, Serialize, Deserialize)]
pub struct R1CSInstance {
num_cons: usize,
num_vars: usize,
@ -22,6 +25,15 @@ pub struct R1CSInstance {
C: SparseMatPolynomial,
}
impl AppendToTranscript for R1CSInstance {
fn append_to_transcript(&self, _label: &'static [u8], transcript: &mut Transcript) {
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
bincode::serialize_into(&mut encoder, &self).unwrap();
let bytes = encoder.finish().unwrap();
transcript.append_message(b"R1CSInstance", &bytes);
}
}
pub struct R1CSCommitmentGens {
gens: SparseMatPolyCommitmentGens,
}
@ -43,6 +55,7 @@ impl R1CSCommitmentGens {
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct R1CSCommitment {
num_cons: usize,
num_vars: usize,
@ -50,6 +63,15 @@ pub struct R1CSCommitment {
comm: SparseMatPolyCommitment,
}
impl AppendToTranscript for R1CSCommitment {
fn append_to_transcript(&self, _label: &'static [u8], transcript: &mut Transcript) {
transcript.append_u64(b"num_cons", self.num_cons as u64);
transcript.append_u64(b"num_vars", self.num_vars as u64);
transcript.append_u64(b"num_inputs", self.num_inputs as u64);
self.comm.append_to_transcript(b"comm", transcript);
}
}
pub struct R1CSDecommitment {
dense: MultiSparseMatPolynomialAsDense,
}

+ 4
- 0
src/r1csproof.rs

@ -152,6 +152,8 @@ impl R1CSProof {
// we currently require the number of |inputs| + 1 to be at most number of vars
assert!(input.len() < vars.len());
input.append_to_transcript(b"input", transcript);
let timer_commit = Timer::new("polycommit");
let (poly_vars, comm_vars, blinds_vars) = {
// create a multilinear polynomial using the supplied assignment for variables
@ -355,6 +357,8 @@ impl R1CSProof {
) -> Result<(Vec<Scalar>, Vec<Scalar>), ProofVerifyError> {
transcript.append_protocol_name(R1CSProof::protocol_name());
input.append_to_transcript(b"input", transcript);
let n = num_vars;
// add the commitment to the verifier's transcript
self

+ 16
- 2
src/sparse_mlpoly.rs

@ -16,7 +16,7 @@ use core::cmp::Ordering;
use merlin::Transcript;
use serde::{Deserialize, Serialize};
#[derive(Debug)]
#[derive(Debug, Serialize, Deserialize)]
pub struct SparseMatEntry {
row: usize,
col: usize,
@ -29,7 +29,7 @@ impl SparseMatEntry {
}
}
#[derive(Debug)]
#[derive(Debug, Serialize, Deserialize)]
pub struct SparseMatPolynomial {
num_vars_x: usize,
num_vars_y: usize,
@ -330,6 +330,20 @@ pub struct SparseMatPolyCommitment {
comm_comb_mem: PolyCommitment,
}
impl AppendToTranscript for SparseMatPolyCommitment {
fn append_to_transcript(&self, _label: &'static [u8], transcript: &mut Transcript) {
transcript.append_u64(b"batch_size", self.batch_size as u64);
transcript.append_u64(b"num_ops", self.num_ops as u64);
transcript.append_u64(b"num_mem_cells", self.num_mem_cells as u64);
self
.comm_comb_ops
.append_to_transcript(b"comm_comb_ops", transcript);
self
.comm_comb_mem
.append_to_transcript(b"comm_comb_mem", transcript);
}
}
impl SparseMatPolynomial {
pub fn new(num_vars_x: usize, num_vars_y: usize, M: Vec<SparseMatEntry>) -> Self {
SparseMatPolynomial {

+ 1
- 1
src/transcript.rs

@ -46,7 +46,7 @@ impl AppendToTranscript for Scalar {
}
}
impl AppendToTranscript for Vec<Scalar> {
impl AppendToTranscript for [Scalar] {
fn append_to_transcript(&self, label: &'static [u8], transcript: &mut Transcript) {
transcript.append_message(label, b"begin_append_vector");
for item in self {

Loading…
Cancel
Save