remove asserts; return result objects (#45) * remove asserts; return result objects * bump version * clippy
@@ -1,6 +1,6 @@
[package] name = "spartan" -version = "0.4.1" +version = "0.5.0" authors = ["Srinath Setty <srinath@microsoft.com>"] edition = "2018" description = "High-speed zkSNARKs without trusted setup"
@@ -1,7 +1,7 @@
# Spartan: High-speed zkSNARKs without trusted setup  -[]((https://crates.io/crates/curve25519-dalek)) +[]((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.@@ -16,7 +16,7 @@ * **No "toxic" waste:** Spartan is a *transparent* zkSNARK and does not require a trusted setup. So, it does not involve any trapdoors that must be kept secret or require a multi-party ceremony to produce public parameters.
* **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`.
@@ -10,7 +10,7 @@ use merlin::Transcript;
fn print(msg: &str) { let star = "* "; - println!("{:indent$}{}{}", "", star, msg.to_string(), indent = 2); + println!("{:indent$}{}{}", "", star, msg, indent = 2); } pub fn main() {
@@ -9,7 +9,7 @@ use merlin::Transcript;
fn print(msg: &str) { let star = "* "; - println!("{:indent$}{}{}", "", star, msg.to_string(), indent = 2); + println!("{:indent$}{}{}", "", star, msg, indent = 2); } pub fn main() {
@@ -441,17 +441,14 @@ let (Ar, Br, Cr) = &self.inst_evals;
Ar.append_to_transcript(b"Ar_claim", transcript); Br.append_to_transcript(b"Br_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_verify.stop(); Ok(())
@@ -231,7 +231,7 @@ /// \\]
/// Panics if the lengths of \\(\mathbf{a}\\) and \\(\mathbf{b}\\) are not equal. pub fn inner_product(a: &[Scalar], b: &[Scalar]) -> Scalar { assert!( - !(a.len() != b.len()), + a.len() == b.len(), "inner_product(a,b): lengths of vectors do not match" ); let mut out = Scalar::zero();
@@ -336,18 +336,13 @@ evals: &(Scalar, Scalar, Scalar),
gens: &R1CSCommitmentGens, transcript: &mut Transcript, ) -> 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, + ) } }
@@ -382,18 +382,14 @@ // perform the intermediate sum-check test with claimed Az, Bz, and Cz
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; - 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_Bz_claim.append_to_transcript(b"comm_Bz_claim", transcript);@@ -408,15 +404,12 @@ * (comm_prod_Az_Bz_claims.decompress().unwrap() - comm_Cz_claim.decompress().unwrap()))
.compress(); // 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 let r_A = transcript.challenge_scalar(b"challenege_Az");@@ -447,16 +440,13 @@ transcript,
)?; // 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 = { // constant term@@ -484,15 +474,12 @@ let (eval_A_r, eval_B_r, eval_C_r) = evals;
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(); // 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)) }
@@ -178,11 +178,8 @@ r_joint.extend(r);
// decommit the joint polynomial at r_joint 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@@ -200,7 +197,7 @@ let mut evals = eval_row_ops_val_vec.to_owned();
evals.extend(eval_col_ops_val_vec); evals.resize(evals.len().next_power_of_two(), Scalar::zero()); - assert!(DerefsEvalProof::verify_single( + DerefsEvalProof::verify_single( &self.proof_derefs, &comm.comm_ops_val, r,@@ -208,9 +205,6 @@ evals,
gens, transcript, ) - .is_ok()); - - Ok(()) } }@@ -910,17 +904,14 @@
// verify derefs at rand_ops 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!(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 let eval_val_vec = &self.eval_val;@@ -990,20 +981,17 @@ let joint_claim_eval_mem = poly_evals_mem[0];
let mut r_joint_mem = challenges_mem; r_joint_mem.extend(rand_mem); 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 let (eval_ops_addr, eval_read_ts, eval_audit_ts) = &self.eval_row; - assert!(HashLayerProof::verify_helper( + HashLayerProof::verify_helper( &(rand_mem, rand_ops), claims_row, eval_row_ops_val,@@ -1013,11 +1001,10 @@ eval_audit_ts,
rx, r_hash, r_multiset_check, - ) - .is_ok()); + )?; let (eval_ops_addr, eval_read_ts, eval_audit_ts) = &self.eval_col; - assert!(HashLayerProof::verify_helper( + HashLayerProof::verify_helper( &(rand_mem, rand_ops), claims_col, eval_col_ops_val,@@ -1027,8 +1014,7 @@ eval_audit_ts,
ry, r_hash, r_multiset_check, - ) - .is_ok()); + )?; timer.stop(); Ok(())@@ -1562,22 +1548,17 @@
// produce a random element from the transcript for hash function 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, + ) } }
@@ -168,7 +168,9 @@ &comm_target,
) .is_ok() }; - assert!(res); + if !res { + return Err(ProofVerifyError::InternalError); + } r.push(r_i); }