portable, composable, deterministic WASM verification runtime for Ethereum proofs

$ curl -L runt.eth.limo/runt -o runt

~16 MB static binary · linux x86_64 · MIT licensed

$ cat README.md

Runt is a WASM runtime that loads pluggable proof verifiers. Each verifier is a tiny .wasm module exporting a standard C ABI: metadata() and verify(). The host provides native crypto (keccak256, BLS, BN254 pairings) through import functions. Everything runs sandboxed, fuel-metered, deterministic.

5 verifiers. 748 bytes to 32 KB each. Portable anywhere WASM runs — browsers, servers, edge, even inside other blockchains.

$ runt list
WASM modules loaded: 5
Verifiers registered: 5

  state:eip1186     v0.1.0 (mpt)       EIP-1186 Merkle Patricia Trie state proof
  tx:receipt        v0.1.0 (mpt)       Transaction receipt inclusion proof
  consensus:altair  v0.1.0 (sync-comm) Altair sync committee light client
  groth16:bn254     v0.1.0 (groth16)   BN254 Groth16 zero-knowledge proof
  hello:dummy       v0.1.0 (dummy)     Hello-world verifier for testing
$ runt verify --proof-type state:eip1186 --proof-file proof.bin
status: VALID
time: 246.79µs
$ cat ARCHITECTURE.md

Every verifier is a plain .wasm module exporting two functions:

// Write JSON metadata to buf, return bytes written
u32 metadata(u8* buf, u32 buf_len);

// Verify a proof. Returns 0=valid, 1=invalid, 2=error
u32 verify(
    u8* proof, u32 proof_len,
    u8* public_inputs, u32 public_inputs_len,
    u8* error_buf, u32 error_buf_len
);

Verifiers import host functions for native crypto:

// keccak256, sha256, blake2b
void host_hash(u32 algorithm, u8* input, u32 input_len, u8* output);

// BLS12-381, secp256k1, ed25519
u32 host_verify_signature(u32 scheme, u8* msg, u32 msg_len,
                          u8* sig, u32 sig_len, u8* pk, u32 pk_len);

// BN254 pairings for Groth16
u32 host_pairing_check(u32 curve, u8* pairs, u32 pairs_len);
$ tree -L 2
runt/
├── runt-abi/          C ABI constants shared between host and verifiers
├── runt-core/         wasmtime engine config, fuel metering, sandboxing
├── runt-host/         verifier registry, loader, crypto providers, routing
├── runt-cli/          command-line interface
├── runt-demo/         live proof generation and verification tool
├── runt-verifiers/    WASM modules implementing the verifier C ABI
│   ├── hello-verifier/
│   ├── state-verifier/
│   ├── tx-verifier/
│   ├── consensus-verifier/
│   └── groth16-verifier/
└── runt-test-vectors/ test fixtures for integration tests
$ make
# build the host + cli
cargo build --workspace

# build all 5 verifier .wasm modules
make verifiers

# list loaded verifiers
runt list

# run 18 integration tests
make test
$ cat ADDING_A_VERIFIER.md

Drop a .wasm file into target/verifiers/ and it auto-registers:

# create a new verifier
cargo build --target wasm32-unknown-unknown --release -p my-verifier
cp target/wasm32-unknown-unknown/release/my_verifier.wasm target/verifiers/

# it appears automatically
runt list

New proof type? New chain? Just swap the .wasm module. No rebuild of the host.

$ curl -sL runt.eth.limo | grep install
# download the binary
curl -L runt.eth.limo/runt -o runt
chmod +x runt

# or install to /usr/local/bin
curl -L runt.eth.limo/runt | sudo tee /usr/local/bin/runt > /dev/null
sudo chmod +x /usr/local/bin/runt

# verify it works
runt list
$ grep -r "use case" .