On an A100
server from lambda labs, this zk light client can verify a committee update and step in ~97 seconds
.
Note
I was able to solve a serious performance issue by using from_uncompressed_unchecked
instead of from_uncompressed
. 📈
This is still secure since the pubkeys are public inputs. ⛓
If you are a developer note that in cases where the pubkeys are private inputs this would be problematic! ⛓️💥
Risc0
does not have a precompile for bls12_381
but to my surprise it generally seems to be faster than SP1
with respect to both hashing and ECC
arithmetic. I was reassured that Risc0
will receive a precompile for bls12_381
SOON ⏱.
Benchmarks for both Risc0
and SP1
will be added to this README SOON ⏳!
Note
The original Halo2 implementation of Spectre is located at Chainsafe
.
This implementation of Spectre leverages ZKVMs like Risc0 for increased performance and groth16 support.
Spectre is a trust minimized light-client for Ethereum
. With Spectre it is possible to cryptographically verify the integrity of Ethereum state root
.
Lightclients are essentially cryptographic infrastructure that make all queries to a blockchain verifiable and therefore enhance security.
Without lightclients the development of secure decentralized applications would be challenging since they would have to query many nodes rather than
relying a single source of truth. Additionally there would be no way to verify the integrity of the state transitions even when querying a large number
of nodes.
TLDR; Spectre makes blockchain queries secure by proving that the state is valid through cryptography(ZK).
iso-*
: Raw Rust implementation of a Spectre component in Isolation. Example: committee-iso
for the CommitteeUpdateCircuit
logic.
circuit/rz-*
: Risc0 circuit implementation of an iso
component.
circuit/sp1-*
: SP1 circuit implementation of an iso
component.
prover
: A special crate that generates proofs using either of the circuits
. This crate will be extended to support verification on AlignedLayer
.
Benchmarking the Step and Committee Circuits on different machines in SP1 and Risc0
Device | Risc0 (sha2 precompile) Elapsed | SP1 (sha2 precompile) Elapsed |
---|---|---|
A100 (40GB) Lambda Labs, 30 core CPU | 29.50s | 40.51s |
Device | Risc0 (sha2 precompile) Elapsed | SP1 (sha2, bls12 precompile) Elapsed |
---|---|---|
A100 (40GB) Lambda Labs, 30 core CPU | 68.28s | 418.87s |
In ZKVMs we refer to public outputs as information committed to the journal
. Inputs can either be committed or kept a secret.
Input | Type |
---|---|
slot | int |
proposer_index | int |
parent_root | Vec |
state_root | Vec |
body_root | Vec |
Input | Type |
---|---|
Public Keys Compressed | [u8;49] |
Finalized Header | BeaconBlockHeader |
Sync Committee Branch | Vec<Vec> |
Output | Type |
---|---|
Finalized Block (Header) Root | [u8;32] |
Key Commitment | [u8;32] |
Input | Type |
---|---|
Aggregate Signature | [u8;32] |
Public Keys Uncompressed | Vec<[u8;96]> |
Participation bits | Vec |
Attested Header | BeaconBlockHeader |
Finalized Header | BeaconBlockHeader |
Execution Payload Root | Vec |
Execution Payload Branch | Vec<Vec> |
domain | [u8;32] |
Output | Type |
---|---|
Finalized Block (Header) Root | [u8;32] |
Key Commitment | [u8;32] |
Note
If the merkle proofs are valid
,
and the data was signed
by the committee,
and the root is unique
,
then the block is trusted
.
Prerequisites:
- Rust installation
- Risc0 toolchain
- Risc0 client
1.1.2
rzup install cargo-risczero <version>
Run this command:
cargo test --bin prover test_committee_circuit_risc0 -- --nocapture
-F metal
for metal acceleration (M2, M3 Macbooks)-F cuda
for cuda acceleration (NVIDIA GPUs)
Note
Running the step circuit in Risc0
only really makes sense on powerful hardware,
currently it takes 40 minutes on my M3 Max Macbook Pro.
SP1
does not have metal acceleration so therefore cuda
is recommended.
For Risc0
a strong Nvidia GPU or Rig should be better than the M3.
Make sure to specify the path to rotation_512.json
as an environment variable when running any of the integration tests that are related to the committee circuit.
Example:
export COMMITTEE_UPDATE_TEST_PATH="/Users/USERNAME/Desktop/spectre-rad/data/rotation_512.json"
Example output:
Compiling host v0.1.0 (/Users/chef/Desktop/spectre-rad/circuits/rz-committee/host)
Finished `dev` profile [optimized + debuginfo] target(s) in 0.95s
Running `target/debug/host`
Verified Committee Root: [25, 122, 75, 125, 192, 12, 117, 238, 92, 109, 3, 192, 224, 63, 84, 28, 196, 131, 90, 32, 180, 39, 160, 7, 188, 177, 162, 100, 181, 205, 38, 142]
Run this command:
cargo test --bin prover test_step_circuit_risc0 -- --nocapture
Make sure to specify the path to sync_step_512.json
as an environment variable when running any of the integration tests that are related to the step circuit.
Example:
see above
Use the -F metal
flag to enable metal
acceleration on MacOS, for example:
cargo test --bin prover test_step_circuit_risc0 --release -F metal
to run the accelerated step circuit
.
Test data for the circuit can be found in data/rotation_512.json
.
It contains a committee update for Beacon with 512
public keys, a merkle branch and the resulting root.
Integrations can be found in prover/integrations/*
. The first integration POC
for the Aligned Builders Hackathon can be found in prover/integrations/*
.
Note that this will only work for the Risc0
version(s) supported by Aligned. I will keep an eye on them and update the integration once support for 1.1.x
has arrived.
In the meantime performance optimizations in 1.1.x
are a priority.
Read more here.