<style>
.ui-content #doc.markdown-body, .ui-content .ui-infobar {
    max-width: 1280px;
}
</style>
# Benchmarks For Digital ID Wallet Project 
## High Level Requirements
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                                            |
## Target Circuit
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.
## Survey of Potential ZKP Solutions
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](https://github.com/0xPolygonZero/plonky2/tree/main) | [TurboPLONK + FRI](https://github.com/0xPolygonZero/plonky2/blob/main/plonky2/plonky2.pdf)     | $O(n \log n)$     | Rust API/[Noirky2](https://blog.eryx.co/2024/10/29/Noirky2-how-we-made-a-Plonky2-proving-backend-for-Noir.html)                                                | [No-lookup](https://github.com/polymerdao/plonky2-sha256/blob/main/src/circuit.rs); [No-lookup](https://github.com/proxima-one/plonky2/tree/merkle-stark/merkle-stark/src/sha256_stark); [No-lookup](https://github.com/JumpCrypto/plonky2-crypto/blob/main/src/hash/sha256.rs); [Noir cross-compile (no-lookup)](https://github.com/eryxcoop/acvm-backend-plonky2/blob/main/plonky2-backend/src/circuit_translation/sha256_translator.rs) | [PSE CSP (mobile-ready)](https://hackmd.io/@clientsideproving/B1xLCuJL5yg), [Celer (2023)](https://blog.celer.network/2023/08/04/the-pantheon-of-zero-knowledge-proof-development-frameworks/) |
| [Plonky3](https://github.com/Plonky3/Plonky3/tree/main)       | TurboPLONK + FRI                                                                               | $O(n \log n)$     | Rust API/[Lurk](https://github.com/lurk-lab/lurk)/[powdr(Rust)](https://docs.powdr.org/backends/plonky3.html)/[SP1(Rust)](https://github.com/succinctlabs/sp1) | [In powdr (no-lookup)](https://github.com/babybear-labs/benchmark/tree/main/powdr); [SP1 (uses precompiles?)](https://github.com/babybear-labs/benchmark/tree/main/sp1/algos/sha256)                                                                                                                                                                                     | [In powdr](https://github.com/babybear-labs/benchmark/tree/main/reports/powdr)                                                                                                                 |
| [STWO](https://github.com/starkware-libs/stwo)                | [CSTARK](https://eprint.iacr.org/2024/278)                                                     | $O(n \log n)$     | Rust API/[Cairo](https://github.com/starkware-libs/stwo-cairo?tab=readme-ov-file)                                                                              | [Cairo port of zkEmail, no-lookup](https://github.com/iosis-tech/zkemail-cairo/blob/main/sha256.cairo)                                                                                                                                                                                                                                                                                                                                     | Not found, but claimed to be ["1.1M CairoCPU cycles, provable with STWO in 6.5s"](https://x.com/bartolomeo_diaz/status/1888240222724354106)                                                    |
| [Polyhedra Expander](https://github.com/PolyhedraZK/Expander) | [Libra](https://eprint.iacr.org/2019/317) ([Orion](https://eprint.iacr.org/2022/1010.pdf) PCS) | $O(n)$            | Rust API/gnark                                                                                                                                                 | [Rust API](https://github.com/PolyhedraZK/proof-arena/blob/d29e6b369e4226f206b6c4a6e65808204fd8fc91/problems/sha256_hash/expander-sha256/src/main.rs); [gnark](https://github.com/MAYA-ZK/Gnark_on_Icicle_benchmarking/blob/main/sha256/sha256.go#L128)                                                                                                                                                                                    | [In Rust](https://proofarena.org/problems/3)                                                                                                                                                   |
| [Spartan + WHIR](https://github.com/worldfnd/ProveKit)                                                | [Spartan](https://eprint.iacr.org/2019/550)+[WHIR](https://eprint.iacr.org/2024/1586)          | $O(n)$            | [Noir](https://github.com/worldfnd/ProveKit)                                                                                                         | [ProveKit Example](https://github.com/worldfnd/ProveKit/tree/main/noir-examples/sha256)                                                                                                                                                                                                                                                                                                                                             | -                                                                                                                                                                    |
| [Binius](https://github.com/IrreducibleOSS/binius/tree/main)  | [Binius](https://eprint.iacr.org/2023/1784.pdf)                                                | ~$O(n)$           | Rust API                                                                                                                                                       | [With lookups](https://github.com/IrreducibleOSS/binius/blob/main/examples/sha256_circuit_with_lookup.rs); [without lookups](https://github.com/IrreducibleOSS/binius/blob/main/examples/sha256_circuit.rs)                                                                                                                                                                                                                                | [Official benchmark](https://www.binius.xyz/benchmarks/)                                                                                                                                       |
| Ligero                                                        | [Ligero](https://eprint.iacr.org/2022/1608)                                                    | $O(n \log n)$     | [C++ API???](https://github.com/scipr-lab/libiop?tab=readme-ov-file)                                                                                           | Not found, but [potentially usable one here](https://github.com/search?q=repo%3Ascipr-lab%2Flibsnark%20sha256&type=code)                                                                                                                                                                                                                                                                                                                   | ⚠️ The linked codebase is older than the recent version of the paper; There is a not-yet-opensourced impl from [Ligetron](https://platform.ligetron.com/marketplace);                          |
## Comparison Across Proof Systems
The benchmarks were measuring the performance of SHA256 circuits with 2048 B input (~33 SHA256 compressions[^2]), 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)](https://github.com/privacy-scaling-explorations/zkid-benchmarks/tree/main/binius)[^2]                                        | 1.8545 s     | 244.48 ms            | 475.6 KB   | 321.8 KB                                           | ~10.44 MB         | ~26.94 MB                   |
| [Binius (lookup)](https://github.com/privacy-scaling-explorations/zkid-benchmarks/tree/main/binius)[^2]                                           | 11.025 s     | 572.73 ms            | 1.8 MB     | 716.86 KB                                          | ~5.02 MB          | ~66.14 MB                   |
| [Plonky2 (no-lookup)](https://github.com/privacy-scaling-explorations/zkid-benchmarks/tree/main/plonky2)                                            | 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)](https://github.com/privacy-scaling-explorations/zkid-benchmarks/tree/main/plonky3-sp1)                  | 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)](https://github.com/privacy-scaling-explorations/zkid-benchmarks/tree/main/plonky3-powdr)                         | 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)](https://github.com/privacy-scaling-explorations/zkid-benchmarks/tree/main/stwo)                                          | 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*)](https://platform.ligetron.com/marketplace/project?id=78180426-2a09-4c36-ac68-52f1ab4ffbe6&version=1.0) | 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](https://github.com/privacy-scaling-explorations/zkid-benchmarks/tree/main/polyhedra-expander)                                                                                                                          |     70 s        |   26 s                   |  30.75 MB          |                                           6 GB (circuit)         |       N/A            |       15.55 GB                      |
[^1]: [Plonkish circuit example with lookups in STWO](https://github.com/starkware-libs/stwo/blob/dev/crates/prover/src/examples/plonk/mod.rs)
[^2]: Binius circuits only perform compressions but not full SHA256, so an actual full implementation would incur extra overhead