This repository contains the source code for the article "zk-OPML: Using Zero-Knowledge Proofs to Optimize OPML." zk-OPML is a novel method for achieving verifiability of machine learning model inference, leveraging crypto-economic and cryptographic principles. The repository includes everything needed to set up a local environment and reproduce the experiments presented in the article.
zk-OPML builds on the principles of Optimistic Machine Learning (OPML) and Zero-Knowledge Machine Learning (ZKML), combining the strengths of both approaches to achieve greater efficiency, scalability, and performance. By leveraging the interactive verification of OPML together with the cryptographic guarantees of ZKML, the protocol introduces a hybrid model that balances practical feasibility with strong security assurances.
At a high level, the protocol works as follows: a user submits a machine learning inference request through a smart contract call, and submitters respond by providing inference results. Challengers monitor these results and can raise a dispute if they believe an output is incorrect. Once a challenge is opened, the Fault Dispute Game (FDG) is played between the submitter and challenger over the sequence of ONNX operators that define the ML model. The binary search process narrows the disagreement to a specific ONNX operator (or group of operators). At this point, a zero-knowledge proof (ZKP) is generated for the disputed operator’s execution and verified on-chain, ensuring that the computation was performed correctly.
The project is structured in the following way:
contracts: smart contracts for the ML model registry, fault disoute game (FDG), and library for SP1 ZKVM on-chain verifiercrates: common code in Rust, SP1 ZKVM programbin: source code for binaries, CLItestdata: test ML models and data for development and testingnotebooks: Jupyter Notebooks for ZKML/EZKL experiments
First, build the code:
just buildBefore starting the zk-OPML, we need to set a few environment variables. Even though testing is performed on the local Ethereum devnet, the SP1 ZKVM proof generation requests are sent to the Succinct Prover Network. For more information on how to use the prover network, check the provided link. You need to configure your .env file with the following variables (check .env.example):
# ML model
MODEL_PATH=<path-to-the-testing-ml-model> # check the folder testdata for all ML models that were tested; this model will be used everywhere
INPUT_DATA_PATH=<path-to-the-input-data>
# SP1 verifier smart contracts (variables needed to deploy local SP1 smart contract verifier)
CHAINS=DEV
RPC_DEV=http://127.0.0.1:8545
# Smart contracts
MODEL_REGISTRY_SMART_CONTRACT=<model-registry-smart-contract-address> # check the output of just deploy-smart-contracts
FDG_SMART_CONTRACT=<fdg-smart-contract-address> # check the output of just deploy-smart-contracts
# SP1 prover network
NETWORK_PRIVATE_KEY=<private-key-for-succinct-prover-network>
NETWORK_RPC_URL=<rpc-url-for-succinct-prover-network>Then we need to setup the development environment (local Ethereum network and IPFS) and deploy all needed smart contracts:
just setup-network # ethereum, IPFS
just deploy-create2 # create2 smart contract
just deploy-sp1-verifier # SP1 on-chain verifier
just deploy-smart-contracts # ML model registry, FDG smart contractAfter everything is set up, we can first start with registering the ML model to the model registry smart contract:
just registerTo test the fault proof game, you need to open three terminal windows and run all three participating entities in the following order:
| Actor | Command | Command Parameters | Description |
|---|---|---|---|
| Submitter | just submit 0 or just submit-defect 0 2 |
0: model id, 2: defect operator |
Responds with ML inference |
| Verifier | just verify 0 |
0: model id |
Verifies the ML inference and can create a challenge |
| User/Requester | just request 0 |
0: model id |
Requests ML inference |
Notes:
Themodel idis an incremental counter assigned to each registered model. The first registered model receivesmodel id0, the next one 1, and so on. Thedefect operatorrefers to the ONNX operator index where the submitter intentionally corrupts the inference (for testing purposes), allowing the verifier to create a successfull challenge.
To shutdown the development environment:
just shutdown-networkThe following ML models are available in the testdata directory:
testdata/xg_boost: XGBoosttestdata/lenet_5: LeNettestdata/2d_conv: Neural network with 2-dimensional convolution and complex ONNX operatorstestdata/mobilenet: MobileNet
To use a specific model, set the variable MODEL_PATH in the .env to the location of the model's ONNX file.
| Model Name | ONNX operators | Number of ONNX operators | Number of parameters | Size (MB) | zk-OPML time | EZKL proving time (witness generation and proving) |
|---|---|---|---|---|---|---|
| XGBoost | 15 x Constant, 11 x Reshape, 10 x Gather, 5 x Add, 5 x Cast, 5 x Less, 4 x GatherElements, 4 x Mul, 1 x ReduceSum, 1 x Softmax | 62 | 3,420 | 0.03 | 120 s + 360 s + 118 s = 598 s | 0.04 s + 18.71 s = 18.75 s |
| LeNet | 3 x Gemm, 2 x Add, 2 x AveragePool, 2 x Conv, 2 x Mul, 1 x Flatten | 12 | 61,706 | 0.24 | 120 s + 240 s + 134 s = 494 s | 0.40 s + 35.97 s = 36.37 s |
| 2d conv | 12 x Relu, 10 x Conv, 5 x MaxPool, 3 x Gemm, 1 x Flatten | 31 | 54,584 | 0.21 | 120 s + 300 s + 146 s = 566 s | 2.11 s + 253.92 s = 256.03 s |
| MobileNet | 54 x Conv, 53 x BatchNormalization, 36 x Relu, 10 x Add, 1 x GlobalAveragePool, 1 x Reshape | 155 | 3,539,138 | 13.6 | 120 s + 480 s + 515 s = 1115 s | 351.53 s + / = / |
Note: The time for zk-OPML was calculated as: zk-OPML time = challenge creation window + 2 × log₂(number of ONNX operators) × response window + SP1 ZKVM proving
Note: EZKL ZK proving was not possible for MobileNet due to very high RAM requirements.
MIT License - see LICENSE file for details.
TODO
- Alloy - Ethereum Rust library
- Foundry - Ethereum smart contract development and testing
- SP1 - Zero-knowledge virtual machine (ZKVM)
- OPML - Optimistic machine learning (OPML)
- EZKL - Zero-knowledge machine learning (ZKML)
- Candle ONNX - ONNX runtime for Rust
- Twitter: @vidkersic
- Email: [email protected]
