git-subtree-dir: vendor/ruvector git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
319 lines
7.4 KiB
Markdown
319 lines
7.4 KiB
Markdown
# 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:**
|
|
```rust
|
|
pub fn verify_batch(proofs: &[ZkRangeProof]) -> Vec<VerificationResult> {
|
|
// TODO: Implement batch verification
|
|
proofs.iter().map(|p| Self::verify(p).unwrap_or_else(...)).collect()
|
|
}
|
|
```
|
|
|
|
**Optimized:**
|
|
```rust
|
|
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:**
|
|
```rust
|
|
pub fn decompress(&self) -> Option<RistrettoPoint> {
|
|
CompressedRistretto::from_slice(&self.point).ok()?.decompress()
|
|
}
|
|
```
|
|
|
|
**Optimized:**
|
|
```rust
|
|
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:**
|
|
```rust
|
|
static ref BP_GENS: BulletproofGens = BulletproofGens::new(MAX_BITS, 16);
|
|
```
|
|
|
|
**Optimized:**
|
|
```rust
|
|
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:**
|
|
```rust
|
|
pub fn set_income(&mut self, income_json: &str) -> Result<(), JsValue> {
|
|
let income: Vec<u64> = serde_json::from_str(income_json)?;
|
|
// ...
|
|
}
|
|
```
|
|
|
|
**Optimized:**
|
|
```rust
|
|
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:**
|
|
```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:**
|
|
```rust
|
|
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_multiple` wrapper
|
|
- [ ] 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
|
|
|
|
```bash
|
|
# 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
|
|
```rust
|
|
let blinding = self.blindings.get("key").unwrap().clone(); // Bad
|
|
```
|
|
|
|
### ✅ Do: Use references
|
|
```rust
|
|
let blinding = self.blindings.get("key").unwrap(); // Good
|
|
```
|
|
|
|
---
|
|
|
|
### ❌ Don't: Allocate without capacity
|
|
```rust
|
|
let mut vec = Vec::new();
|
|
vec.push(data); // Bad
|
|
```
|
|
|
|
### ✅ Do: Pre-allocate
|
|
```rust
|
|
let mut vec = Vec::with_capacity(expected_size);
|
|
vec.push(data); // Good
|
|
```
|
|
|
|
---
|
|
|
|
### ❌ Don't: Convert to JSON in WASM
|
|
```rust
|
|
serde_json::to_string(&proof) // Bad: 2-3x slower
|
|
```
|
|
|
|
### ✅ Do: Use bincode or serde-wasm-bindgen
|
|
```rust
|
|
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)
|
|
|
|
1. **Aggregated Proofs**: Combine multiple range proofs into one
|
|
2. **Proof Compression**: Use zstd on proof bytes (30-40% smaller)
|
|
3. **Pre-computed Tables**: Cache common range generators
|
|
4. **SIMD Operations**: Use AVX2 for point operations (dalek already does this)
|
|
5. **GPU Acceleration**: MSMs for batch verification (experimental)
|
|
|
|
---
|
|
|
|
**Last Updated:** 2026-01-01
|