mirror of
https://github.com/arnaucube/testudo.git
synced 2026-01-13 01:01:28 +01:00
remove asserts; return result objects (#45)
* remove asserts; return result objects * bump version * clippy
This commit is contained in:
@@ -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"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Spartan: High-speed zkSNARKs without trusted setup
|
# 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.
|
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`.
|
||||||
|
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
19
src/lib.rs
19
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
|
self.r1cs_eval_proof.verify(
|
||||||
.r1cs_eval_proof
|
&comm.comm,
|
||||||
.verify(
|
&rx,
|
||||||
&comm.comm,
|
&ry,
|
||||||
&rx,
|
&self.inst_evals,
|
||||||
&ry,
|
&gens.gens_r1cs_eval,
|
||||||
&self.inst_evals,
|
transcript,
|
||||||
&gens.gens_r1cs_eval,
|
)?;
|
||||||
transcript
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
timer_eval_proof.stop();
|
timer_eval_proof.stop();
|
||||||
timer_verify.stop();
|
timer_verify.stop();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -336,18 +336,13 @@ impl R1CSEvalProof {
|
|||||||
gens: &R1CSCommitmentGens,
|
gens: &R1CSCommitmentGens,
|
||||||
transcript: &mut Transcript,
|
transcript: &mut Transcript,
|
||||||
) -> Result<(), ProofVerifyError> {
|
) -> Result<(), ProofVerifyError> {
|
||||||
assert!(self
|
self.proof.verify(
|
||||||
.proof
|
&comm.comm,
|
||||||
.verify(
|
rx,
|
||||||
&comm.comm,
|
ry,
|
||||||
rx,
|
&[evals.0, evals.1, evals.2],
|
||||||
ry,
|
&gens.gens,
|
||||||
&[evals.0, evals.1, evals.2],
|
transcript,
|
||||||
&gens.gens,
|
)
|
||||||
transcript
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
pok_Cz_claim.verify(&gens.gens_sc.gens_1, transcript, comm_Cz_claim)?;
|
||||||
.verify(&gens.gens_sc.gens_1, transcript, comm_Cz_claim)
|
proof_prod.verify(
|
||||||
.is_ok());
|
&gens.gens_sc.gens_1,
|
||||||
assert!(proof_prod
|
transcript,
|
||||||
.verify(
|
comm_Az_claim,
|
||||||
&gens.gens_sc.gens_1,
|
comm_Bz_claim,
|
||||||
transcript,
|
comm_prod_Az_Bz_claims,
|
||||||
comm_Az_claim,
|
)?;
|
||||||
comm_Bz_claim,
|
|
||||||
comm_prod_Az_Bz_claims
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
|
|
||||||
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
|
self.proof_eq_sc_phase1.verify(
|
||||||
.proof_eq_sc_phase1
|
&gens.gens_sc.gens_1,
|
||||||
.verify(
|
transcript,
|
||||||
&gens.gens_sc.gens_1,
|
&expected_claim_post_phase1,
|
||||||
transcript,
|
&comm_claim_post_phase1,
|
||||||
&expected_claim_post_phase1,
|
)?;
|
||||||
&comm_claim_post_phase1,
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
|
|
||||||
// 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
|
self.proof_eval_vars_at_ry.verify(
|
||||||
.proof_eval_vars_at_ry
|
&gens.gens_pc,
|
||||||
.verify(
|
transcript,
|
||||||
&gens.gens_pc,
|
&ry[1..].to_vec(),
|
||||||
transcript,
|
&self.comm_vars_at_ry,
|
||||||
&ry[1..].to_vec(),
|
&self.comm_vars,
|
||||||
&self.comm_vars_at_ry,
|
)?;
|
||||||
&self.comm_vars
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
|
|
||||||
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
|
self.proof_eq_sc_phase2.verify(
|
||||||
.proof_eq_sc_phase2
|
&gens.gens_sc.gens_1,
|
||||||
.verify(
|
transcript,
|
||||||
&gens.gens_sc.gens_1,
|
&expected_claim_post_phase2,
|
||||||
transcript,
|
&comm_claim_post_phase2,
|
||||||
&expected_claim_post_phase2,
|
)?;
|
||||||
&comm_claim_post_phase2,
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
|
|
||||||
Ok((rx, ry))
|
Ok((rx, ry))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
self.proof_derefs.verify(
|
||||||
.proof_derefs
|
rand_ops,
|
||||||
.verify(
|
eval_row_ops_val,
|
||||||
rand_ops,
|
eval_col_ops_val,
|
||||||
eval_row_ops_val,
|
&gens.gens_derefs,
|
||||||
eval_col_ops_val,
|
comm_derefs,
|
||||||
&gens.gens_derefs,
|
transcript,
|
||||||
comm_derefs,
|
)?;
|
||||||
transcript
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
|
|
||||||
// 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
|
self.proof_mem.verify_plain(
|
||||||
.proof_mem
|
&gens.gens_mem,
|
||||||
.verify_plain(
|
transcript,
|
||||||
&gens.gens_mem,
|
&r_joint_mem,
|
||||||
transcript,
|
&joint_claim_eval_mem,
|
||||||
&r_joint_mem,
|
&comm.comm_comb_mem,
|
||||||
&joint_claim_eval_mem,
|
)?;
|
||||||
&comm.comm_comb_mem
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
|
|
||||||
// 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
|
self.poly_eval_network_proof.verify(
|
||||||
.poly_eval_network_proof
|
comm,
|
||||||
.verify(
|
&self.comm_derefs,
|
||||||
comm,
|
evals,
|
||||||
&self.comm_derefs,
|
gens,
|
||||||
evals,
|
&rx_ext,
|
||||||
gens,
|
&ry_ext,
|
||||||
&rx_ext,
|
&(r_mem_check[0], r_mem_check[1]),
|
||||||
&ry_ext,
|
nz,
|
||||||
&(r_mem_check[0], r_mem_check[1]),
|
transcript,
|
||||||
nz,
|
)
|
||||||
transcript,
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user