Browse Source

remove asserts; return result objects (#45)

* remove asserts; return result objects

* bump version

* clippy
master
Srinath Setty 2 years ago
committed by GitHub
parent
commit
6722e6c6ad
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 84 additions and 122 deletions
  1. +1
    -1
      Cargo.toml
  2. +2
    -2
      README.md
  3. +1
    -1
      profiler/nizk.rs
  4. +1
    -1
      profiler/snark.rs
  5. +8
    -11
      src/lib.rs
  6. +1
    -1
      src/nizk/bullet.rs
  7. +8
    -13
      src/r1csinstance.rs
  8. +27
    -40
      src/r1csproof.rs
  9. +32
    -51
      src/sparse_mlpoly.rs
  10. +3
    -1
      src/sumcheck.rs

+ 1
- 1
Cargo.toml

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

+ 2
- 2
README.md

@ -1,7 +1,7 @@
# Spartan: High-speed zkSNARKs without trusted setup # Spartan: High-speed zkSNARKs without trusted setup
![Rust](https://github.com/microsoft/Spartan/workflows/Rust/badge.svg) ![Rust](https://github.com/microsoft/Spartan/workflows/Rust/badge.svg)
[![](https://img.shields.io/crates/v/spartan.svg)]((https://crates.io/crates/curve25519-dalek))
[![](https://img.shields.io/crates/v/spartan.svg)]((https://crates.io/crates/spartan))
Spartan is a high-speed zero-knowledge proof system, a cryptographic primitive that enables a prover to prove a mathematical statement to a verifier without revealing anything besides the validity of the statement. This repository provides `libspartan,` a Rust library that implements a zero-knowledge succinct non-interactive argument of knowledge (zkSNARK), which is a type of zero-knowledge proof system with short proofs and fast verification times. The details of the Spartan proof system are described in our [paper](https://eprint.iacr.org/2019/550) published at [CRYPTO 2020](https://crypto.iacr.org/2020/). The security of the Spartan variant implemented in this library is based on the discrete logarithm problem in the random oracle model. Spartan is a high-speed zero-knowledge proof system, a cryptographic primitive that enables a prover to prove a mathematical statement to a verifier without revealing anything besides the validity of the statement. This repository provides `libspartan,` a Rust library that implements a zero-knowledge succinct non-interactive argument of knowledge (zkSNARK), which is a type of zero-knowledge proof system with short proofs and fast verification times. The details of the Spartan proof system are described in our [paper](https://eprint.iacr.org/2019/550) published at [CRYPTO 2020](https://crypto.iacr.org/2020/). The security of the Spartan variant implemented in this library is based on the discrete logarithm problem in the random oracle model.
@ -16,7 +16,7 @@ We now highlight Spartan's distinctive features.
* **General-purpose:** Spartan produces proofs for arbitrary NP statements. `libspartan` supports NP statements expressed as rank-1 constraint satisfiability (R1CS) instances, a popular language for which there exists efficient transformations and compiler toolchains from high-level programs of interest. * **General-purpose:** Spartan produces proofs for arbitrary NP statements. `libspartan` supports NP statements expressed as rank-1 constraint satisfiability (R1CS) instances, a popular language for which there exists efficient transformations and compiler toolchains from high-level programs of interest.
* **Sub-linear verification costs and linear-time proving costs:** Spartan is the first transparent proof system with sub-linear verification costs for arbitrary NP statements (e.g., R1CS). Spartan also features a linear-time prover, a property that has remained elusive for nearly all zkSNARKs in the literature.
* **Sub-linear verification costs:** Spartan is the first transparent proof system with sub-linear verification costs for arbitrary NP statements (e.g., R1CS).
* **Standardized security:** Spartan's security relies on the hardness of computing discrete logarithms (a standard cryptographic assumption) in the random oracle model. `libspartan` uses `ristretto255`, a prime-order group abstraction atop `curve25519` (a high-speed elliptic curve). We use [`curve25519-dalek`](https://docs.rs/curve25519-dalek) for arithmetic over `ristretto255`. * **Standardized security:** Spartan's security relies on the hardness of computing discrete logarithms (a standard cryptographic assumption) in the random oracle model. `libspartan` uses `ristretto255`, a prime-order group abstraction atop `curve25519` (a high-speed elliptic curve). We use [`curve25519-dalek`](https://docs.rs/curve25519-dalek) for arithmetic over `ristretto255`.

+ 1
- 1
profiler/nizk.rs

@ -10,7 +10,7 @@ use merlin::Transcript;
fn print(msg: &str) { fn print(msg: &str) {
let star = "* "; let star = "* ";
println!("{:indent$}{}{}", "", star, msg.to_string(), indent = 2);
println!("{:indent$}{}{}", "", star, msg, indent = 2);
} }
pub fn main() { pub fn main() {

+ 1
- 1
profiler/snark.rs

@ -9,7 +9,7 @@ use merlin::Transcript;
fn print(msg: &str) { fn print(msg: &str) {
let star = "* "; let star = "* ";
println!("{:indent$}{}{}", "", star, msg.to_string(), indent = 2);
println!("{:indent$}{}{}", "", star, msg, indent = 2);
} }
pub fn main() { pub fn main() {

+ 8
- 11
src/lib.rs

@ -441,17 +441,14 @@ impl SNARK {
Ar.append_to_transcript(b"Ar_claim", transcript); Ar.append_to_transcript(b"Ar_claim", transcript);
Br.append_to_transcript(b"Br_claim", transcript); Br.append_to_transcript(b"Br_claim", transcript);
Cr.append_to_transcript(b"Cr_claim", transcript); Cr.append_to_transcript(b"Cr_claim", transcript);
assert!(self
.r1cs_eval_proof
.verify(
&comm.comm,
&rx,
&ry,
&self.inst_evals,
&gens.gens_r1cs_eval,
transcript
)
.is_ok());
self.r1cs_eval_proof.verify(
&comm.comm,
&rx,
&ry,
&self.inst_evals,
&gens.gens_r1cs_eval,
transcript,
)?;
timer_eval_proof.stop(); timer_eval_proof.stop();
timer_verify.stop(); timer_verify.stop();
Ok(()) Ok(())

+ 1
- 1
src/nizk/bullet.rs

@ -231,7 +231,7 @@ impl BulletReductionProof {
/// Panics if the lengths of \\(\mathbf{a}\\) and \\(\mathbf{b}\\) are not equal. /// Panics if the lengths of \\(\mathbf{a}\\) and \\(\mathbf{b}\\) are not equal.
pub fn inner_product(a: &[Scalar], b: &[Scalar]) -> Scalar { pub fn inner_product(a: &[Scalar], b: &[Scalar]) -> Scalar {
assert!( assert!(
!(a.len() != b.len()),
a.len() == b.len(),
"inner_product(a,b): lengths of vectors do not match" "inner_product(a,b): lengths of vectors do not match"
); );
let mut out = Scalar::zero(); let mut out = Scalar::zero();

+ 8
- 13
src/r1csinstance.rs

@ -336,18 +336,13 @@ impl R1CSEvalProof {
gens: &R1CSCommitmentGens, gens: &R1CSCommitmentGens,
transcript: &mut Transcript, transcript: &mut Transcript,
) -> Result<(), ProofVerifyError> { ) -> Result<(), ProofVerifyError> {
assert!(self
.proof
.verify(
&comm.comm,
rx,
ry,
&[evals.0, evals.1, evals.2],
&gens.gens,
transcript
)
.is_ok());
Ok(())
self.proof.verify(
&comm.comm,
rx,
ry,
&[evals.0, evals.1, evals.2],
&gens.gens,
transcript,
)
} }
} }

+ 27
- 40
src/r1csproof.rs

@ -382,18 +382,14 @@ impl R1CSProof {
let (comm_Az_claim, comm_Bz_claim, comm_Cz_claim, comm_prod_Az_Bz_claims) = &self.claims_phase2; let (comm_Az_claim, comm_Bz_claim, comm_Cz_claim, comm_prod_Az_Bz_claims) = &self.claims_phase2;
let (pok_Cz_claim, proof_prod) = &self.pok_claims_phase2; let (pok_Cz_claim, proof_prod) = &self.pok_claims_phase2;
assert!(pok_Cz_claim
.verify(&gens.gens_sc.gens_1, transcript, comm_Cz_claim)
.is_ok());
assert!(proof_prod
.verify(
&gens.gens_sc.gens_1,
transcript,
comm_Az_claim,
comm_Bz_claim,
comm_prod_Az_Bz_claims
)
.is_ok());
pok_Cz_claim.verify(&gens.gens_sc.gens_1, transcript, comm_Cz_claim)?;
proof_prod.verify(
&gens.gens_sc.gens_1,
transcript,
comm_Az_claim,
comm_Bz_claim,
comm_prod_Az_Bz_claims,
)?;
comm_Az_claim.append_to_transcript(b"comm_Az_claim", transcript); comm_Az_claim.append_to_transcript(b"comm_Az_claim", transcript);
comm_Bz_claim.append_to_transcript(b"comm_Bz_claim", transcript); comm_Bz_claim.append_to_transcript(b"comm_Bz_claim", transcript);
@ -408,15 +404,12 @@ impl R1CSProof {
.compress(); .compress();
// verify proof that expected_claim_post_phase1 == claim_post_phase1 // verify proof that expected_claim_post_phase1 == claim_post_phase1
assert!(self
.proof_eq_sc_phase1
.verify(
&gens.gens_sc.gens_1,
transcript,
&expected_claim_post_phase1,
&comm_claim_post_phase1,
)
.is_ok());
self.proof_eq_sc_phase1.verify(
&gens.gens_sc.gens_1,
transcript,
&expected_claim_post_phase1,
&comm_claim_post_phase1,
)?;
// derive three public challenges and then derive a joint claim // derive three public challenges and then derive a joint claim
let r_A = transcript.challenge_scalar(b"challenege_Az"); let r_A = transcript.challenge_scalar(b"challenege_Az");
@ -447,16 +440,13 @@ impl R1CSProof {
)?; )?;
// verify Z(ry) proof against the initial commitment // verify Z(ry) proof against the initial commitment
assert!(self
.proof_eval_vars_at_ry
.verify(
&gens.gens_pc,
transcript,
&ry[1..].to_vec(),
&self.comm_vars_at_ry,
&self.comm_vars
)
.is_ok());
self.proof_eval_vars_at_ry.verify(
&gens.gens_pc,
transcript,
&ry[1..].to_vec(),
&self.comm_vars_at_ry,
&self.comm_vars,
)?;
let poly_input_eval = { let poly_input_eval = {
// constant term // constant term
@ -484,15 +474,12 @@ impl R1CSProof {
let expected_claim_post_phase2 = let expected_claim_post_phase2 =
((r_A * eval_A_r + r_B * eval_B_r + r_C * eval_C_r) * comm_eval_Z_at_ry).compress(); ((r_A * eval_A_r + r_B * eval_B_r + r_C * eval_C_r) * comm_eval_Z_at_ry).compress();
// verify proof that expected_claim_post_phase1 == claim_post_phase1 // verify proof that expected_claim_post_phase1 == claim_post_phase1
assert!(self
.proof_eq_sc_phase2
.verify(
&gens.gens_sc.gens_1,
transcript,
&expected_claim_post_phase2,
&comm_claim_post_phase2,
)
.is_ok());
self.proof_eq_sc_phase2.verify(
&gens.gens_sc.gens_1,
transcript,
&expected_claim_post_phase2,
&comm_claim_post_phase2,
)?;
Ok((rx, ry)) Ok((rx, ry))
} }

+ 32
- 51
src/sparse_mlpoly.rs

@ -178,11 +178,8 @@ impl DerefsEvalProof {
// decommit the joint polynomial at r_joint // decommit the joint polynomial at r_joint
joint_claim_eval.append_to_transcript(b"joint_claim_eval", transcript); joint_claim_eval.append_to_transcript(b"joint_claim_eval", transcript);
assert!(proof
.verify_plain(gens, transcript, &r_joint, &joint_claim_eval, comm)
.is_ok());
Ok(())
proof.verify_plain(gens, transcript, &r_joint, &joint_claim_eval, comm)
} }
// verify evaluations of both polynomials at r // verify evaluations of both polynomials at r
@ -200,7 +197,7 @@ impl DerefsEvalProof {
evals.extend(eval_col_ops_val_vec); evals.extend(eval_col_ops_val_vec);
evals.resize(evals.len().next_power_of_two(), Scalar::zero()); evals.resize(evals.len().next_power_of_two(), Scalar::zero());
assert!(DerefsEvalProof::verify_single(
DerefsEvalProof::verify_single(
&self.proof_derefs, &self.proof_derefs,
&comm.comm_ops_val, &comm.comm_ops_val,
r, r,
@ -208,9 +205,6 @@ impl DerefsEvalProof {
gens, gens,
transcript, transcript,
) )
.is_ok());
Ok(())
} }
} }
@ -910,17 +904,14 @@ impl HashLayerProof {
// verify derefs at rand_ops // verify derefs at rand_ops
let (eval_row_ops_val, eval_col_ops_val) = &self.eval_derefs; let (eval_row_ops_val, eval_col_ops_val) = &self.eval_derefs;
assert_eq!(eval_row_ops_val.len(), eval_col_ops_val.len()); assert_eq!(eval_row_ops_val.len(), eval_col_ops_val.len());
assert!(self
.proof_derefs
.verify(
rand_ops,
eval_row_ops_val,
eval_col_ops_val,
&gens.gens_derefs,
comm_derefs,
transcript
)
.is_ok());
self.proof_derefs.verify(
rand_ops,
eval_row_ops_val,
eval_col_ops_val,
&gens.gens_derefs,
comm_derefs,
transcript,
)?;
// verify the decommitments used in evaluation sum-check // verify the decommitments used in evaluation sum-check
let eval_val_vec = &self.eval_val; let eval_val_vec = &self.eval_val;
@ -990,20 +981,17 @@ impl HashLayerProof {
let mut r_joint_mem = challenges_mem; let mut r_joint_mem = challenges_mem;
r_joint_mem.extend(rand_mem); r_joint_mem.extend(rand_mem);
joint_claim_eval_mem.append_to_transcript(b"joint_claim_eval_mem", transcript); joint_claim_eval_mem.append_to_transcript(b"joint_claim_eval_mem", transcript);
assert!(self
.proof_mem
.verify_plain(
&gens.gens_mem,
transcript,
&r_joint_mem,
&joint_claim_eval_mem,
&comm.comm_comb_mem
)
.is_ok());
self.proof_mem.verify_plain(
&gens.gens_mem,
transcript,
&r_joint_mem,
&joint_claim_eval_mem,
&comm.comm_comb_mem,
)?;
// verify the claims from the product layer // verify the claims from the product layer
let (eval_ops_addr, eval_read_ts, eval_audit_ts) = &self.eval_row; let (eval_ops_addr, eval_read_ts, eval_audit_ts) = &self.eval_row;
assert!(HashLayerProof::verify_helper(
HashLayerProof::verify_helper(
&(rand_mem, rand_ops), &(rand_mem, rand_ops),
claims_row, claims_row,
eval_row_ops_val, eval_row_ops_val,
@ -1013,11 +1001,10 @@ impl HashLayerProof {
rx, rx,
r_hash, r_hash,
r_multiset_check, r_multiset_check,
)
.is_ok());
)?;
let (eval_ops_addr, eval_read_ts, eval_audit_ts) = &self.eval_col; let (eval_ops_addr, eval_read_ts, eval_audit_ts) = &self.eval_col;
assert!(HashLayerProof::verify_helper(
HashLayerProof::verify_helper(
&(rand_mem, rand_ops), &(rand_mem, rand_ops),
claims_col, claims_col,
eval_col_ops_val, eval_col_ops_val,
@ -1027,8 +1014,7 @@ impl HashLayerProof {
ry, ry,
r_hash, r_hash,
r_multiset_check, r_multiset_check,
)
.is_ok());
)?;
timer.stop(); timer.stop();
Ok(()) Ok(())
@ -1562,22 +1548,17 @@ impl SparseMatPolyEvalProof {
// produce a random element from the transcript for hash function // produce a random element from the transcript for hash function
let r_mem_check = transcript.challenge_vector(b"challenge_r_hash", 2); let r_mem_check = transcript.challenge_vector(b"challenge_r_hash", 2);
assert!(self
.poly_eval_network_proof
.verify(
comm,
&self.comm_derefs,
evals,
gens,
&rx_ext,
&ry_ext,
&(r_mem_check[0], r_mem_check[1]),
nz,
transcript,
)
.is_ok());
Ok(())
self.poly_eval_network_proof.verify(
comm,
&self.comm_derefs,
evals,
gens,
&rx_ext,
&ry_ext,
&(r_mem_check[0], r_mem_check[1]),
nz,
transcript,
)
} }
} }

+ 3
- 1
src/sumcheck.rs

@ -168,7 +168,9 @@ impl ZKSumcheckInstanceProof {
) )
.is_ok() .is_ok()
}; };
assert!(res);
if !res {
return Err(ProofVerifyError::InternalError);
}
r.push(r_i); r.push(r_i);
} }

Loading…
Cancel
Save