On-chain Proof Verification

Note

If you've successfully performed fast-track migration, you do not need to follow the steps on this page.

The cryptographic fault proofs generated by Kailua require the existence of a RISC Zero verifier contract on the parent chain (ethereum).

Tip

Use the Kailua CLI config command to retrieve the address of the officially deployed RISC Zero verifier for your parent chain. If one is available, you can use that address as your verifier and skip the steps in this section.

This section explains how to deploy a verifier suited to your needs, but you'll need to maintain it in case of adopting any updates to Kailua that change the RISC Zero zkVM version used for proving.

Verifier Contracts

This section describes the contracts that make up the on-chain proof verification pipeline.

Verifier Router

The RISCZeroVerifierRouter contract routes proofs from different sources to their correct verifier. This allows your application (and Kailua) to leverage proofs generated using different zkVM versions, or through the Boundless proving network, while delegating the complexity of managing the verifier version to the router contract.

Depending on your needs, you may need to deploy and manage your own verifier instead of relying on the pre-deployed router managed by RISC Zero.

Warning

The verifier deployment made by Kailua does not yet utilize the Emergency stop contract in the pre-deployed RISC Zero verifier, which allows anyone to permissionlessy disable a verification backend in the router by proving a false statement.

Groth16 Verifier

The RISCZeroGroth16Verifier only accepts valid Groth16 proofs generated using its hardcoded RISC Zero zkVM version determined by the control root and id constructor parameters. This verifier is intended to be deployed and then added as a possible backend to a router instead of being used directly on its own. However, it is possible to call and use this verifier directly if the prover and verifier versions align.

Fake Proof Verifier (INSECURE)

This verifier accepts fake proofs generated while running the RISC Zero zkVM in "dev mode". It is only useful for testing out the zkVM in a development environment without being delayed by proving time.

Danger

Do not use the fake proof verifier anywhere near production.

Deployment

This section will walk you through creating your own verifier deployment. The commands below will be using Foundry's forge and cast utilities, which you should have installed as part of the foundry prerequisite.

Note

The below foundry commands expect both a parameter that determines the wallet to use and the rpc endpoint of the parent chain. You will have to add these two parameters manually to every command below. For more information, refer to forge create --help, cast call --help, and cast send --help

First, change your working directory to crates/contracts/foundry for forge to work:

cd crates/contracts/foundry

Router

constructor(address admin) Ownable(admin)

The RISCZeroVerifierRouter constructor requires a single admin address, which is an account authorised to modify the router in one of two ways after it is deployed:

  1. Add a new verification backend through addVerifier:
  2. Permanently disable a verification backend through removeVerifier:

To deploy a new router, invoke the following command

forge create RiscZeroVerifierRouter --constructor-args [ADMIN_ADDRESS]

On success, you should see output similar to the following:

Deployer: [YOUR_DEPLOYER_WALLET_ADDRESS]
Deployed to: [YOUR_DEPLOYED_ROUTER_CONTRACT]
Transaction hash: [YOUR_DEPLOYMENT_TRANSACTION_HASH]

Success

Make sure to note down the YOUR_DEPLOYED_ROUTER_CONTRACT address. We will use this in the following commands when adding proving backends. The router cannot verify any proofs on its own.

Groth16 Verifier

The Groth16 verifier validates stand-alone cryptographic proofs generated using the RISC Zero zkVM and compressed using the RISC Zero STARK-to-SNARK wrapper.

This verifier can be deployed as follows using the control root and id from the kailua-cli config command output:

forge create RiscZeroGroth16Verifier --constructor-args \ 
  [YOUR_CONTROL_ROOT] \
  [YOUR_CONTROL_ID]

The output should again give you the relevant addresses:

Deployer: [YOUR_DEPLOYER_WALLET_ADDRESS]
Deployed to: [YOUR_DEPLOYED_GROTH16_VERIFIER_CONTRACT]
Transaction hash: [YOUR_DEPLOYMENT_TRANSACTION_HASH]

We again need to query this verifier's selector:

cast call [YOUR_DEPLOYED_GROTH16_VERIFIER_CONTRACT] \
  "SELECTOR() returns (bytes4)"

Yielding another 4-byte selector:

0xc101b42b

And finally we need to add this verifier to our router:

cast send \
  [YOUR_DEPLOYED_ROUTER_CONTRACT] \
  "addVerifier(bytes4 selector, address verifier)" \
  [YOUR_GROTH16_SELECTOR] \
  [YOUR_DEPLOYED_GROTH16_VERIFIER_CONTRACT]

Success

You now have a RISC Zero verifier contract!