https://github.com/ReamLabs/consensp1us
(My **etude** for PoC)
I've been working on a PoC (Proof-of-Concept) project that "snarkifies" the current Ethereum beacon chain processor. Since [SP1](https://docs.succinct.xyz/docs/introduction) offers an excellent developer experience, I began by exploring SP1. Succinct Labs also recommends using [Precompiles](https://docs.succinct.xyz/docs/writing-programs/precompiles) for common operations (e.g., hash functions, arithmetic on elliptic curves) including [bls12_381](https://github.com/sp1-patches/bls12_381). I thought leveraging these with [Lighthouse](https://github.com/sigp/lighthouse) would be a great way to deepen my understanding of zkVM's core concepts.
This article documents my short journey hacking with SP1 and Lighthouse.
## Adding a new backend: `bls12_381`
https://github.com/syjn99/lighthouse/pull/1
Lighthouse supports adding new "backends" for BLS ([`crypto/bls/src/lib.rs`](https://github.com/sigp/lighthouse/blob/0d90135047519f4c2ee586d50e560f7bb2ff9b10/crypto/bls/src/lib.rs#L1-L18)). My first step was implementing a new backend using `zkcrypto/bls12_381`. As `bls12_381` provides a more **raw** API, I first had to study the basic concepts of BLS12-381.
https://x.com/junsong_eth/status/1878036588191793288
It worked: the backend changes passed all pre-written unit tests in Lighthouse. Now, we can also use the patched `bls12_381` from SP1, as its implementation is mostly the same.
## Dependency issues
https://github.com/sigp/lighthouse/blob/stable/consensus/types/Cargo.toml
To implement a beacon processor in my project, I needed to import the `types` crate from Lighthouse. This crate itself comes with numerous dependencies.
The process would have been straightforward if 1) all libraries were written in Rust, and 2) all supported RISC-V compilation. However, I encountered several crates that didn't meet these conditions. Here's how I addressed the issues:
- **`ethereum_hashing`**: This crate uses `ring`, but it supports a `sha2` backend written in pure Rust. I replaced it: https://github.com/syjn99/ethereum_hashing/tree/sha2-version → This worked!
- **`rusqlite`**: It seemed I/O functionality was not working, so I removed the `rusqlite` dependency: https://github.com/syjn99/lighthouse/commit/f74de5df2eb78d0beeb4905e82daef0489883a48 → This also worked!
- **`alloy-primitives` (v0.8.15)**: This crate depends on `proptest`, which in turn depends on `rusty-fork`, and `rusty-fork` relies on `wait-timeout`. The issue arises with `wait-timeout`, causing a compilation error due to unimplemented functionality:
- Problematic line: https://github.com/alexcrichton/wait-timeout/blob/2a4f0f2e85768735575558b0e97e6c35df815e97/src/lib.rs#L68
- `proptest-derive` generates the `Arbitrary` trait for all primitives, but I haven't fully grasped the structure of `alloy-rs/core`, so I didn't investigate further.
- **`c-kzg`**: KZG was the last dependency blocking my project. [`rust-kzg`](https://github.com/grandinetech/rust-kzg) is a great project that provides a "drop-in replacement" for [`c-kzg-4844`](https://github.com/ethereum/c-kzg-4844).
- However, the replacement only works with version `>= 2`. Currently, Lighthouse uses `v1.0.3`, making it incompatible.
- Modularizing and diversifying the backend could solve this issue, such as supporting `rust-kzg-blst`, but this would involve significant effort.
## Conclusion
I spent a considerable amount of time resolving dependency issues, mainly due to compatibility challenges with the RISC-V ISA. Here are my suggestions for future projects:
- Design programs running on zkVM to be as lightweight as possible.
- Avoid external crates that bind to languages other than Rust. There are plenty of Rust-based crypto crates that offer better performance.
- Verify that newly added dependencies are compatible with RISC-V before integrating them.