git-subtree-dir: vendor/ruvector git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
7.4 KiB
7.4 KiB
ZK Proof Optimization Quick Reference
Target Files:
/home/user/ruvector/examples/edge/src/plaid/zkproofs_prod.rs/home/user/ruvector/examples/edge/src/plaid/zk_wasm_prod.rs
🚀 Top 5 Performance Wins
1. Implement Batch Verification (70% gain) ⭐⭐⭐
Location: zkproofs_prod.rs:536
Current:
pub fn verify_batch(proofs: &[ZkRangeProof]) -> Vec<VerificationResult> {
// TODO: Implement batch verification
proofs.iter().map(|p| Self::verify(p).unwrap_or_else(...)).collect()
}
Optimized:
pub fn verify_batch(proofs: &[ZkRangeProof]) -> Result<Vec<VerificationResult>, String> {
// Group by bit size
let mut groups: HashMap<usize, Vec<&ZkRangeProof>> = HashMap::new();
for proof in proofs {
let bits = calculate_bits(proof.max - proof.min);
groups.entry(bits).or_insert_with(Vec::new).push(proof);
}
// Batch verify each group using Bulletproofs API
for (bits, group) in groups {
BulletproofRangeProof::verify_multiple(...)?;
}
}
Impact: 2.0-2.9x faster verification
2. Cache Point Decompression (20% gain) ⭐⭐⭐
Location: zkproofs_prod.rs:94
Current:
pub fn decompress(&self) -> Option<RistrettoPoint> {
CompressedRistretto::from_slice(&self.point).ok()?.decompress()
}
Optimized:
use std::cell::OnceCell;
#[derive(Debug, Clone)]
pub struct PedersenCommitment {
pub point: [u8; 32],
#[serde(skip)]
cached: OnceCell<RistrettoPoint>,
}
pub fn decompress(&self) -> Option<&RistrettoPoint> {
self.cached.get_or_init(|| {
CompressedRistretto::from_slice(&self.point)
.ok()?.decompress()?
}).as_ref()
}
Impact: 15-20% faster verification, 500-1000x for repeated access
3. Reduce Generator Memory (50% memory) ⭐⭐
Location: zkproofs_prod.rs:54
Current:
static ref BP_GENS: BulletproofGens = BulletproofGens::new(MAX_BITS, 16);
Optimized:
static ref BP_GENS: BulletproofGens = BulletproofGens::new(MAX_BITS, 1);
Impact: 16 MB → 8 MB (50% reduction), 14 MB smaller WASM binary
4. WASM Typed Arrays (3-5x serialization) ⭐⭐⭐
Location: zk_wasm_prod.rs:43
Current:
pub fn set_income(&mut self, income_json: &str) -> Result<(), JsValue> {
let income: Vec<u64> = serde_json::from_str(income_json)?;
// ...
}
Optimized:
use js_sys::Uint32Array;
#[wasm_bindgen(js_name = setIncomeTyped)]
pub fn set_income_typed(&mut self, income: &[u64]) {
self.inner.set_income(income.to_vec());
}
JavaScript:
// Instead of: prover.setIncome(JSON.stringify([650000, 650000, ...]))
prover.setIncomeTyped(new Uint32Array([650000, 650000, ...]));
Impact: 3-5x faster serialization
5. Parallel Bundle Generation (2.7x bundles) ⭐⭐
Location: New method in zkproofs_prod.rs
Add:
use rayon::prelude::*;
impl RentalApplicationBundle {
pub fn create_parallel(
prover: &mut FinancialProver,
rent: u64,
income_multiplier: u64,
stability_days: usize,
savings_months: Option<u64>,
) -> Result<Self, String> {
// Pre-generate blindings sequentially
let keys = vec!["affordability", "no_overdraft"];
let blindings: Vec<_> = keys.iter()
.map(|k| prover.get_or_create_blinding(k))
.collect();
// Generate proofs in parallel
let proofs: Vec<_> = vec![
("affordability", || prover.prove_affordability(rent, income_multiplier)),
("stability", || prover.prove_no_overdrafts(stability_days)),
]
.into_par_iter()
.map(|(_, proof_fn)| proof_fn())
.collect::<Result<Vec<_>, _>>()?;
// ... assemble bundle
}
}
Impact: 2.7x faster bundle creation (4 cores)
📊 Performance Targets
| Operation | Current | Optimized | Gain |
|---|---|---|---|
| Single proof (32-bit) | 20 ms | 15 ms | 25% |
| Bundle (3 proofs) | 60 ms | 22 ms | 2.7x |
| Verify single | 1.5 ms | 1.2 ms | 20% |
| Verify batch (10) | 15 ms | 5 ms | 3x |
| WASM call overhead | 30 μs | 8 μs | 3.8x |
| Memory (generators) | 16 MB | 8 MB | 50% |
🔧 Implementation Checklist
Phase 1: Quick Wins (2 days)
- Reduce generator to
party=1 - Implement point decompression caching
- Add batch verification skeleton
- Run benchmarks to establish baseline
Phase 2: Batch Verification (3 days)
- Implement
verify_multiplewrapper - Group proofs by bit size
- Handle mixed bit sizes
- Add tests for batch verification
- Benchmark improvement
Phase 3: WASM Optimization (2 days)
- Add typed array input methods
- Implement bincode serialization option
- Add lazy encoding for outputs
- Test in browser environment
- Measure actual WASM performance
Phase 4: Parallelization (3 days)
- Add rayon dependency
- Implement parallel bundle creation
- Implement parallel batch verification
- Add thread pool configuration
- Benchmark with different core counts
📈 Benchmarking Commands
# Run all benchmarks
cd /home/user/ruvector/examples/edge
cargo bench --bench zkproof_bench
# Run specific benchmark
cargo bench --bench zkproof_bench -- "proof_generation"
# Profile with flamegraph
cargo flamegraph --bench zkproof_bench
# WASM size
wasm-pack build --release --target web
ls -lh pkg/*.wasm
# Browser performance
# In devtools console:
performance.mark('start');
await prover.proveIncomeAbove(500000);
performance.mark('end');
performance.measure('proof', 'start', 'end');
🐛 Common Pitfalls
❌ Don't: Clone scalars unnecessarily
let blinding = self.blindings.get("key").unwrap().clone(); // Bad
✅ Do: Use references
let blinding = self.blindings.get("key").unwrap(); // Good
❌ Don't: Allocate without capacity
let mut vec = Vec::new();
vec.push(data); // Bad
✅ Do: Pre-allocate
let mut vec = Vec::with_capacity(expected_size);
vec.push(data); // Good
❌ Don't: Convert to JSON in WASM
serde_json::to_string(&proof) // Bad: 2-3x slower
✅ Do: Use bincode or serde-wasm-bindgen
bincode::serialize(&proof) // Good: Binary format
🔍 Profiling Hotspots
Expected Time Distribution (Before Optimization)
Proof Generation (20ms total):
- Bulletproof generation: 85% (17ms)
- Blinding factor: 5% (1ms)
- Commitment creation: 5% (1ms)
- Transcript ops: 2% (0.4ms)
- Metadata/hashing: 3% (0.6ms)
Verification (1.5ms total):
- Bulletproof verify: 70% (1.05ms)
- Point decompression: 15% (0.23ms) ← Optimize this
- Transcript recreation: 10% (0.15ms)
- Metadata checks: 5% (0.08ms)
📚 References
- Full analysis:
/home/user/ruvector/examples/edge/docs/zk_performance_analysis.md - Benchmarks:
/home/user/ruvector/examples/edge/benches/zkproof_bench.rs - Bulletproofs crate: https://docs.rs/bulletproofs
- Dalek cryptography: https://doc.dalek.rs/
💡 Advanced Optimizations (Future)
- Aggregated Proofs: Combine multiple range proofs into one
- Proof Compression: Use zstd on proof bytes (30-40% smaller)
- Pre-computed Tables: Cache common range generators
- SIMD Operations: Use AVX2 for point operations (dalek already does this)
- GPU Acceleration: MSMs for batch verification (experimental)
Last Updated: 2026-01-01