diff --git a/dp-crypto/benches/cpu_vs_gpu.rs b/dp-crypto/benches/cpu_vs_gpu.rs index 63df2dc..c2bebe4 100644 --- a/dp-crypto/benches/cpu_vs_gpu.rs +++ b/dp-crypto/benches/cpu_vs_gpu.rs @@ -9,18 +9,15 @@ use ark_bn254::{Bn254, Fr}; use ark_ff::AdditiveGroup; +use ark_std::rand::Rng; use ark_std::rand::thread_rng; use divan::Bencher; +#[cfg(feature = "cuda")] +use dp_crypto::arkyper::HyperKZGGpu; use dp_crypto::{ - arkyper::{ - transcript::blake3::Blake3Transcript, - CommitmentScheme, HyperKZG, - }, + arkyper::{CommitmentScheme, HyperKZG, transcript::blake3::Blake3Transcript}, poly::dense::DensePolynomial, }; -#[cfg(feature = "cuda")] -use dp_crypto::arkyper::HyperKZGGpu; -use ark_std::rand::Rng; fn main() { divan::main(); @@ -58,9 +55,7 @@ mod batch_commit { let (pp, _) = HyperKZG::::test_setup(&mut thread_rng(), LOG_N); (pp, polys) }) - .bench_local_values(|(pp, polys)| { - HyperKZG::::batch_commit(&pp, &polys).unwrap() - }) + .bench_local_values(|(pp, polys)| HyperKZG::::batch_commit(&pp, &polys).unwrap()) } #[divan::bench] @@ -71,9 +66,7 @@ mod batch_commit { let (pp, _) = HyperKZGGpu::::test_setup(&mut thread_rng(), LOG_N); (pp, polys) }) - .bench_local_values(|(pp, polys)| { - HyperKZGGpu::::batch_commit(&pp, &polys).unwrap() - }) + .bench_local_values(|(pp, polys)| HyperKZGGpu::::batch_commit(&pp, &polys).unwrap()) } } @@ -86,18 +79,19 @@ mod batch_open { use super::*; /// Build a single combined polynomial with small (≤53-bit) coefficients. - fn make_open_input>() -> (CS::ProverSetup, DensePolynomial<'static, Fr>, Vec, Blake3Transcript) { + fn make_open_input>() -> ( + CS::ProverSetup, + DensePolynomial<'static, Fr>, + Vec, + Blake3Transcript, + ) { let polys = make_polys(); let (pp, _) = CS::test_setup(&mut thread_rng(), LOG_N); let point: Vec = (0..LOG_N).map(|i| Fr::from(i as u64)).collect(); // Use small challenges so the linear combination stays ≤53-bit. - let challenges: Vec = (1..=polys.len()) - .map(|i| Fr::from(i as u64)) - .collect(); - let poly = DensePolynomial::linear_combination( - &polys.iter().collect::>(), - &challenges, - ); + let challenges: Vec = (1..=polys.len()).map(|i| Fr::from(i as u64)).collect(); + let poly = + DensePolynomial::linear_combination(&polys.iter().collect::>(), &challenges); let transcript = Blake3Transcript::new(b"bench_open"); (pp, poly, point, transcript) } @@ -105,17 +99,17 @@ mod batch_open { #[divan::bench] fn cpu(b: Bencher) { b.with_inputs(make_open_input::>) - .bench_local_values(|(pp, poly, point, mut transcript)| { - HyperKZG::::open(&pp, &poly, &point, &Fr::ZERO, &mut transcript).unwrap() - }) + .bench_local_values(|(pp, poly, point, mut transcript)| { + HyperKZG::::open(&pp, &poly, &point, &Fr::ZERO, &mut transcript).unwrap() + }) } #[divan::bench] #[cfg(feature = "cuda")] fn gpu(b: Bencher) { b.with_inputs(make_open_input::>) - .bench_local_values(|(pp, poly, point, mut transcript)| { - HyperKZGGpu::::prove(&pp, &poly, &point, None, &mut transcript).unwrap() - }) + .bench_local_values(|(pp, poly, point, mut transcript)| { + HyperKZGGpu::::prove(&pp, &poly, &point, None, &mut transcript).unwrap() + }) } } diff --git a/dp-crypto/benches/msm_bitlength.rs b/dp-crypto/benches/msm_bitlength.rs index 624b406..2b82923 100644 --- a/dp-crypto/benches/msm_bitlength.rs +++ b/dp-crypto/benches/msm_bitlength.rs @@ -10,8 +10,8 @@ //! ``` use ark_bn254::Fr; -use ark_std::rand::SeedableRng; use ark_std::UniformRand; +use ark_std::rand::SeedableRng; use divan::Bencher; fn main() { @@ -34,9 +34,9 @@ fn generate_small_scalars(n: usize, max_bits: u32, rng: &mut impl ark_std::rand: #[divan::bench_group(sample_count = 5, sample_size = 1)] mod gpu_msm_bitlength { use super::*; - use dp_crypto::arkyper::gpu_msm::{convert_bases_to_gpu, convert_scalars_to_bigint, GPU_MSM}; - use dp_crypto::arkyper::{HyperKZGSRS, HyperKZGProverKey}; use ark_bn254::Bn254; + use dp_crypto::arkyper::gpu_msm::{GPU_MSM, convert_bases_to_gpu, convert_scalars_to_bigint}; + use dp_crypto::arkyper::{HyperKZGProverKey, HyperKZGSRS}; use std::sync::Arc; /// MSM with 53-bit scalars (typical for polynomial evaluations from fix_var). @@ -86,9 +86,9 @@ mod gpu_msm_bitlength { #[divan::bench_group(sample_count = 5, sample_size = 1)] mod cpu_msm_bitlength { use super::*; - use ark_ec::VariableBaseMSM; use ark_bn254::{Bn254, G1Projective}; - use dp_crypto::arkyper::{HyperKZGSRS, HyperKZGProverKey}; + use ark_ec::VariableBaseMSM; + use dp_crypto::arkyper::{HyperKZGProverKey, HyperKZGSRS}; #[divan::bench(args = SIZES)] fn msm_53bit_scalars(b: Bencher, log_n: usize) { @@ -100,9 +100,7 @@ mod cpu_msm_bitlength { let bases = &pk.g1_powers()[..n]; let scalars = generate_small_scalars(n, 53, &mut rng); - b.bench_local(|| { - G1Projective::msm(bases, &scalars).expect("CPU MSM failed") - }) + b.bench_local(|| G1Projective::msm(bases, &scalars).expect("CPU MSM failed")) } #[divan::bench(args = SIZES)] @@ -115,8 +113,6 @@ mod cpu_msm_bitlength { let bases = &pk.g1_powers()[..n]; let scalars: Vec = (0..n).map(|_| Fr::rand(&mut rng)).collect(); - b.bench_local(|| { - G1Projective::msm(bases, &scalars).expect("CPU MSM failed") - }) + b.bench_local(|| G1Projective::msm(bases, &scalars).expect("CPU MSM failed")) } } diff --git a/dp-crypto/benches/pcs.rs b/dp-crypto/benches/pcs.rs index ec3ac78..2621d2d 100644 --- a/dp-crypto/benches/pcs.rs +++ b/dp-crypto/benches/pcs.rs @@ -6,12 +6,12 @@ use ark_poly::DenseMultilinearExtension; use ark_poly_commit::multilinear_pc::MultilinearPC; use ark_std::rand::thread_rng; use divan::Bencher; +#[cfg(feature = "cuda")] +use dp_crypto::arkyper::HyperKZGGpu; use dp_crypto::{ arkyper::{CommitmentScheme, HyperKZG}, poly::{dense::DensePolynomial as ADensePolynomial, slice::SmartSlice}, }; -#[cfg(feature = "cuda")] -use dp_crypto::arkyper::HyperKZGGpu; #[allow(unused_imports)] use jolt_core::poly::{ commitment::{ @@ -68,7 +68,10 @@ mod commit { fn arkyper_gpu_commit(b: Bencher, n: usize) { b.with_inputs(|| { let evals = arkworks_static_evals(2u32.pow(n as u32) as usize); - (evals, HyperKZGGpu::::test_setup(&mut thread_rng(), n)) + ( + evals, + HyperKZGGpu::::test_setup(&mut thread_rng(), n), + ) }) .bench_local_values(|(s, (pp, _))| { let poly = ADensePolynomial::new(s); @@ -83,7 +86,10 @@ mod commit { let polys = (0..NUM_BATCHED_POLYS) .map(|_| ADensePolynomial::new(arkworks_static_evals(2u32.pow(n as u32) as usize))) .collect::>(); - (polys, HyperKZGGpu::::test_setup(&mut thread_rng(), n)) + ( + polys, + HyperKZGGpu::::test_setup(&mut thread_rng(), n), + ) }) .bench_local_values(|(polys, (pp, _))| { HyperKZGGpu::::batch_commit(&pp, &polys).unwrap() @@ -196,8 +202,8 @@ mod commit { mod open { use ark_bn254::Fr; use ark_ff::AdditiveGroup; - use dp_crypto::arkyper::transcript::blake3::Blake3Transcript; use dp_crypto::arkyper::transcript::Transcript; + use dp_crypto::arkyper::transcript::blake3::Blake3Transcript; #[allow(unused_imports)] use jolt_core::field::JoltField; #[allow(unused_imports)] diff --git a/dp-crypto/examples/hyperkzg_gpu.rs b/dp-crypto/examples/hyperkzg_gpu.rs index 314f776..8146b0f 100644 --- a/dp-crypto/examples/hyperkzg_gpu.rs +++ b/dp-crypto/examples/hyperkzg_gpu.rs @@ -6,12 +6,12 @@ //! ``` use ark_bn254::{Bn254, Fr}; -use ark_std::rand::SeedableRng; use ark_std::UniformRand; +use ark_std::rand::SeedableRng; use dp_crypto::{ arkyper::{ - transcript::blake3::Blake3Transcript, CommitmentScheme, HyperKZG, HyperKZGGpu, - HyperKZGGpuProverKey, HyperKZGSRS, + CommitmentScheme, HyperKZG, HyperKZGGpu, HyperKZGGpuProverKey, HyperKZGSRS, + transcript::blake3::Blake3Transcript, }, poly::dense::DensePolynomial, }; @@ -66,7 +66,10 @@ fn main() -> anyhow::Result<()> { println!(" GPU commit time: {:?}", gpu_commit_time); // Verify they match - assert_eq!(cpu_commitment.0, gpu_commitment.0, "Commitments should match!"); + assert_eq!( + cpu_commitment.0, gpu_commitment.0, + "Commitments should match!" + ); println!(" Commitments match!"); println!( " Speedup: {:.2}x\n", @@ -99,7 +102,11 @@ fn main() -> anyhow::Result<()> { println!(" GPU batch commit time: {:?}", gpu_batch_time); // Verify they match - for (i, ((cpu_c, _), (gpu_c, _))) in cpu_commitments.iter().zip(gpu_commitments.iter()).enumerate() { + for (i, ((cpu_c, _), (gpu_c, _))) in cpu_commitments + .iter() + .zip(gpu_commitments.iter()) + .enumerate() + { assert_eq!(cpu_c.0, gpu_c.0, "Commitment {} should match!", i); } println!(" All {} commitments match!", num_polys); diff --git a/dp-crypto/src/arkyper/gpu_msm.rs b/dp-crypto/src/arkyper/gpu_msm.rs index 2bb5e76..ba7a516 100644 --- a/dp-crypto/src/arkyper/gpu_msm.rs +++ b/dp-crypto/src/arkyper/gpu_msm.rs @@ -4,9 +4,7 @@ use ark_bn254::{Fq, Fr, G1Affine, G1Projective}; use ark_ec::AffineRepr; use ark_ff::PrimeField; use ec_gpu::arkworks_bn254::G1Affine as GpuG1Affine; -use ec_gpu_gen::{ - program, rust_gpu_tools::Device, threadpool::Worker, G1AffineM, MultiexpKernel, -}; +use ec_gpu_gen::{G1AffineM, MultiexpKernel, program, rust_gpu_tools::Device, threadpool::Worker}; use rayon::prelude::*; pub static GPU_MSM: std::sync::LazyLock> = @@ -88,7 +86,6 @@ impl GpuMsm { } Ok(results) } - } fn fq_to_montgomery_bytes(x: &Fq) -> [u8; 32] { diff --git a/dp-crypto/src/arkyper/hyperkzg_gpu.rs b/dp-crypto/src/arkyper/hyperkzg_gpu.rs index ddfa8d4..272cc2d 100644 --- a/dp-crypto/src/arkyper/hyperkzg_gpu.rs +++ b/dp-crypto/src/arkyper/hyperkzg_gpu.rs @@ -432,8 +432,11 @@ pub fn gpu_batch_commit( results[idx] = r; } } - tracing::trace!("[gpu_batch_commit] CPU fallback: {} polys, {:.1}ms", - cpu_poly_count, t_cpu.elapsed().as_secs_f64() * 1000.0); + tracing::trace!( + "[gpu_batch_commit] CPU fallback: {} polys, {:.1}ms", + cpu_poly_count, + t_cpu.elapsed().as_secs_f64() * 1000.0 + ); } // Join GPU results @@ -449,8 +452,11 @@ pub fn gpu_batch_commit( Ok(()) })?; - tracing::trace!("[gpu_batch_commit] TOTAL: {:.1}ms ({} polys)", - overall_start.elapsed().as_secs_f64() * 1000.0, polys.len()); + tracing::trace!( + "[gpu_batch_commit] TOTAL: {:.1}ms ({} polys)", + overall_start.elapsed().as_secs_f64() * 1000.0, + polys.len() + ); Ok(results) } diff --git a/dp-crypto/src/arkyper/mock.rs b/dp-crypto/src/arkyper/mock.rs new file mode 100644 index 0000000..3c1bd25 --- /dev/null +++ b/dp-crypto/src/arkyper/mock.rs @@ -0,0 +1,148 @@ +use ark_std::rand::{Rng, RngCore}; +use ark_std::vec; +use std::{borrow::Borrow, fmt::Debug}; + +use crate::{ + arkyper::{CommitmentScheme, Transcript, transcript::AppendToTranscript}, + poly::dense::DensePolynomial, +}; + +#[derive(Clone, Debug, Default)] +pub struct MockCommitmentScheme { + _marker: std::marker::PhantomData, +} + +impl AppendToTranscript for () { + fn append_to_transcript(&self, _transcript: &mut ProofTranscript) { + } +} + +impl CommitmentScheme for MockCommitmentScheme { + type Field = F; + type ProverSetup = (); + type VerifierSetup = (); + type Commitment = (); + type Proof = (); + type BatchedProof = (); + type OpeningProofHint = (); + + fn test_setup( + _: &mut R, + _: usize, + ) -> (Self::ProverSetup, Self::VerifierSetup) { + ((), ()) + } + + fn commit( + _: &Self::ProverSetup, + _: &DensePolynomial, + ) -> anyhow::Result<(Self::Commitment, Self::OpeningProofHint)> { + Ok(((), ())) + } + + fn batch_commit<'a, U>( + _: &Self::ProverSetup, + _: &[U], + ) -> anyhow::Result> + where + U: Borrow> + Sync, + { + Ok(vec![((), ()); 0]) + } + + fn combine_commitments>( + _: &[C], + _: &[Self::Field], + ) -> anyhow::Result { + Ok(()) + } + + fn combine_hints(_: Vec, _: &[Self::Field]) -> Self::OpeningProofHint {} + + fn prove( + _: &Self::ProverSetup, + _: &DensePolynomial, + _: &[Self::Field], + _: Option, + _: &mut ProofTranscript, + ) -> anyhow::Result { + Ok(()) + } + + fn verify( + _: &Self::VerifierSetup, + _: &Self::Proof, + _: &mut ProofTranscript, + _: &[Self::Field], + _: &Self::Field, + _: &Self::Commitment, + ) -> anyhow::Result<()> { + Ok(()) + } + + fn protocol_name() -> &'static [u8] { + b"MockCommitmentScheme" + } +} +#[cfg(test)] +mod tests { + use crate::arkyper::transcript::blake3; + + use super::*; + use ark_bn254::Fr as F; + use ark_ff::Field; + use ark_std::rand::thread_rng; + + #[test] + fn test_mock_commitment_scheme() { + let mut rng = thread_rng(); + let (prover_setup, verifier_setup) = MockCommitmentScheme::::test_setup(&mut rng, 0); + let polynomial = DensePolynomial::new( + vec![1, 2, 3, 4] + .into_iter() + .map(F::from) + .collect::>(), + ); + + // Test commit + let (commitment, hint) = + MockCommitmentScheme::::commit(&prover_setup, &polynomial).unwrap(); + + // Test batch_commit + let _batch_commitments = + MockCommitmentScheme::::batch_commit(&prover_setup, &[&polynomial]).unwrap(); + + // Test combine_commitments + let _combined_commitment = + MockCommitmentScheme::::combine_commitments(&[&commitment], &[F::ONE]).unwrap(); + + // Test combine_hints + let combined_hint = MockCommitmentScheme::::combine_hints(vec![hint], &[F::ONE]); + + let mut transcript = blake3::Blake3Transcript::new(b"test"); + // Test prove + let proof = MockCommitmentScheme::::prove( + &prover_setup, + &polynomial, + &[F::ONE], + Some(combined_hint), + &mut transcript, + ) + .unwrap(); + + // Test verify + let verify_result = MockCommitmentScheme::::verify( + &verifier_setup, + &proof, + &mut transcript, + &[F::ONE], + &F::ONE, + &commitment, + ); + assert!(verify_result.is_ok()); + + // Test protocol_name + let name = MockCommitmentScheme::::protocol_name(); + assert_eq!(name, b"MockCommitmentScheme"); + } +} diff --git a/dp-crypto/src/arkyper/mod.rs b/dp-crypto/src/arkyper/mod.rs index 2183cdb..8f58069 100644 --- a/dp-crypto/src/arkyper/mod.rs +++ b/dp-crypto/src/arkyper/mod.rs @@ -31,6 +31,7 @@ pub mod gpu_msm; pub mod hyperkzg_gpu; #[cfg(feature = "cuda")] pub use hyperkzg_gpu::{HyperKZGGpu, HyperKZGGpuProverKey, HyperKZGGpuSRS, gpu_setup}; +pub mod mock; /// Mutex to serialize GPU tests. GPU operations are not thread-safe across /// multiple test threads because they share global GPU state (lazy statics diff --git a/dp-crypto/src/poly/dense.rs b/dp-crypto/src/poly/dense.rs index c7e7bc1..d51db29 100644 --- a/dp-crypto/src/poly/dense.rs +++ b/dp-crypto/src/poly/dense.rs @@ -104,7 +104,10 @@ impl<'a, F: Field> DensePolynomial<'a, F> { } } - pub fn shallow_clone<'b>(&'a self) -> DensePolynomial<'b, F> where 'a: 'b { + pub fn shallow_clone<'b>(&'a self) -> DensePolynomial<'b, F> + where + 'a: 'b, + { Self { num_vars: self.num_vars, len: self.len, diff --git a/dp-crypto/src/poly/slice.rs b/dp-crypto/src/poly/slice.rs index e93239c..f569729 100644 --- a/dp-crypto/src/poly/slice.rs +++ b/dp-crypto/src/poly/slice.rs @@ -34,7 +34,10 @@ impl<'a, T> Default for SmartSlice<'a, T> { impl<'a, T> SmartSlice<'a, T> { /// Returns a SmartSlice that borrows from the current smart slice. /// It panics if the smart slice is a mutable borrowed slice. - pub fn as_borrow<'b>(&'a self) -> SmartSlice<'b,T> where 'a: 'b { + pub fn as_borrow<'b>(&'a self) -> SmartSlice<'b, T> + where + 'a: 'b, + { match self { SmartSlice::Borrowed(slice) => SmartSlice::Borrowed(slice), SmartSlice::Owned(vec) => SmartSlice::Borrowed(vec.as_slice()),