diff --git a/Cargo.toml b/Cargo.toml index 529316f9..e5c119b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ tracing-subscriber = { version = "0.2" } serde = { version = "1.0", features = ["derive"] } csv = "1.1.5" criterion = "0.3.6" +hex = "0.4.3" [lib] name = "libspartan" @@ -77,4 +78,4 @@ ark-groth16 = { git = "https://github.com/arkworks-rs/groth16" } blstrs = { git = "https://github.com/nikkolasg/blstrs", branch = "feat/arkwork" } ark-ec = { git = "https://github.com/vmx/algebra", branch = "affine-repr-xy-owned" } ark-ff = { git = "https://github.com/vmx/algebra", branch = "affine-repr-xy-owned" } -ark-serialize = { git = "https://github.com/vmx/algebra", branch = "affine-repr-xy-owned" } \ No newline at end of file +ark-serialize = { git = "https://github.com/vmx/algebra", branch = "affine-repr-xy-owned", features= ["derive"] } \ No newline at end of file diff --git a/benches/testudo.rs b/benches/testudo.rs index 13ca03cc..2d312b58 100644 --- a/benches/testudo.rs +++ b/benches/testudo.rs @@ -25,9 +25,9 @@ struct BenchmarkResults { } fn main() { - bench_with_bls12_377(); + // bench_with_bls12_377(); // bench_with_bls12_381(); - // bench_with_ark_blst(); + bench_with_ark_blst(); } fn bench_with_ark_blst() { diff --git a/src/commitments.rs b/src/commitments.rs index 458a8397..f8c96560 100644 --- a/src/commitments.rs +++ b/src/commitments.rs @@ -2,11 +2,13 @@ use crate::ark_std::UniformRand; use crate::parameters::*; use ark_crypto_primitives::sponge::poseidon::PoseidonSponge; use ark_crypto_primitives::sponge::CryptographicSponge; +use ark_ec::AffineRepr; use ark_ec::{CurveGroup, VariableBaseMSM}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use rand::SeedableRng; use std::ops::Mul; -#[derive(Debug, Clone)] +#[derive(Debug, CanonicalSerialize, CanonicalDeserialize, Clone)] pub struct MultiCommitGens { pub n: usize, pub G: Vec, @@ -29,6 +31,7 @@ impl MultiCommitGens { let mut prng = rand::rngs::StdRng::from_seed(uniform_bytes); G::Affine::rand(&mut prng) }) + .inspect(|e| assert!(!e.is_zero(), "multicommitgen zero element")) .collect::>(); MultiCommitGens { @@ -82,6 +85,6 @@ impl PedersenCommit { gens_n: &MultiCommitGens, ) -> G { assert_eq!(scalars.len(), gens_n.n); - ::msm_unchecked(&gens_n.G, scalars) + gens_n.h.mul(blind) + ::msm_unchecked(&gens_n.G, scalars) //+ gens_n.h.mul(blind) } } diff --git a/src/dense_mlpoly.rs b/src/dense_mlpoly.rs index 3a649b77..d9251a74 100644 --- a/src/dense_mlpoly.rs +++ b/src/dense_mlpoly.rs @@ -7,7 +7,7 @@ use super::nizk::{DotProductProofGens, DotProductProofLog}; use crate::poseidon_transcript::{PoseidonTranscript, TranscriptWriter}; use ark_crypto_primitives::sponge::Absorb; use ark_ec::scalar_mul::variable_base::VariableBaseMSM; -use ark_ec::{pairing::Pairing, CurveGroup}; +use ark_ec::{pairing::Pairing, AffineRepr, CurveGroup}; use ark_ff::{PrimeField, Zero}; use ark_poly::MultilinearExtension; use ark_poly_commit::multilinear_pc::data_structures::{CommitterKey, VerifierKey}; @@ -172,7 +172,7 @@ impl<'a, 'b, F: PrimeField> SubAssign<&'a DensePolynomial> for DensePolynomia } } -#[derive(Clone)] +#[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] pub struct PolyCommitmentGens { pub gens: DotProductProofGens, pub ck: CommitterKey, @@ -188,7 +188,7 @@ impl PolyCommitmentGens { // Generates the SRS and trims it based on the number of variables in the // multilinear polynomial. - let mut rng = ark_std::test_rng(); + let mut rng = rand::thread_rng(); let pst_gens = MultilinearPC::::setup(num_vars / 2, &mut rng); let (ck, vk) = MultilinearPC::::trim(&pst_gens, num_vars / 2); @@ -202,7 +202,7 @@ pub struct PolyCommitmentBlinds { #[derive(Debug, CanonicalSerialize, CanonicalDeserialize)] pub struct PolyCommitment { - C: Vec, + C: Vec, } #[derive(Debug, CanonicalSerialize, CanonicalDeserialize)] @@ -318,9 +318,10 @@ impl DensePolynomial { let R_size = self.Z.len() / L_size; assert_eq!(L_size * R_size, self.Z.len()); let C = (0..L_size) - .into_par_iter() + .into_iter() .map(|i| { - PedersenCommit::commit_slice(&self.Z[R_size * i..R_size * (i + 1)], &blinds[i], gens) + let slice = &self.Z[R_size * i..R_size * (i + 1)]; + PedersenCommit::commit_slice(slice, &blinds[i], gens).into_affine() }) .collect(); PolyCommitment { C } @@ -336,9 +337,8 @@ impl DensePolynomial { assert_eq!(L_size * R_size, self.Z.len()); let C = (0..L_size) .map(|i| { - self.Z[R_size * i..R_size * (i + 1)] - .commit(&blinds[i], gens) - .compress() + PedersenCommit::commit_slice(&self.Z[R_size * i..R_size * (i + 1)], &blinds[i], gens) + .into_affine() }) .collect(); PolyCommitment { C } @@ -462,7 +462,7 @@ impl Index for DensePolynomial { impl TranscriptWriter for PolyCommitment { fn write_to_transcript(&self, transcript: &mut PoseidonTranscript) { for i in 0..self.C.len() { - transcript.append_point(b"", &self.C[i]); + transcript.append_point(b"", &self.C[i].into_group()); } } } @@ -546,11 +546,15 @@ where let (L, R) = eq.compute_factored_evals(); // compute a weighted sum of commitments and L - let C_decompressed = &comm.C; - - let C_LZ = - ::msm(&::normalize_batch(C_decompressed), &L) - .unwrap(); + // NOTE: This is necessary because of blst not supporting 0 points in msm + // TODO: fix the polycommit generators not being 0 - this should not have to be + let (c, s): (Vec<_>, Vec<_>) = comm + .C + .iter() + .zip(L.iter()) + .filter(|(c, _)| !c.is_zero()) + .unzip(); + let C_LZ = ::msm(&c, &s).expect("msm of different length"); self .proof diff --git a/src/lib.rs b/src/lib.rs index b1aca3a4..90965532 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,6 +49,7 @@ use r1csinstance::{R1CSCommitment, R1CSDecommitment, R1CSInstance}; use ark_ec::CurveGroup; /// `ComputationCommitment` holds a public preprocessed NP statement (e.g., R1CS) +#[derive(Debug)] pub struct ComputationCommitment { comm: R1CSCommitment, } @@ -296,6 +297,8 @@ mod tests { type F = ark_bls12_377::Fr; + type E = ark_bls12_377::Bls12_377; + type F = ark_bls12_377::Fr; #[test] pub fn check_r1cs_invalid_index() { let num_cons = 4; diff --git a/src/nizk/bullet.rs b/src/nizk/bullet.rs index 5d84b679..c6f46038 100644 --- a/src/nizk/bullet.rs +++ b/src/nizk/bullet.rs @@ -236,7 +236,6 @@ impl BulletReductionProof { let G_hat = G::msm(Gs, s.as_slice()).map_err(|_| ProofVerifyError::InternalError)?; let a_hat = inner_product(a, &s); - let Gamma_hat = G::msm( &G::normalize_batch( &Ls diff --git a/src/nizk/mod.rs b/src/nizk/mod.rs index ffafabbe..e878278a 100644 --- a/src/nizk/mod.rs +++ b/src/nizk/mod.rs @@ -14,7 +14,7 @@ use std::ops::Mul; mod bullet; use bullet::BulletReductionProof; -#[derive(Clone)] +#[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] pub struct DotProductProofGens { n: usize, pub gens_n: MultiCommitGens, @@ -168,7 +168,6 @@ where let lhs = (Gamma_hat.mul(c_s) + beta_s).mul(a_hat_s) + delta_s; let rhs = (g_hat + gens.gens_1.G[0].mul(a_hat_s)).mul(z1_s) + gens.gens_1.h.mul(z2_s); - assert_eq!(lhs, rhs); if lhs == rhs { @@ -182,29 +181,40 @@ where #[cfg(test)] mod tests { - use crate::parameters::poseidon_params; + use crate::parameters::PoseidonConfiguration; use super::*; + use ark_ec::CurveGroup; use ark_std::UniformRand; - type F = ark_bls12_377::Fr; - type G = ark_bls12_377::G1Projective; #[test] - fn check_dotproductproof_log() { + fn check_dotproductproof_log_blst() { + check_dotproductproof_log::(); + } + + #[test] + fn check_dotproductproof_log_arkworks_bls12_381() { + check_dotproductproof_log::(); + } + + fn check_dotproductproof_log() + where + G::ScalarField: PoseidonConfiguration + Absorb, + { let mut rng = ark_std::rand::thread_rng(); let n = 1024; let gens = DotProductProofGens::::new(n, b"test-1024"); - let x: Vec = (0..n).map(|_i| F::rand(&mut rng)).collect(); - let a: Vec = (0..n).map(|_i| F::rand(&mut rng)).collect(); + let x: Vec = (0..n).map(|_i| G::ScalarField::rand(&mut rng)).collect(); + let a: Vec = (0..n).map(|_i| G::ScalarField::rand(&mut rng)).collect(); let y = crate::dot_product(&x, &a); - let r_x = F::rand(&mut rng); - let r_y = F::rand(&mut rng); + let r_x = G::ScalarField::rand(&mut rng); + let r_y = G::ScalarField::rand(&mut rng); - let params = poseidon_params(); + let params = G::ScalarField::poseidon_params(); let mut prover_transcript = PoseidonTranscript::new(¶ms); let (proof, Cx, Cy) = DotProductProofLog::::prove(&gens, &mut prover_transcript, &x, &r_x, &a, &y, &r_y); diff --git a/src/poseidon_transcript.rs b/src/poseidon_transcript.rs index 8a08ae7e..8517a352 100644 --- a/src/poseidon_transcript.rs +++ b/src/poseidon_transcript.rs @@ -103,6 +103,28 @@ mod test { use ark_bls12_381::Fr; use ark_ff::PrimeField; use poseidon_paramgen; + + use super::*; + use crate::ark_std::UniformRand; + use crate::parameters::PoseidonConfiguration; + + #[test] + fn poseidon_compatibility() { + let mut f1 = PoseidonTranscript::new(&ark_bls12_381::Fr::poseidon_params()); + let mut f2 = PoseidonTranscript::new(&ark_blst::Scalar::poseidon_params()); + + let r1 = ark_bls12_381::Fr::rand(&mut rand::thread_rng()); + let r2 = ark_blst::Scalar::from(r1); + + f1.append_scalar(b"", &r1); + f2.append_scalar(b"", &r2); + + let c1: ark_bls12_381::Fr = f1.challenge_scalar(b""); + let c2: ark_blst::Scalar = f2.challenge_scalar(b""); + + let c22 = ark_blst::Scalar::from(c1); + assert!(c2 == c22); + } #[test] fn poseidon_parameters_generation() { print_modulus::(); diff --git a/src/r1csinstance.rs b/src/r1csinstance.rs index 14bb3562..96aaed55 100644 --- a/src/r1csinstance.rs +++ b/src/r1csinstance.rs @@ -26,6 +26,7 @@ pub struct R1CSInstance { C: SparseMatPolynomial, } +#[derive(CanonicalDeserialize, CanonicalSerialize, Debug)] pub struct R1CSCommitmentGens { gens: SparseMatPolyCommitmentGens, } diff --git a/src/sparse_mlpoly.rs b/src/sparse_mlpoly.rs index b538423a..32a85586 100644 --- a/src/sparse_mlpoly.rs +++ b/src/sparse_mlpoly.rs @@ -283,6 +283,7 @@ pub struct MultiSparseMatPolynomialAsDense { comb_mem: DensePolynomial, } +#[derive(CanonicalSerialize, CanonicalDeserialize, Debug)] pub struct SparseMatPolyCommitmentGens { gens_ops: PolyCommitmentGens, gens_mem: PolyCommitmentGens, diff --git a/src/testudo_snark.rs b/src/testudo_snark.rs index 7f8cc013..3c3ce5aa 100644 --- a/src/testudo_snark.rs +++ b/src/testudo_snark.rs @@ -170,7 +170,7 @@ where timer_eval_proof.stop(); transcript.new_from_state(&c); - let timer_sat_circuit_verification = Timer::new("r1cs_sat_circuit_verification"); + let timer_sat_circuit_verification = Timer::new("r1cs_sat_circuit_verification_proof"); let r1cs_verifier_proof = r1cs_sat_proof .prove_verifier( inst.inst.get_num_vars(),