diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml deleted file mode 100644 index df6ba15..0000000 --- a/.github/workflows/rust.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Build and Test Spartan - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - build_nightly: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Install - run: rustup default nightly - - name: Install rustfmt Components - run: rustup component add rustfmt - - name: Install clippy - run: rustup component add clippy - - name: Build - run: cargo build --verbose - - name: Run tests - run: cargo test --verbose - - name: Build examples - run: cargo build --examples --verbose - - name: Check Rustfmt Code Style - run: cargo fmt --all -- --check - - name: Check clippy warnings - run: cargo clippy --all-targets --all-features -- -D warnings - diff --git a/.github/workflows/testudo.yml b/.github/workflows/testudo.yml new file mode 100644 index 0000000..acd6a67 --- /dev/null +++ b/.github/workflows/testudo.yml @@ -0,0 +1,29 @@ +name: Build and Test Testudo + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + build_nightly: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install + run: rustup default nightly + - name: Install rustfmt Components + run: rustup component add rustfmt + - name: Install clippy + run: rustup component add clippy + - name: Build + run: cargo build --verbose + - name: Run tests + run: cargo test --verbose + - name: Build examples + run: cargo build --examples --verbose + - name: Check Rustfmt Code Style + run: cargo fmt --all -- --check + - name: Check clippy warnings + run: cargo clippy --all-targets --all-features diff --git a/examples/cubic.rs b/examples/cubic.rs index b474594..6ccdbfc 100644 --- a/examples/cubic.rs +++ b/examples/cubic.rs @@ -69,7 +69,7 @@ fn produce_r1cs() -> ( A.push((3, 3, one.clone())); A.push((3, num_vars, Scalar::from(5u32).into_repr().to_bytes_le())); B.push((3, num_vars, one.clone())); - C.push((3, num_vars + 1, one.clone())); + C.push((3, num_vars + 1, one)); let inst = Instance::new(num_cons, num_vars, num_inputs, &A, &B, &C).unwrap(); diff --git a/src/commitments.rs b/src/commitments.rs index eb646cf..2818ad3 100644 --- a/src/commitments.rs +++ b/src/commitments.rs @@ -25,7 +25,7 @@ impl MultiCommitGens { let mut gens: Vec = Vec::new(); for _ in 0..n + 1 { let mut el_aff: Option = None; - while el_aff.is_some() != true { + while el_aff.is_none() { let uniform_bytes = sponge.squeeze_bytes(64); el_aff = GroupElementAffine::from_random_bytes(&uniform_bytes); } diff --git a/src/constraints.rs b/src/constraints.rs index 4604793..4b44a3f 100644 --- a/src/constraints.rs +++ b/src/constraints.rs @@ -23,10 +23,10 @@ use ark_r1cs_std::{ fields::fp::FpVar, prelude::{Boolean, EqGadget, FieldVar}, }; -<<<<<<< HEAD use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, Namespace, SynthesisError}; -======= -use ark_relations::{ +use ark_sponge::{ + constraints::CryptographicSpongeVar, + poseidon::{constraints::PoseidonSpongeVar, PoseidonParameters}, }; use rand::{CryptoRng, Rng}; @@ -46,12 +46,12 @@ impl PoseidonTranscripVar { if let Some(c) = challenge { let c_var = FpVar::::new_witness(cs.clone(), || Ok(c)).unwrap(); - sponge.absorb(&c_var); + sponge.absorb(&c_var).unwrap(); } Self { - cs: cs, - sponge: sponge, + cs, + sponge, params: params.clone(), } } @@ -60,7 +60,7 @@ impl PoseidonTranscripVar { self.sponge.absorb(&input) } - fn append_vector(&mut self, input_vec: &Vec>) -> Result<(), SynthesisError> { + fn append_vector(&mut self, input_vec: &[FpVar]) -> Result<(), SynthesisError> { for input in input_vec.iter() { self.append(input)?; } @@ -96,7 +96,7 @@ impl AllocVar for UniPolyVar { let cp: &UniPoly = c.borrow(); let mut coeffs_var = Vec::new(); for coeff in cp.coeffs.iter() { - let coeff_var = FpVar::::new_variable(cs.clone(), || Ok(coeff.clone()), mode)?; + let coeff_var = FpVar::::new_variable(cs.clone(), || Ok(coeff), mode)?; coeffs_var.push(coeff_var); } Ok(Self { coeffs: coeffs_var }) @@ -138,7 +138,7 @@ pub struct SumcheckVerificationCircuit { impl SumcheckVerificationCircuit { fn verifiy_sumcheck( &self, - poly_vars: &Vec, + poly_vars: &[UniPolyVar], claim_var: &FpVar, transcript_var: &mut PoseidonTranscripVar, ) -> Result<(FpVar, Vec>), SynthesisError> { @@ -173,7 +173,7 @@ impl AllocVar for SparsePolyEntryVar { f().and_then(|s| { let cs = cs.into(); let spe: &SparsePolyEntry = s.borrow(); - let val_var = FpVar::::new_witness(cs.clone(), || Ok(spe.val))?; + let val_var = FpVar::::new_witness(cs, || Ok(spe.val))?; Ok(Self { idx: spe.idx, val_var, @@ -211,7 +211,7 @@ impl AllocVar for SparsePolynomialVar { } impl SparsePolynomialVar { - fn compute_chi(a: &[bool], r_vars: &Vec>) -> FpVar { + fn compute_chi(a: &[bool], r_vars: &[FpVar]) -> FpVar { let mut chi_i_var = FpVar::::one(); let one = FpVar::::one(); for (i, r_var) in r_vars.iter().enumerate() { @@ -224,12 +224,12 @@ impl SparsePolynomialVar { chi_i_var } - pub fn evaluate(&self, r_var: &Vec>) -> FpVar { + pub fn evaluate(&self, r_var: &[FpVar]) -> FpVar { let mut sum = FpVar::::zero(); for spe_var in self.Z_var.iter() { // potential problem let bits = &spe_var.idx.get_bits(r_var.len()); - sum += SparsePolynomialVar::compute_chi(&bits, r_var) * &spe_var.val_var; + sum += SparsePolynomialVar::compute_chi(bits, r_var) * &spe_var.val_var; } sum } @@ -350,7 +350,7 @@ impl ConstraintSynthesizer for R1CSVerificationCircuit { AllocationMode::Witness, )?; - let poly_input_eval_var = input_as_sparse_poly_var.evaluate(&ry_var[1..].to_vec()); + let poly_input_eval_var = input_as_sparse_poly_var.evaluate(&ry_var[1..]); let eval_vars_at_ry_var = FpVar::::new_input(cs.clone(), || Ok(&self.eval_vars_at_ry))?; @@ -361,7 +361,7 @@ impl ConstraintSynthesizer for R1CSVerificationCircuit { let eval_A_r_var = FpVar::::new_witness(cs.clone(), || Ok(eval_A_r))?; let eval_B_r_var = FpVar::::new_witness(cs.clone(), || Ok(eval_B_r))?; - let eval_C_r_var = FpVar::::new_witness(cs.clone(), || Ok(eval_C_r))?; + let eval_C_r_var = FpVar::::new_witness(cs, || Ok(eval_C_r))?; let scalar_var = &r_A_var * &eval_A_r_var + &r_B_var * &eval_B_r_var + &r_C_var * &eval_C_r_var; @@ -407,7 +407,7 @@ impl VerifierCircuit { let proof = Groth16::::prove(&pk, inner_circuit.clone(), &mut rng)?; let pvk = Groth16::::process_vk(&vk).unwrap(); Ok(Self { - inner_circuit: inner_circuit, + inner_circuit, inner_proof: proof, inner_vk: pvk, evals_var_at_ry: config.eval_vars_at_ry, @@ -432,7 +432,7 @@ impl ConstraintSynthesizer for VerifierCircuit { .collect::, _>>()?; let input_var = BooleanInputVar::::new(bits); - let vk_var = PreparedVerifyingKeyVar::new_witness(cs.clone(), || Ok(self.inner_vk.clone()))?; + let vk_var = PreparedVerifyingKeyVar::new_witness(cs, || Ok(self.inner_vk.clone()))?; Groth16VerifierGadget::verify_with_processed_vk(&vk_var, &input_var, &proof_var)? .enforce_equal(&Boolean::constant(true))?; Ok(()) diff --git a/src/group.rs b/src/group.rs index 55923f5..8e0baa9 100644 --- a/src/group.rs +++ b/src/group.rs @@ -6,7 +6,7 @@ use lazy_static::lazy_static; use super::scalar::Scalar; -use ark_ec::{AffineCurve, ProjectiveCurve}; +use ark_ec::ProjectiveCurve; use ark_serialize::*; use core::borrow::Borrow; @@ -38,7 +38,6 @@ impl CompressGroupElement for GroupElement { fn compress(&self) -> CompressedGroup { let mut point_encoding = Vec::new(); self.serialize(&mut point_encoding).unwrap(); - // println!("in compress {:?}", point_encoding);; CompressedGroup(point_encoding) } } @@ -46,11 +45,11 @@ impl CompressGroupElement for GroupElement { impl DecompressGroupElement for GroupElement { fn decompress(encoded: &CompressedGroup) -> Option { let res = GroupElement::deserialize(&*encoded.0); - if res.is_err() { + if let Ok(r) = res { + Some(r) + } else { println!("{:?}", res); None - } else { - Some(res.unwrap()) } } } @@ -58,7 +57,7 @@ impl DecompressGroupElement for GroupElement { impl UnpackGroupElement for CompressedGroup { fn unpack(&self) -> Result { let encoded = self.0.clone(); - GroupElement::decompress(self).ok_or_else(|| ProofVerifyError::DecompressionError(encoded)) + GroupElement::decompress(self).ok_or(ProofVerifyError::DecompressionError(encoded)) } } @@ -69,11 +68,11 @@ pub trait VartimeMultiscalarMul { impl VartimeMultiscalarMul for GroupElement { fn vartime_multiscalar_mul(scalars: &[Scalar], points: &[GroupElement]) -> GroupElement { let repr_scalars = scalars - .into_iter() + .iter() .map(|S| S.borrow().into_repr()) .collect::::BigInt>>(); let aff_points = points - .into_iter() + .iter() .map(|P| P.borrow().into_affine()) .collect::>(); VariableBaseMSM::multi_scalar_mul(aff_points.as_slice(), repr_scalars.as_slice()) diff --git a/src/lib.rs b/src/lib.rs index e0566f2..58776d0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -56,7 +56,6 @@ use random::RandomTape; use scalar::Scalar; use timer::Timer; -use transcript::ProofTranscript; /// `ComputationCommitment` holds a public preprocessed NP statement (e.g., R1CS) pub struct ComputationCommitment { @@ -81,8 +80,8 @@ impl Assignment { let mut vec_scalar: Vec = Vec::new(); for v in vec { let val = Scalar::from_random_bytes(v.as_slice()); - if val.is_some() == true { - vec_scalar.push(val.unwrap()); + if let Some(v) = val { + vec_scalar.push(v); } else { return Err(R1CSError::InvalidScalar); } @@ -188,14 +187,14 @@ impl Instance { return Err(R1CSError::InvalidIndex); } - let val = Scalar::from_random_bytes(&val_bytes.as_slice()); - if val.is_some() == true { + let val = Scalar::from_random_bytes(val_bytes.as_slice()); + if let Some(v) = val { // if col >= num_vars, it means that it is referencing a 1 or input in the satisfying // assignment if *col >= num_vars { - mat.push((*row, *col + num_vars_padded - num_vars, val.unwrap())); + mat.push((*row, *col + num_vars_padded - num_vars, v)); } else { - mat.push((*row, *col, val.unwrap())); + mat.push((*row, *col, v)); } } else { return Err(R1CSError::InvalidScalar); diff --git a/src/nizk/bullet.rs b/src/nizk/bullet.rs index f85266e..8283a11 100644 --- a/src/nizk/bullet.rs +++ b/src/nizk/bullet.rs @@ -91,14 +91,14 @@ impl BulletReductionProof { .iter() .chain(iter::once(&c_L)) .chain(iter::once(blind_L)) - .map(|s| *s) + .copied() .collect::>() .as_slice(), G_R .iter() .chain(iter::once(Q)) .chain(iter::once(H)) - .map(|p| *p) + .copied() .collect::>() .as_slice(), ); @@ -108,14 +108,14 @@ impl BulletReductionProof { .iter() .chain(iter::once(&c_R)) .chain(iter::once(blind_R)) - .map(|s| *s) + .copied() .collect::>() .as_slice(), G_L .iter() .chain(iter::once(Q)) .chain(iter::once(H)) - .map(|p| *p) + .copied() .collect::>() .as_slice(), ); @@ -248,13 +248,13 @@ impl BulletReductionProof { .iter() .chain(u_inv_sq.iter()) .chain(iter::once(&Scalar::one())) - .map(|s| *s) + .copied() .collect::>() .as_slice(), Ls.iter() .chain(Rs.iter()) .chain(iter::once(Gamma)) - .map(|p| *p) + .copied() .collect::>() .as_slice(), ); diff --git a/src/nizk/mod.rs b/src/nizk/mod.rs index f8e7497..e904406 100644 --- a/src/nizk/mod.rs +++ b/src/nizk/mod.rs @@ -128,8 +128,8 @@ impl EqualityProof { ) -> Result<(), ProofVerifyError> { // transcript.append_protocol_name(EqualityProof::protocol_name()); - transcript.append_point(&C1); - transcript.append_point(&C2); + transcript.append_point(C1); + transcript.append_point(C2); transcript.append_point(&self.alpha); let c = transcript.challenge_scalar(); @@ -351,7 +351,7 @@ impl DotProductProof { let Cy = y.commit(blind_y, gens_1).compress(); Cy.append_to_poseidon(transcript); - transcript.append_scalar_vector(&a_vec.to_vec()); + transcript.append_scalar_vector(a_vec); let delta = d_vec.commit(&r_delta, gens_n).compress(); delta.append_to_poseidon(transcript); @@ -398,7 +398,7 @@ impl DotProductProof { // transcript.append_protocol_name(DotProductProof::protocol_name()); Cx.append_to_poseidon(transcript); Cy.append_to_poseidon(transcript); - transcript.append_scalar_vector(&a.to_vec()); + transcript.append_scalar_vector(a); self.delta.append_to_poseidon(transcript); self.beta.append_to_poseidon(transcript); @@ -484,7 +484,7 @@ impl DotProductProofLog { let Cy = y.commit(blind_y, &gens.gens_1).compress(); transcript.append_point(&Cy); - transcript.append_scalar_vector(&a_vec.to_vec()); + transcript.append_scalar_vector(a_vec); let blind_Gamma = (*blind_x) + blind_y; let (bullet_reduction_proof, _Gamma_hat, x_hat, a_hat, g_hat, rhat_Gamma) = @@ -548,9 +548,9 @@ impl DotProductProofLog { // Cy.append_to_poseidon( transcript); // a.append_to_poseidon( transcript); - transcript.append_point(&Cx); - transcript.append_point(&Cy); - transcript.append_scalar_vector(&a.to_vec()); + transcript.append_point(Cx); + transcript.append_point(Cy); + transcript.append_scalar_vector(a); let Gamma = Cx.unpack()? + Cy.unpack()?; diff --git a/src/poseidon_transcript.rs b/src/poseidon_transcript.rs index 666f2d9..3ada903 100644 --- a/src/poseidon_transcript.rs +++ b/src/poseidon_transcript.rs @@ -4,7 +4,6 @@ use super::scalar::Scalar; // use ark_r1cs_std::prelude::*; use ark_sponge::{ - constraints::CryptographicSpongeVar, poseidon::{PoseidonParameters, PoseidonSponge}, CryptographicSponge, }; @@ -21,14 +20,14 @@ impl PoseidonTranscript { pub fn new(params: &PoseidonParameters) -> Self { let sponge = PoseidonSponge::new(params); PoseidonTranscript { - sponge: sponge, + sponge, params: params.clone(), } } pub fn new_from_state(&mut self, challenge: &Scalar) { self.sponge = PoseidonSponge::new(&self.params); - self.append_scalar(&challenge); + self.append_scalar(challenge); } pub fn append_u64(&mut self, x: u64) { @@ -47,20 +46,18 @@ impl PoseidonTranscript { self.sponge.absorb(&point.0); } - pub fn append_scalar_vector(&mut self, scalars: &Vec) { + pub fn append_scalar_vector(&mut self, scalars: &[Scalar]) { for scalar in scalars.iter() { - self.append_scalar(&scalar); + self.append_scalar(scalar); } } pub fn challenge_scalar(&mut self) -> Scalar { - let scalar = self.sponge.squeeze_field_elements(1).remove(0); - scalar + self.sponge.squeeze_field_elements(1).remove(0) } pub fn challenge_vector(&mut self, len: usize) -> Vec { - let challenges = self.sponge.squeeze_field_elements(len); - challenges + self.sponge.squeeze_field_elements(len) } } diff --git a/src/product_tree.rs b/src/product_tree.rs index 0bb883e..5d4b071 100644 --- a/src/product_tree.rs +++ b/src/product_tree.rs @@ -6,7 +6,6 @@ use super::dense_mlpoly::EqPolynomial; use super::math::Math; use super::scalar::Scalar; use super::sumcheck::SumcheckInstanceProof; -use super::transcript::ProofTranscript; use ark_serialize::*; use ark_std::One; diff --git a/src/r1csinstance.rs b/src/r1csinstance.rs index ac9191f..323d040 100644 --- a/src/r1csinstance.rs +++ b/src/r1csinstance.rs @@ -17,7 +17,6 @@ use ark_std::{One, UniformRand, Zero}; use digest::{ExtendableOutput, Input}; use merlin::Transcript; -use serde::Serialize; use sha3::Shake256; #[derive(Debug, CanonicalSerialize, CanonicalDeserialize, Clone)] @@ -167,7 +166,7 @@ impl R1CSInstance { shake.input(bytes); let mut reader = shake.xof_result(); let mut buf = [0u8; 256]; - reader.read(&mut buf).unwrap(); + reader.read_exact(&mut buf).unwrap(); buf.to_vec() } diff --git a/src/r1csproof.rs b/src/r1csproof.rs index 1de8581..02d3645 100644 --- a/src/r1csproof.rs +++ b/src/r1csproof.rs @@ -11,16 +11,12 @@ use ark_bw6_761::BW6_761 as P; use super::commitments::MultiCommitGens; use super::dense_mlpoly::{DensePolynomial, EqPolynomial, PolyCommitmentGens}; use super::errors::ProofVerifyError; -use super::group::{ - CompressGroupElement, DecompressGroupElement, GroupElement, VartimeMultiscalarMul, -}; -use super::nizk::{EqualityProof, KnowledgeProof, ProductProof}; + use super::r1csinstance::R1CSInstance; use super::scalar::Scalar; use super::sparse_mlpoly::{SparsePolyEntry, SparsePolynomial}; use super::timer::Timer; -use super::transcript::ProofTranscript; use ark_crypto_primitives::{CircuitSpecificSetupSNARK, SNARK}; use ark_groth16::Groth16; @@ -141,7 +137,7 @@ impl R1CSProof { let c = transcript.challenge_scalar(); transcript.new_from_state(&c); - transcript.append_scalar_vector(&input.to_vec()); + transcript.append_scalar_vector(input); let poly_vars = DensePolynomial::new(vars.clone()); @@ -219,7 +215,7 @@ impl R1CSProof { timer_sc_proof_phase2.stop(); let timer_polyeval = Timer::new("polyeval"); - let eval_vars_at_ry = poly_vars.evaluate(&ry[1..].to_vec()); + let eval_vars_at_ry = poly_vars.evaluate(&ry[1..]); timer_polyeval.stop(); timer_prove.stop(); @@ -259,8 +255,8 @@ impl R1CSProof { SparsePolynomial::new(n.log_2() as usize, input_as_sparse_poly_entries); let config = VerifierConfig { - num_vars: num_vars, - num_cons: num_cons, + num_vars, + num_cons, input: input.to_vec(), evals: *evals, params: poseidon_params(), @@ -269,7 +265,7 @@ impl R1CSProof { polys_sc1: self.sc_proof_phase1.polys.clone(), polys_sc2: self.sc_proof_phase2.polys.clone(), eval_vars_at_ry: self.eval_vars_at_ry, - input_as_sparse_poly: input_as_sparse_poly, + input_as_sparse_poly, }; let mut rng = ark_std::test_rng(); @@ -283,7 +279,7 @@ impl R1CSProof { let ds = start.elapsed().as_millis(); let start = Instant::now(); - let proof = Groth16::

::prove(&pk, circuit.clone(), &mut rng).unwrap(); + let proof = Groth16::

::prove(&pk, circuit, &mut rng).unwrap(); let dp2 = start.elapsed().as_millis(); let start = Instant::now(); @@ -317,8 +313,8 @@ impl R1CSProof { SparsePolynomial::new(n.log_2() as usize, input_as_sparse_poly_entries); let config = VerifierConfig { - num_vars: num_vars, - num_cons: num_cons, + num_vars, + num_cons, input: input.to_vec(), evals: *evals, params: poseidon_params(), @@ -327,7 +323,7 @@ impl R1CSProof { polys_sc1: self.sc_proof_phase1.polys.clone(), polys_sc2: self.sc_proof_phase2.polys.clone(), eval_vars_at_ry: self.eval_vars_at_ry, - input_as_sparse_poly: input_as_sparse_poly, + input_as_sparse_poly, }; let mut rng = ark_std::test_rng(); @@ -335,7 +331,7 @@ impl R1CSProof { let nc_inner = verify_constraints_inner(circuit.clone(), &num_cons); - let nc_outer = verify_constraints_outer(circuit.clone(), &num_cons); + let nc_outer = verify_constraints_outer(circuit, &num_cons); Ok(nc_inner + nc_outer) } } diff --git a/src/sparse_mlpoly.rs b/src/sparse_mlpoly.rs index 009639e..3d8b0d5 100644 --- a/src/sparse_mlpoly.rs +++ b/src/sparse_mlpoly.rs @@ -13,12 +13,11 @@ use super::product_tree::{DotProductCircuit, ProductCircuit, ProductCircuitEvalP use super::random::RandomTape; use super::scalar::Scalar; use super::timer::Timer; -use super::transcript::{AppendToTranscript, ProofTranscript}; +use super::transcript::AppendToTranscript; use ark_ff::{Field, One, Zero}; use ark_serialize::*; use core::cmp::Ordering; use merlin::Transcript; -use serde::Serialize; #[derive(Debug, CanonicalSerialize, CanonicalDeserialize, Clone)] pub struct SparseMatEntry { @@ -1650,11 +1649,7 @@ impl SparsePolynomial { #[cfg(test)] mod tests { -<<<<<<< HEAD use crate::parameters::poseidon_params; -======= - use crate::{parameters::poseidon_params}; ->>>>>>> implement spartan verifier as a circuit and verify it with groth16 use super::*; use ark_std::UniformRand; @@ -1716,7 +1711,6 @@ mod tests { ); let mut verifier_transcript = PoseidonTranscript::new(¶ms); - (b"example"); assert!(proof .verify( &poly_comm, diff --git a/src/sumcheck.rs b/src/sumcheck.rs index f6069dd..b34f037 100644 --- a/src/sumcheck.rs +++ b/src/sumcheck.rs @@ -6,7 +6,6 @@ use super::dense_mlpoly::DensePolynomial; use super::errors::ProofVerifyError; use super::scalar::Scalar; -use super::transcript::ProofTranscript; use super::unipoly::UniPoly; use ark_ff::Zero; diff --git a/src/transcript.rs b/src/transcript.rs index 29eabcc..a5c22ea 100644 --- a/src/transcript.rs +++ b/src/transcript.rs @@ -18,7 +18,7 @@ impl ProofTranscript for Transcript { } fn append_scalar(&mut self, label: &'static [u8], scalar: &Scalar) { - self.append_message(label, &scalar.into_repr().to_bytes_le().as_slice()); + self.append_message(label, scalar.into_repr().to_bytes_le().as_slice()); } fn append_point(&mut self, label: &'static [u8], point: &CompressedGroup) {