Skip to content

trionlabs/sp1-self

Repository files navigation

sp1-self

Verify Self Protocol identity proofs inside SP1 zkVM.

Takes a Self Protocol Groth16 BN254 proof (passport, local ID etc.), verifies it inside SP1, and extracts identity fields (name, nationality, DOB, issuing state, age threshold) as ABI-encoded public values.

Structure

program/          SP1 guest — Groth16 verification + MRZ field extraction
script/           Host scripts — execute, prove, EVM proof, vkey
lib/              Shared ABI types (SelfIdPublicValues)
self2gnark/       Go converter — Self Protocol JSON -> gnark binary format
sp1-verifier-patch/  Patched sp1-verifier with BN254 pairing for RISC-V
self-vkeys/       Self Protocol verification keys
test-data/        Mock passport proof

Requirements

Quick start

# 1. Convert a Self Protocol proof to gnark binary format
cd self2gnark
go run main.go --proof ../test-data/passport_proof.json

# 2. Execute inside SP1 (no proof generation, just runs the program)
cd ../script
cargo run --release -- --execute

Expected output:

groth16_verified: true
attestation_id:   1
surname:          DOE
given_name:       JOHN
nationality:      USA
dob:              041023
older_than:       18

Proving

Generate a SP1 proof:

cd script
cargo run --release -- --prove

Using the Succinct prover network:

cp .env.example .env
# set NETWORK_PRIVATE_KEY in .env
cargo run --release -- --prove --network

TEE private proving:

cargo run --release -- --prove --network --private

EVM proofs

Generate a Groth16 or PLONK proof for on-chain verification:

cd script
cargo run --release --bin evm -- --system groth16
cargo run --release --bin evm -- --system plonk

Get the program verification key for your contract:

cargo run --release --bin vkey

Why sp1-verifier-patch?

The stock sp1-verifier v5.2.4 has a bug in prepare_inputs where public inputs with scalar value 0 (all-zero bytes) cause Fr::from_slice to fail. Self Protocol proofs commonly have zero-valued public signals, so verification panics on valid proofs. The sp1-verifier-patch fixes this by pinning substrate-bn-succinct to 0.6.0-v5.0.0 and explicitly skipping zero-valued inputs in the MSM accumulator (if *i != Fr::zero() { acc + (*b * *i) } else { acc }).

SP1 v6 fixes this natively, but it's still in prerelease and the BN254 precompiles are not yet optimized, Groth16 verification costs ~100M+ cycles instead of ~8M. Once v6 stabilizes, this patch can be dropped.

Supported attestation types

ID Type Layout
1 E-Passport 3 packed elements, 93 bytes
2 EU ID Card 4 packed elements, 94 bytes
3 Aadhaar TODO: converter supports it, SP1 guest layout missing

About

Verify Self Protocol's zk-identity proofs (passport, local id etc.) inside SP1 zkVM

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors