Cryptography Precompiles
SP1's zkVM includes built-in precompiles for various cryptographic operations that dramatically reduce execution time and proving costs. These precompiles are specialized, highly-optimized circuits that execute directly within the zkVM.
To make these optimizations accessible, we provide "patched" versions of popular cryptography libraries. These patches automatically route operations through our precompiles, delivering significant performance improvements without requiring changes to your code besides adding the patched crate to your dependencies.
Patched Crates
If you know of a library or library version that you think should be patched, please open an SP1 issue!
Crate Name | Repository | Versions |
---|---|---|
sha2 | sha2-v0-10-8 = { git = "https://github.com/sp1-patches/RustCrypto-hashes", package = "sha2", tag = "patch-sha2-0.10.8-sp1-4.0.0" } | 0.9.9, 0.10.6, 0.10.8 |
sha3 | sha3-v0-10-8 = { git = "https://github.com/sp1-patches/RustCrypto-hashes", package = "sha3", tag = "patch-sha3-0.10.8-sp1-4.0.0" } | 0.10.8 |
bigint | crypto-bigint = { git = "https://github.com/sp1-patches/RustCrypto-bigint", tag = "patch-0.5.5-sp1-4.0.0" } | 0.5.5 |
tiny-keccak | tiny-keccak = { git = "https://github.com/sp1-patches/tiny-keccak", tag = "patch-2.0.2-sp1-4.0.0" } | 2.0.2 |
curve25519-dalek | curve25519-dalek = { git = "https://github.com/sp1-patches/curve25519-dalek", tag = "patch-4.1.3-sp1-4.0.0" } | 4.1.3 |
curve25519-dalek-ng | curve25519-dalek-ng = { git = "https://github.com/sp1-patches/curve25519-dalek-ng", tag = "patch-4.1.1-sp1-4.0.0" } | 4.1.1 |
k256 | k256 = { git = "https://github.com/sp1-patches/elliptic-curves", tag = "patch-k256-13.4-sp1-4.1.0" } | 13.4 |
p256 | p256 = { git = "https://github.com/sp1-patches/elliptic-curves", tag = "patch-p256-13.2-sp1-4.1.0" } | 13.2 |
secp256k1 | secp256k1 = { git = "https://github.com/sp1-patches/rust-secp256k1", tag = "patch-0.29.1-sp1-4.1.0" } | 0.29.1, 0.30.0 |
substrate-bn | substrate-bn = { git = "https://github.com/sp1-patches/bn", tag = "patch-0.6.0-sp1-4.0.0" } | 0.6.0 |
bls12_381 | bls12_381 = { git = "https://github.com/sp1-patches/bls12_381", tag = "patch-0.8.0-sp1-4.0.0-v2" } | 0.8.0 |
rsa | rsa = { git = "https://github.com/sp1-patches/RustCrypto-RSA", tag = "patch-0.9.6-sp1-4.0.0-v2" } | 0.9.6 |
Using Patched Crates
To use the patched libraries, you can use corresponding patch entries in your program's Cargo.toml
.
Ensure that you are using the correct patched version for your crate. For example, if you are using sha2
0.10.8
, you should use the patch-sha2-0.10.8-sp1-4.0.0
tag. If you are using sha2
0.10.6
, you should use the patch-sha2-0.10.6-sp1-4.0.0
tag.
Patching crates.io Dependencies
To patch p256
13.2
, you can add the following to your Cargo.toml
:
[dependencies]
p256 = "=13.2"
[patch.crates-io]
p256 = { git = "https://github.com/sp1-patches/elliptic-curves", package = "p256", tag = "patch-p256-13.2-sp1-4.1.0" }
Patching GitHub Dependencies
To patch p256
from GitHub, you need to specify the repository in the patch section. For example:
[dependencies]
p256 = { git = "https://github.com/sp1-patches/elliptic-curves", package = "p256" }
[patch."https://github.com/sp1-patches/elliptic-curves"]
p256 = { git = "https://github.com/sp1-patches/elliptic-curves", package = "p256", tag = "patch-p256-13.2-sp1-4.1.0" }
Confirming Patch Usage
To confirm that the patch is being applied, you can use the following command:
cargo tree -p p256
Next to the package name, it should have a link to the Github repository that you patched with:
p256 v13.2 (https://github.com/sp1-patches/elliptic-curves?tag=patch-p256-13.2-sp1-4.1.0)
├── ...
If you see multiple versions of the same crate or the patch has not applied, you can try updating the crate manually to use the version matching the patch tag:
cargo update -p p256 --precise 13.2
Example Usage in Programs
SP1 Blobstream and OP Succinct demonstrate how to use the patched crates in a program.
KZG Acceleration
We built an pure Rust alternative to c-kzg: kzg-rs, that
relies on our patched bls12_381
crate to significantly improves the performance of KZG operations.
You can enable it on revm
with the kzg-rs
feature.
Troubleshooting
Verifying Patch Application: Cargo
You can check if the patch was applied by using cargo's tree command to print the dependencies of the crate you patched.
cargo tree -p sha2@0.10.8
Next to the package name, it should have a link to the Github repository that you patched with.
Ex.
sha2 v0.10.8 (https://github.com/sp1-patches/RustCrypto-hashes?tag=patch-sha2-0.10.8-sp1-4.0.0)
├── ...
Verifying Patch Usage during Program Execution
To check if a precompile is used during the execution of your program with specific inputs, you can view SP1's ExecutionReport
, which is returned when executing a program with execute
. In ExecutionReport
you can view the syscall_counts
map to view if a specific syscall was used.
For example, if you wanted to check sha256
was used, you would look for SHA_EXTEND
and SHA_COMPRESS
in syscall_counts
.
An example of this is available in our Patch Testing Example.
Cargo Version Issues
If you encounter issues with version commits on your patches, you should try updating the patched crate manually.
cargo update -p <patch-crate-name>
If you encounter issues relating to cargo / git, you can try setting CARGO_NET_GIT_FETCH_WITH_CLI
:
CARGO_NET_GIT_FETCH_WITH_CLI=true cargo update -p <patch-crate-name>
You can permanently set this value in ~/.cargo/config
:
[net]
git-fetch-with-cli = true