-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(protocol): risc0 verifier contract (#16331)
Co-authored-by: Keszey Dániel <[email protected]> Co-authored-by: Daniel Wang <[email protected]> Co-authored-by: Daniel Wang <[email protected]>
- Loading branch information
1 parent
2b07d43
commit 17abc18
Showing
10 changed files
with
353 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
packages/protocol/contracts/thirdparty/risczero/IRiscZeroReceiptVerifier.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.24; | ||
|
||
/// @notice Verifier interface for RISC Zero receipts of execution. | ||
/// https://github.com/risc0/risc0-ethereum/blob/release-0.7/contracts/src/IRiscZeroVerifier.sol | ||
interface IRiscZeroReceiptVerifier { | ||
/// @notice Verify that the given seal is a valid RISC Zero proof of execution with the | ||
/// given image ID, post-state digest, and journal digest. | ||
/// @dev This method additionally ensures that the input hash is all-zeros (i.e. no | ||
/// committed input), the exit code is (Halted, 0), and there are no assumptions (i.e. the | ||
/// receipt is unconditional). | ||
/// @param seal The encoded cryptographic proof (i.e. SNARK). | ||
/// @param imageId The identifier for the guest program. | ||
/// @param postStateDigest A hash of the final memory state. Required to run the verifier, but | ||
/// otherwise can be left unconstrained for most use cases. | ||
/// @param journalDigest The SHA-256 digest of the journal bytes. | ||
/// @return true if the receipt passes the verification checks. The return code must be checked. | ||
function verify( | ||
bytes calldata seal, | ||
bytes32 imageId, | ||
bytes32 postStateDigest, | ||
bytes32 journalDigest | ||
) | ||
external | ||
view | ||
returns (bool); | ||
} |
86 changes: 86 additions & 0 deletions
86
packages/protocol/contracts/verifiers/RiscZeroVerifier.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.24; | ||
|
||
import "../common/EssentialContract.sol"; | ||
import "../thirdparty/risczero/IRiscZeroReceiptVerifier.sol"; | ||
import "../L1/ITaikoL1.sol"; | ||
import "./IVerifier.sol"; | ||
import "./libs/LibPublicInput.sol"; | ||
|
||
/// @title RiscZeroVerifier | ||
/// @custom:security-contact [email protected] | ||
contract RiscZeroVerifier is EssentialContract, IVerifier { | ||
/// @notice RISC Zero remote verifier contract address, e.g.: | ||
/// https://sepolia.etherscan.io/address/0x83c2e9cd64b2a16d3908e94c7654f3864212e2f8 | ||
IRiscZeroReceiptVerifier public receiptVerifier; | ||
/// @notice Trusted imageId mapping | ||
mapping(bytes32 imageId => bool trusted) public isImageTrusted; | ||
|
||
uint256[48] private __gap; | ||
|
||
/// @dev Emitted when a trusted image is set / unset. | ||
/// @param imageId The id of the image | ||
/// @param trusted The block's assigned prover. | ||
event ImageTrusted(bytes32 imageId, bool trusted); | ||
|
||
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 _addressManager The address of the AddressManager. | ||
/// @param _receiptVerifier The address of the risc zero receipt verifier contract. | ||
function init( | ||
address _owner, | ||
address _addressManager, | ||
address _receiptVerifier | ||
) | ||
external | ||
initializer | ||
{ | ||
__Essential_init(_owner, _addressManager); | ||
receiptVerifier = IRiscZeroReceiptVerifier(_receiptVerifier); | ||
} | ||
|
||
/// @notice Sets/unsets an the imageId as trusted entity | ||
/// @param _imageId The id of the image. | ||
/// @param _trusted True if trusted, false otherwise. | ||
function setImageIdTrusted(bytes32 _imageId, bool _trusted) external onlyOwner { | ||
isImageTrusted[_imageId] = _trusted; | ||
|
||
emit ImageTrusted(_imageId, _trusted); | ||
} | ||
|
||
/// @inheritdoc IVerifier | ||
function verifyProof( | ||
Context calldata _ctx, | ||
TaikoData.Transition calldata _tran, | ||
TaikoData.TierProof calldata _proof | ||
) | ||
external | ||
view | ||
{ | ||
// Do not run proof verification to contest an existing proof | ||
if (_ctx.isContesting) return; | ||
|
||
// Decode will throw if not proper length/encoding | ||
(bytes memory seal, bytes32 imageId, bytes32 postStateDigest) = | ||
abi.decode(_proof.data, (bytes, bytes32, bytes32)); | ||
|
||
if (!isImageTrusted[imageId]) { | ||
revert RISC_ZERO_INVALID_IMAGE_ID(); | ||
} | ||
|
||
uint64 chainId = ITaikoL1(resolve("taiko", false)).getConfig().chainId; | ||
bytes32 hash = LibPublicInput.hashPublicInputs( | ||
_tran, address(this), address(0), _ctx.prover, _ctx.metaHash, chainId | ||
); | ||
|
||
// journalDigest is the sha256 hash of the hashed public input | ||
bytes32 journalDigest = sha256(bytes.concat(hash)); | ||
|
||
if (!receiptVerifier.verify(seal, imageId, postStateDigest, journalDigest)) { | ||
revert RISC_ZERO_INVALID_PROOF(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
packages/protocol/contracts/verifiers/libs/LibPublicInput.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.24; | ||
|
||
import "../../L1/TaikoData.sol"; | ||
|
||
/// @title LibPublicInput | ||
/// @notice A library for handling hashing the so-called public input hash, used by sgx and zk | ||
/// proofs. | ||
/// @custom:security-contact [email protected] | ||
library LibPublicInput { | ||
/// @notice Hashes the public input for the proof verification. | ||
/// @param _tran The transition to verify. | ||
/// @param _verifierContract The contract address which as current verifier. | ||
/// @param _newInstance The new instance address. For SGX it is the new signer address, for ZK | ||
/// this variable is not used and must have value address(0). | ||
/// @param _prover The prover address. | ||
/// @param _metaHash The meta hash. | ||
/// @param _chainId The chain id. | ||
/// @return The public input hash. | ||
function hashPublicInputs( | ||
TaikoData.Transition memory _tran, | ||
address _verifierContract, | ||
address _newInstance, | ||
address _prover, | ||
bytes32 _metaHash, | ||
uint64 _chainId | ||
) | ||
public | ||
pure | ||
returns (bytes32) | ||
{ | ||
return keccak256( | ||
abi.encode( | ||
"VERIFY_PROOF", _chainId, _verifierContract, _tran, _newInstance, _prover, _metaHash | ||
) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.