Skip to content

Commit

Permalink
feat(protocol): introduce risc0 proof (#17877)
Browse files Browse the repository at this point in the history
Signed-off-by: smtmfft <smtm@taiko.xyz>
Co-authored-by: YoGhurt111 <YoGhurt111@users.noreply.github.com>
Co-authored-by: Daniel Wang <99078276+dantaik@users.noreply.github.com>
Co-authored-by: dantaik <dantaik@users.noreply.github.com>
Co-authored-by: Daniel Wang <dan@taiko.xyz>
Co-authored-by: Keszey Dániel <keszeyd@MacBook-Pro.local>
Co-authored-by: Daniel Wang <dan@taikocha.in>
Co-authored-by: smtmfft <smtm@taiko.xyz>
Co-authored-by: maskpp <maskpp266@gmail.com>
Co-authored-by: smtmfft <smtmfft@users.noreply.github.com>
  • Loading branch information
10 people authored Aug 6, 2024
1 parent dbed3ab commit bcb57cb
Show file tree
Hide file tree
Showing 20 changed files with 3,784 additions and 3,828 deletions.
5 changes: 4 additions & 1 deletion _typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ extend-ignore-identifiers-re = [
"bafybeiegdqpwx3he5dvoxqklspdjekjepjcobfaakyficksratn73qbbyy",
"TGE",
"tge",
"baed"
"baed",
"Groth",
"groth",
"GROTH"
]

[files]
Expand Down
70 changes: 34 additions & 36 deletions packages/protocol/contract_layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -444,24 +444,23 @@
| __gap | uint256[47] | 254 | 0 | 1504 | contracts/verifiers/SgxVerifier.sol:SgxVerifier |

## RiscZeroVerifier
| Name | Type | Slot | Offset | Bytes | Contract |
|-----------------|-----------------------------------|------|--------|-------|-----------------------------------------------------------|
| _initialized | uint8 | 0 | 0 | 1 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| _initializing | bool | 0 | 1 | 1 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __gap | uint256[50] | 1 | 0 | 1600 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| _owner | address | 51 | 0 | 20 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __gap | uint256[49] | 52 | 0 | 1568 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| _pendingOwner | address | 101 | 0 | 20 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __gap | uint256[49] | 102 | 0 | 1568 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| addressManager | address | 151 | 0 | 20 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __gap | uint256[49] | 152 | 0 | 1568 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __reentry | uint8 | 201 | 0 | 1 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __paused | uint8 | 201 | 1 | 1 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| lastUnpausedAt | uint64 | 201 | 2 | 8 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __gap | uint256[49] | 202 | 0 | 1568 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| receiptVerifier | contract IRiscZeroReceiptVerifier | 251 | 0 | 20 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| isImageTrusted | mapping(bytes32 => bool) | 252 | 0 | 32 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __gap | uint256[48] | 253 | 0 | 1536 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| Name | Type | Slot | Offset | Bytes | Contract |
|----------------|--------------------------|------|--------|-------|-----------------------------------------------------------|
| _initialized | uint8 | 0 | 0 | 1 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| _initializing | bool | 0 | 1 | 1 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __gap | uint256[50] | 1 | 0 | 1600 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| _owner | address | 51 | 0 | 20 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __gap | uint256[49] | 52 | 0 | 1568 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| _pendingOwner | address | 101 | 0 | 20 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __gap | uint256[49] | 102 | 0 | 1568 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| addressManager | address | 151 | 0 | 20 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __gap | uint256[49] | 152 | 0 | 1568 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __reentry | uint8 | 201 | 0 | 1 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __paused | uint8 | 201 | 1 | 1 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| lastUnpausedAt | uint64 | 201 | 2 | 8 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __gap | uint256[49] | 202 | 0 | 1568 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| isImageTrusted | mapping(bytes32 => bool) | 251 | 0 | 32 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |
| __gap | uint256[49] | 252 | 0 | 1568 | contracts/verifiers/RiscZeroVerifier.sol:RiscZeroVerifier |

## QuotaManager
| Name | Type | Slot | Offset | Bytes | Contract |
Expand Down Expand Up @@ -683,24 +682,23 @@
| __gap | uint256[48] | 253 | 0 | 1536 | contracts/mainnet/MainnetProverSet.sol:MainnetProverSet |

## MainnetRiscZeroVerifier
| Name | Type | Slot | Offset | Bytes | Contract |
|-----------------|-----------------------------------|------|--------|-------|-----------------------------------------------------------------------|
| _initialized | uint8 | 0 | 0 | 1 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| _initializing | bool | 0 | 1 | 1 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __gap | uint256[50] | 1 | 0 | 1600 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| _owner | address | 51 | 0 | 20 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __gap | uint256[49] | 52 | 0 | 1568 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| _pendingOwner | address | 101 | 0 | 20 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __gap | uint256[49] | 102 | 0 | 1568 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| addressManager | address | 151 | 0 | 20 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __gap | uint256[49] | 152 | 0 | 1568 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __reentry | uint8 | 201 | 0 | 1 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __paused | uint8 | 201 | 1 | 1 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| lastUnpausedAt | uint64 | 201 | 2 | 8 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __gap | uint256[49] | 202 | 0 | 1568 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| receiptVerifier | contract IRiscZeroReceiptVerifier | 251 | 0 | 20 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| isImageTrusted | mapping(bytes32 => bool) | 252 | 0 | 32 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __gap | uint256[48] | 253 | 0 | 1536 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| Name | Type | Slot | Offset | Bytes | Contract |
|----------------|--------------------------|------|--------|-------|-----------------------------------------------------------------------|
| _initialized | uint8 | 0 | 0 | 1 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| _initializing | bool | 0 | 1 | 1 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __gap | uint256[50] | 1 | 0 | 1600 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| _owner | address | 51 | 0 | 20 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __gap | uint256[49] | 52 | 0 | 1568 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| _pendingOwner | address | 101 | 0 | 20 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __gap | uint256[49] | 102 | 0 | 1568 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| addressManager | address | 151 | 0 | 20 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __gap | uint256[49] | 152 | 0 | 1568 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __reentry | uint8 | 201 | 0 | 1 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __paused | uint8 | 201 | 1 | 1 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| lastUnpausedAt | uint64 | 201 | 2 | 8 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __gap | uint256[49] | 202 | 0 | 1568 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| isImageTrusted | mapping(bytes32 => bool) | 251 | 0 | 32 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |
| __gap | uint256[49] | 252 | 0 | 1568 | contracts/mainnet/MainnetRiscZeroVerifier.sol:MainnetRiscZeroVerifier |

## MainnetRollupAddressManager
| Name | Type | Slot | Offset | Bytes | Contract |
Expand Down
1 change: 1 addition & 0 deletions packages/protocol/contracts/common/LibStrings.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ library LibStrings {
bytes32 internal constant B_TIER_SGX = bytes32("tier_sgx");
bytes32 internal constant B_TIER_SGX2 = bytes32("tier_sgx2");
bytes32 internal constant B_TIER_SGX_ZKVM = bytes32("tier_sgx_zkvm");
bytes32 internal constant B_RISCZERO_GROTH16_VERIFIER = bytes32("risc0_groth16_verifier");
bytes32 internal constant B_WITHDRAWER = bytes32("withdrawer");
bytes32 internal constant H_RETURN_LIVENESS_BOND = keccak256("RETURN_LIVENESS_BOND");
bytes32 internal constant H_SIGNAL_ROOT = keccak256("SIGNAL_ROOT");
Expand Down

This file was deleted.

36 changes: 15 additions & 21 deletions packages/protocol/contracts/verifiers/RiscZeroVerifier.sol
Original file line number Diff line number Diff line change
@@ -1,46 +1,40 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import "@risc0/contracts/IRiscZeroVerifier.sol";
import "../common/EssentialContract.sol";
import "../common/LibStrings.sol";
import "../thirdparty/risczero/IRiscZeroReceiptVerifier.sol";
import "../L1/ITaikoL1.sol";
import "./IVerifier.sol";
import "./libs/LibPublicInput.sol";

/// @title RiscZeroVerifier
/// @custom:security-contact security@taiko.xyz
contract RiscZeroVerifier is EssentialContract, IVerifier {
/// @notice RISC Zero remote verifier contract address, e.g.:
/// https://sepolia.etherscan.io/address/0x3d24C84FC1A2B26f9229e58ddDf11A8dfba802d0
IRiscZeroReceiptVerifier public receiptVerifier;
// [32, 0, 0, 0] -- big-endian uint32(32) for hash bytes len
bytes private constant FIXED_JOURNAL_HEADER = hex"20000000";

/// @notice Trusted imageId mapping
mapping(bytes32 imageId => bool trusted) public isImageTrusted;

uint256[48] private __gap;
uint256[49] private __gap;

/// @dev Emitted when a trusted image is set / unset.
/// @param imageId The id of the image
/// @param trusted True if trusted, false otherwise
event ImageTrusted(bytes32 imageId, bool trusted);

/// @dev Emitted when a proof is verified
event ProofVerified(bytes32 metaHash, bytes32 publicInputHash);

error RISC_ZERO_INVALID_IMAGE_ID();
error RISC_ZERO_INVALID_PROOF();

/// @notice Initializes the contract with the provided address manager.
/// @param _owner The address of the owner.
/// @param _rollupAddressManager The address of the AddressManager.
/// @param _receiptVerifier The address of the risc zero receipt verifier contract.
function init(
address _owner,
address _rollupAddressManager,
address _receiptVerifier
)
external
initializer
{
function init(address _owner, address _rollupAddressManager) external initializer {
__Essential_init(_owner, _rollupAddressManager);
receiptVerifier = IRiscZeroReceiptVerifier(_receiptVerifier);
}

/// @notice Sets/unsets an the imageId as trusted entity
Expand All @@ -59,7 +53,6 @@ contract RiscZeroVerifier is EssentialContract, IVerifier {
TaikoData.TierProof calldata _proof
)
external
view
{
// Do not run proof verification to contest an existing proof
if (_ctx.isContesting) return;
Expand All @@ -71,21 +64,22 @@ contract RiscZeroVerifier is EssentialContract, IVerifier {
revert RISC_ZERO_INVALID_IMAGE_ID();
}

bytes32 hash = LibPublicInput.hashPublicInputs(
bytes32 publicInputHash = LibPublicInput.hashPublicInputs(
_tran, address(this), address(0), _ctx.prover, _ctx.metaHash, taikoChainId()
);

// journalDigest is the sha256 hash of the hashed public input
bytes32 journalDigest = sha256(bytes.concat(hash));
bytes32 journalDigest = sha256(bytes.concat(FIXED_JOURNAL_HEADER, publicInputHash));

// call risc0 verifier contract
(bool success,) = address(receiptVerifier).staticcall(
abi.encodeCall(IRiscZeroReceiptVerifier.verify, (seal, imageId, journalDigest))
(bool success,) = resolve(LibStrings.B_RISCZERO_GROTH16_VERIFIER, false).staticcall(
abi.encodeCall(IRiscZeroVerifier.verify, (seal, imageId, journalDigest))
);

if (!success) {
revert RISC_ZERO_INVALID_PROOF();
}

emit ProofVerified(_ctx.metaHash, publicInputHash);
}

function taikoChainId() internal view virtual returns (uint64) {
Expand Down
5 changes: 4 additions & 1 deletion packages/protocol/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@ solc_version = "0.8.24"
evm_version = "cancun"
remappings = [
"@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/",
"openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/",
"@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
"openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
"@risc0/contracts/=node_modules/risc0-ethereum/contracts/src/",
"@solady/=node_modules/solady/",
"@optimism/=node_modules/optimism/",
"@sp1-contracts/=node_modules/sp1-contracts/contracts/",
"forge-std/=node_modules/forge-std/",
"ds-test/=node_modules/ds-test/src/",
"p256-verifier/=node_modules/p256-verifier/",
"@p256-verifier/contracts/=node_modules/p256-verifier/src/",
]

# Do not change the block_gas_limit value, TaikoL2.t.sol depends on it.
Expand Down
1 change: 1 addition & 0 deletions packages/protocol/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"merkletreejs": "^0.3.11",
"optimism": "github:ethereum-optimism/optimism#v1.8.0",
"p256-verifier": "github:taikoxyz/p256-verifier#v0.1.0",
"risc0-ethereum": "github:risc0/risc0-ethereum#v1.0.0",
"solady": "github:Vectorized/solady#v0.0.231",
"sp1-contracts": "github:succinctlabs/sp1-contracts#v1.1.0"
}
Expand Down
26 changes: 20 additions & 6 deletions packages/protocol/script/DeployOnL1.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
pragma solidity 0.8.24;

import "@openzeppelin/contracts/utils/Strings.sol";
import "@risc0/contracts/groth16/RiscZeroGroth16Verifier.sol";

// Actually this one is deployed already on mainnet, but we are now deploying our own (non via-ir)
// version. For mainnet, it is easier to go with one of:
// - https://github.com/daimo-eth/p256-verifier
// - https://github.com/rdubois-crypto/FreshCryptoLib
import "@p256-verifier/contracts/P256Verifier.sol";

import "../contracts/common/LibStrings.sol";
import "../contracts/tko/TaikoToken.sol";
Expand All @@ -27,12 +34,7 @@ import "../test/common/erc20/FreeMintERC20.sol";
import "../test/common/erc20/MayFailFreeMintERC20.sol";
import "../test/L1/TestTierProvider.sol";
import "../test/DeployCapability.sol";

// Actually this one is deployed already on mainnet, but we are now deploying our own (non via-ir)
// version. For mainnet, it is easier to go with one of:
// - https://github.com/daimo-eth/p256-verifier
// - https://github.com/rdubois-crypto/FreshCryptoLib
import { P256Verifier } from "p256-verifier/src/P256Verifier.sol";
import "../contracts/verifiers/RiscZeroVerifier.sol";

/// @title DeployOnL1
/// @notice This script deploys the core Taiko protocol smart contract on L1,
Expand Down Expand Up @@ -383,6 +385,18 @@ contract DeployOnL1 is DeployCapability {
ProverSet.init, (owner, vm.envAddress("PROVER_SET_ADMIN"), rollupAddressManager)
)
});

// Deploy r0 groth16 verifier
RiscZeroGroth16Verifier verifier =
new RiscZeroGroth16Verifier(ControlID.CONTROL_ROOT, ControlID.BN254_CONTROL_ID);
register(rollupAddressManager, "risc0_groth16_verifier", address(verifier));

deployProxy({
name: "risc0_verifier",
impl: address(new RiscZeroVerifier()),
data: abi.encodeCall(RiscZeroVerifier.init, (owner, rollupAddressManager)),
registerTo: rollupAddressManager
});
}

function deployTierProvider(string memory tierProviderName) private returns (address) {
Expand Down
5 changes: 3 additions & 2 deletions packages/protocol/script/DeploySP1Verifier.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ contract DeploySP1Verifier is DeployCapability {
}

function run() external broadcast {
address sp1RemoteVerifierOrGateway = vm.envOr("SP1_REMOTE_VERIFIER_GATEWAY", address(0)); // address(0)
// is fine, we can set it later
// address sp1RemoteVerifierOrGateway = vm.envOr("SP1_REMOTE_VERIFIER_GATEWAY", address(0));
// // address(0)
// is fine, we can set it later
address owner = vm.envOr("SP1_VERIFIER_OWNER", msg.sender);

address sp1Verifier = address(new SP1Verifier());
Expand Down
2 changes: 1 addition & 1 deletion packages/protocol/test/TaikoTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ abstract contract TaikoTest is Test, DeployCapability {
address internal Bob = vm.addr(0x2);
address internal Carol = vm.addr(0x3);
address internal David = vm.addr(0x4);
address internal Emma = randAddress();
address internal Emma = vm.addr(0x5);
address internal Frank = randAddress();
address internal Grace = randAddress();
address internal Henry = randAddress();
Expand Down
Loading

0 comments on commit bcb57cb

Please sign in to comment.