The zero-knowledge proof (ZKP) scheme that will be used in Digital ID Wallet (DIW) should meet the following requirements:
Requirement | Rationale |
---|---|
No trusted setup / long structured reference string | Fewer security assumptions and less mobile bandwidth usage |
Overall low bandwidth usage | Mobile device limitations |
Recursive proving | Offline verifiable presentation generation capability |
Fast proving | Mobile device limitations |
Post-quantum soundness | Future-proofing |
The credential issuer should sign a SHA256 hash of a JSON web token (JWT) containing the credential attributes. Therefore, SHA256 is a good target circuit and an assumed performance bottleneck of the per-issuance proof.
The ZKP schemes in the table below are plausibly post-quantum sound and do not require trusted setup.
Solutions | ZKP Scheme | Prover Complexity | Frontend | Existing SHA256 Implementations | Existing Benchmarks |
---|---|---|---|---|---|
Plonky2 | TurboPLONK + FRI | \(O(n \log n)\) | Rust API/Noirky2 | No-lookup; No-lookup; No-lookup; Noir cross-compile (no-lookup) | PSE CSP (mobile-ready), Celer (2023) |
Plonky3 | TurboPLONK + FRI | \(O(n \log n)\) | Rust API/Lurk/powdr(Rust)/SP1(Rust) | In powdr (no-lookup); SP1 (uses precompiles?) | In powdr |
STWO | CSTARK | \(O(n \log n)\) | Rust API/Cairo | Cairo port of zkEmail, no-lookup | Not found, but claimed to be "1.1M CairoCPU cycles, provable with STWO in 6.5s" |
Polyhedra Expander | Libra (Orion PCS) | \(O(n)\) | Rust API/gnark | Rust API; gnark | In Rust |
Spartan + WHIR | Spartan+WHIR | \(O(n)\) | Noir | ProveKit Example | - |
Binius | Binius | ~\(O(n)\) | Rust API | With lookups; without lookups | Official benchmark |
Ligero | Ligero | \(O(n \log n)\) | C++ API??? | Not found, but potentially usable one here | ⚠️ The linked codebase is older than the recent version of the paper; There is a not-yet-opensourced impl from Ligetron; |
The benchmarks were measuring the performance of SHA256 circuits with 2048 B input (~33 SHA256 compressions[1]), with the exception of Polyhedra Expander circuit (1024 B input). Measured on Apple M2 Air laptop.
Circuit (GitHub link) | Proving Time | Verification Time | Proof Size | Preprocessing Size | Preprocessing RAM | Prover RAM |
---|---|---|---|---|---|---|
Binius (no-lookup)[1:1] | 1.8545 s | 244.48 ms | 475.6 KB | 321.8 KB | ~10.44 MB | ~26.94 MB |
Binius (lookup)[1:2] | 11.025 s | 572.73 ms | 1.8 MB | 716.86 KB | ~5.02 MB | ~66.14 MB |
Plonky2 (no-lookup) | 20.138 s | 5.3135 ms | 175.6 KB | 2.28 GB (prover-only data) + 1.06 KB (common data) | ~2.74 GB | ~2.40 GB |
Plonky3 (SP1 w/precompile) | 12.596 s | 184.11 ms | 1.72 MB | 156.34 MB (PK) + 90.76 KB (ELF) | ~1 GB | ~5 GB |
Plonky3 (powdr, no precompile) | 20.741 s | 256.11 ms | 1.93 MB | 3.1 GB (proving key) + 321 MB (constants) | ~3.87 GB | ~0.32 GB |
STWO (Cairo) | 21.1 s | N/A (verifier error) | 39.5 MB | 12.6 MB (trace) + 3.4 Mb (memory) | ~600 MB | ~10GB |
Ligero (Ligetron, uses WebGPU) | 12.06 s | 9.16 s | 10.29 MB | 33KB (prover data) | N/A | ~500 MB VRAM + ~30 MB RAM |
Polyhedra Expander (Orion + GF2), 1kB input | 70 s | 26 s | 30.75 MB | 6 GB (circuit) | N/A | 15.55 GB |