Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00Multichain Info
N/A
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
11922634 | 9 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
RiscZeroGroth16Verifier
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 10000 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// Copyright 2024 RISC Zero, Inc. // // The RiscZeroGroth16Verifier is a free software: you can redistribute it // and/or modify it under the terms of the GNU General Public License as // published by the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // // The RiscZeroGroth16Verifier is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General // Public License for more details. // // You should have received a copy of the GNU General Public License along with // the RiscZeroGroth16Verifier. If not, see <https://www.gnu.org/licenses/>. // // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.9; import {SafeCast} from "openzeppelin/contracts/utils/math/SafeCast.sol"; import {ControlID} from "./ControlID.sol"; import {Groth16Verifier} from "./Groth16Verifier.sol"; import { ExitCode, IRiscZeroVerifier, Output, OutputLib, Receipt, ReceiptClaim, ReceiptClaimLib, SystemExitCode, VerificationFailed } from "../IRiscZeroVerifier.sol"; import {StructHash} from "../StructHash.sol"; import {reverseByteOrderUint256, reverseByteOrderUint32} from "../Util.sol"; import {IRiscZeroSelectable} from "../IRiscZeroSelectable.sol"; /// @notice A Groth16 seal over the claimed receipt claim. struct Seal { uint256[2] a; uint256[2][2] b; uint256[2] c; } /// @notice Error raised when this verifier receives a receipt with a selector that does not match /// its own. The selector value is calculated from the verifier parameters, and so this /// usually indicates a mismatch between the version of the prover and this verifier. error SelectorMismatch(bytes4 received, bytes4 expected); /// @notice Groth16 verifier contract for RISC Zero receipts of execution. contract RiscZeroGroth16Verifier is IRiscZeroVerifier, IRiscZeroSelectable, Groth16Verifier { using ReceiptClaimLib for ReceiptClaim; using OutputLib for Output; using SafeCast for uint256; /// @notice Semantic version of the RISC Zero system of which this contract is part. /// @dev This is set to be equal to the version of the risc0-zkvm crate. string public constant VERSION = "3.0.0"; /// @notice Control root hash binding the set of circuits in the RISC Zero system. /// @dev This value controls what set of recursion programs (e.g. lift, join, resolve), and /// therefore what version of the zkVM circuit, will be accepted by this contract. Each /// instance of this verifier contract will accept a single release of the RISC Zero circuits. /// /// New releases of RISC Zero's zkVM require updating these values. These values can be /// calculated from the [risc0 monorepo][1] using: `cargo xtask bootstrap`. /// /// [1]: https://github.com/risc0/risc0 bytes16 public immutable CONTROL_ROOT_0; bytes16 public immutable CONTROL_ROOT_1; bytes32 public immutable BN254_CONTROL_ID; /// @notice A short key attached to the seal to select the correct verifier implementation. /// @dev The selector is taken from the hash of the verifier parameters including the Groth16 /// verification key and the control IDs that commit to the RISC Zero circuits. If two /// receipts have different selectors (i.e. different verifier parameters), then it can /// generally be assumed that they need distinct verifier implementations. This is used as /// part of the RISC Zero versioning mechanism. /// /// A selector is not intended to be collision resistant, in that it is possible to find /// two preimages that result in the same selector. This is acceptable since it's purpose /// to a route a request among a set of trusted verifiers, and to make errors of sending a /// receipt to a mismatching verifiers easier to debug. It is analogous to the ABI /// function selectors. bytes4 public immutable SELECTOR; /// @notice Identifier for the Groth16 verification key encoded into the base contract. /// @dev This value is computed at compile time. function verifier_key_digest() internal pure returns (bytes32) { bytes32[] memory ic_digests = new bytes32[](6); ic_digests[0] = sha256(abi.encodePacked(IC0x, IC0y)); ic_digests[1] = sha256(abi.encodePacked(IC1x, IC1y)); ic_digests[2] = sha256(abi.encodePacked(IC2x, IC2y)); ic_digests[3] = sha256(abi.encodePacked(IC3x, IC3y)); ic_digests[4] = sha256(abi.encodePacked(IC4x, IC4y)); ic_digests[5] = sha256(abi.encodePacked(IC5x, IC5y)); return sha256( abi.encodePacked( // tag sha256("risc0_groth16.VerifyingKey"), // down sha256(abi.encodePacked(alphax, alphay)), sha256(abi.encodePacked(betax1, betax2, betay1, betay2)), sha256(abi.encodePacked(gammax1, gammax2, gammay1, gammay2)), sha256(abi.encodePacked(deltax1, deltax2, deltay1, deltay2)), StructHash.taggedList(sha256("risc0_groth16.VerifyingKey.IC"), ic_digests), // down length uint16(5) << 8 ) ); } constructor(bytes32 control_root, bytes32 bn254_control_id) { (CONTROL_ROOT_0, CONTROL_ROOT_1) = splitDigest(control_root); BN254_CONTROL_ID = bn254_control_id; SELECTOR = bytes4( sha256( abi.encodePacked( // tag sha256("risc0.Groth16ReceiptVerifierParameters"), // down control_root, reverseByteOrderUint256(uint256(bn254_control_id)), verifier_key_digest(), // down length uint16(3) << 8 ) ) ); } /// @notice splits a digest into two 128-bit halves to use as public signal inputs. /// @dev RISC Zero's Circom verifier circuit takes each of two hash digests in two 128-bit /// chunks. These values can be derived from the digest by splitting the digest in half and /// then reversing the bytes of each. function splitDigest(bytes32 digest) internal pure returns (bytes16, bytes16) { uint256 reversed = reverseByteOrderUint256(uint256(digest)); return (bytes16(uint128(reversed)), bytes16(uint128(reversed >> 128))); } /// @inheritdoc IRiscZeroVerifier function verify(bytes calldata seal, bytes32 imageId, bytes32 journalDigest) external view { _verifyIntegrity(seal, ReceiptClaimLib.ok(imageId, journalDigest).digest()); } /// @inheritdoc IRiscZeroVerifier function verifyIntegrity(Receipt calldata receipt) external view { return _verifyIntegrity(receipt.seal, receipt.claimDigest); } /// @notice internal implementation of verifyIntegrity, factored to avoid copying calldata bytes to memory. function _verifyIntegrity(bytes calldata seal, bytes32 claimDigest) internal view { // Check that the seal has a matching selector. Mismatch generally indicates that the // prover and this verifier are using different parameters, and so the verification // will not succeed. if (SELECTOR != bytes4(seal[:4])) { revert SelectorMismatch({received: bytes4(seal[:4]), expected: SELECTOR}); } // Run the Groth16 verify procedure. (bytes16 claim0, bytes16 claim1) = splitDigest(claimDigest); Seal memory decodedSeal = abi.decode(seal[4:], (Seal)); bool verified = this.verifyProof( decodedSeal.a, decodedSeal.b, decodedSeal.c, [ uint256(uint128(CONTROL_ROOT_0)), uint256(uint128(CONTROL_ROOT_1)), uint256(uint128(claim0)), uint256(uint128(claim1)), uint256(BN254_CONTROL_ID) ] ); // Revert is verification failed. if (!verified) { revert VerificationFailed(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } /** * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { assembly ("memory-safe") { u := iszero(iszero(b)) } } }
// Copyright 2025 RISC Zero, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 // This file is automatically generated by: // cargo xtask bootstrap-groth16 pragma solidity ^0.8.9; library ControlID { bytes32 public constant CONTROL_ROOT = hex"a54dc85ac99f851c92d7c96d7318af41dbe7c0194edfcc37eb4d422a998c1f56"; // NOTE: This has the opposite byte order to the value in the risc0 repository. bytes32 public constant BN254_CONTROL_ID = hex"04446e66d300eb7fb45c9726bb53c793dda407a62e9601618bb43c5c14657ac0"; }
// SPDX-License-Identifier: GPL-3.0 /* Copyright 2021 0KIMS association. This file is generated with [snarkJS](https://github.com/iden3/snarkjs). snarkJS is a free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. snarkJS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with snarkJS. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity >=0.7.0 <0.9.0; contract Groth16Verifier { // Scalar field size uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Base field size uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // Verification Key data uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042; uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958; uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132; uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731; uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679; uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856; uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634; uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; uint256 constant deltax1 = 1668323501672964604911431804142266013250380587483576094566949227275849579036; uint256 constant deltax2 = 12043754404802191763554326994664886008979042643626290185762540825416902247219; uint256 constant deltay1 = 7710631539206257456743780535472368339139328733484942210876916214502466455394; uint256 constant deltay2 = 13740680757317479711909903993315946540841369848973133181051452051592786724563; uint256 constant IC0x = 8446592859352799428420270221449902464741693648963397251242447530457567083492; uint256 constant IC0y = 1064796367193003797175961162477173481551615790032213185848276823815288302804; uint256 constant IC1x = 3179835575189816632597428042194253779818690147323192973511715175294048485951; uint256 constant IC1y = 20895841676865356752879376687052266198216014795822152491318012491767775979074; uint256 constant IC2x = 5332723250224941161709478398807683311971555792614491788690328996478511465287; uint256 constant IC2y = 21199491073419440416471372042641226693637837098357067793586556692319371762571; uint256 constant IC3x = 12457994489566736295787256452575216703923664299075106359829199968023158780583; uint256 constant IC3y = 19706766271952591897761291684837117091856807401404423804318744964752784280790; uint256 constant IC4x = 19617808913178163826953378459323299110911217259216006187355745713323154132237; uint256 constant IC4y = 21663537384585072695701846972542344484111393047775983928357046779215877070466; uint256 constant IC5x = 6834578911681792552110317589222010969491336870276623105249474534788043166867; uint256 constant IC5y = 15060583660288623605191393599883223885678013570733629274538391874953353488393; // Memory data uint16 constant pVk = 0; uint16 constant pPairing = 128; uint16 constant pLastMem = 896; function verifyProof( uint256[2] calldata _pA, uint256[2][2] calldata _pB, uint256[2] calldata _pC, uint256[5] calldata _pubSignals ) public view returns (bool) { assembly { function checkField(v) { if iszero(lt(v, r)) { mstore(0, 0) return(0, 0x20) } } // G1 function to multiply a G1 value(x,y) to value in an address function g1_mulAccC(pR, x, y, s) { let success let mIn := mload(0x40) mstore(mIn, x) mstore(add(mIn, 32), y) mstore(add(mIn, 64), s) success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64) if iszero(success) { mstore(0, 0) return(0, 0x20) } mstore(add(mIn, 64), mload(pR)) mstore(add(mIn, 96), mload(add(pR, 32))) success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64) if iszero(success) { mstore(0, 0) return(0, 0x20) } } function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk { let _pPairing := add(pMem, pPairing) let _pVk := add(pMem, pVk) mstore(_pVk, IC0x) mstore(add(_pVk, 32), IC0y) // Compute the linear combination vk_x g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0))) g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32))) g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64))) g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96))) g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128))) // -A mstore(_pPairing, calldataload(pA)) mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q)) // B mstore(add(_pPairing, 64), calldataload(pB)) mstore(add(_pPairing, 96), calldataload(add(pB, 32))) mstore(add(_pPairing, 128), calldataload(add(pB, 64))) mstore(add(_pPairing, 160), calldataload(add(pB, 96))) // alpha1 mstore(add(_pPairing, 192), alphax) mstore(add(_pPairing, 224), alphay) // beta2 mstore(add(_pPairing, 256), betax1) mstore(add(_pPairing, 288), betax2) mstore(add(_pPairing, 320), betay1) mstore(add(_pPairing, 352), betay2) // vk_x mstore(add(_pPairing, 384), mload(add(pMem, pVk))) mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32)))) // gamma2 mstore(add(_pPairing, 448), gammax1) mstore(add(_pPairing, 480), gammax2) mstore(add(_pPairing, 512), gammay1) mstore(add(_pPairing, 544), gammay2) // C mstore(add(_pPairing, 576), calldataload(pC)) mstore(add(_pPairing, 608), calldataload(add(pC, 32))) // delta2 mstore(add(_pPairing, 640), deltax1) mstore(add(_pPairing, 672), deltax2) mstore(add(_pPairing, 704), deltay1) mstore(add(_pPairing, 736), deltay2) let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20) isOk := and(success, mload(_pPairing)) } let pMem := mload(0x40) mstore(0x40, add(pMem, pLastMem)) // Validate that all evaluations ∈ F checkField(calldataload(add(_pubSignals, 0))) checkField(calldataload(add(_pubSignals, 32))) checkField(calldataload(add(_pubSignals, 64))) checkField(calldataload(add(_pubSignals, 96))) checkField(calldataload(add(_pubSignals, 128))) // Validate all evaluations let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) mstore(0, isValid) return(0, 0x20) } } }
// Copyright 2025 RISC Zero, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.9; import {reverseByteOrderUint32} from "./Util.sol"; /// @notice A receipt attesting to a claim using the RISC Zero proof system. /// @dev A receipt contains two parts: a seal and a claim. /// /// The seal is a zero-knowledge proof attesting to knowledge of a witness for the claim. The claim /// is a set of public outputs, and for zkVM execution is the hash of a `ReceiptClaim` struct. /// /// IMPORTANT: The `claimDigest` field must be a hash computed by the caller for verification to /// have meaningful guarantees. Treat this similar to verifying an ECDSA signature, in that hashing /// is a key operation in verification. The most common way to calculate this hash is to use the /// `ReceiptClaimLib.ok(imageId, journalDigest).digest()` for successful executions. struct Receipt { bytes seal; bytes32 claimDigest; } /// @notice Public claims about a zkVM guest execution, such as the journal committed to by the guest. /// @dev Also includes important information such as the exit code and the starting and ending system /// state (i.e. the state of memory). `ReceiptClaim` is a "Merkle-ized struct" supporting /// partial openings of the underlying fields from a hash commitment to the full structure. struct ReceiptClaim { /// @notice Digest of the SystemState just before execution has begun. bytes32 preStateDigest; /// @notice Digest of the SystemState just after execution has completed. bytes32 postStateDigest; /// @notice The exit code for the execution. ExitCode exitCode; /// @notice A digest of the input to the guest. /// @dev This field is currently unused and must be set to the zero digest. bytes32 input; /// @notice Digest of the Output of the guest, including the journal /// and assumptions set during execution. bytes32 output; } library ReceiptClaimLib { using OutputLib for Output; using SystemStateLib for SystemState; bytes32 constant TAG_DIGEST = sha256("risc0.ReceiptClaim"); // Define a constant to ensure hashing is done at compile time. Can't use the // SystemStateLib.digest method here because the Solidity compiler complains. bytes32 constant SYSTEM_STATE_ZERO_DIGEST = 0xa3acc27117418996340b84e5a90f3ef4c49d22c79e44aad822ec9c313e1eb8e2; /// @notice Construct a ReceiptClaim from the given imageId and journalDigest. /// Returned ReceiptClaim will represent a successful execution of the zkVM, running /// the program committed by imageId and resulting in the journal specified by /// journalDigest. /// @param imageId The identifier for the guest program. /// @param journalDigest The SHA-256 digest of the journal bytes. /// @dev Input hash and postStateDigest are set to all-zeros (i.e. no committed input, or /// final memory state), the exit code is (Halted, 0), and there are no assumptions /// (i.e. the receipt is unconditional). function ok(bytes32 imageId, bytes32 journalDigest) internal pure returns (ReceiptClaim memory) { return ReceiptClaim( imageId, SYSTEM_STATE_ZERO_DIGEST, ExitCode(SystemExitCode.Halted, 0), bytes32(0), Output(journalDigest, bytes32(0)).digest() ); } function digest(ReceiptClaim memory claim) internal pure returns (bytes32) { return sha256( abi.encodePacked( TAG_DIGEST, // down claim.input, claim.preStateDigest, claim.postStateDigest, claim.output, // data uint32(claim.exitCode.system) << 24, uint32(claim.exitCode.user) << 24, // down.length uint16(4) << 8 ) ); } } /// @notice Commitment to the memory state and program counter (pc) of the zkVM. /// @dev The "pre" and "post" fields of the ReceiptClaim are digests of the system state at the /// start are stop of execution. Programs are loaded into the zkVM by creating a memory image /// of the loaded program, and creating a system state for initializing the zkVM. This is /// known as the "image ID". struct SystemState { /// @notice Program counter. uint32 pc; /// @notice Root hash of a merkle tree which confirms the integrity of the memory image. bytes32 merkle_root; } library SystemStateLib { bytes32 constant TAG_DIGEST = sha256("risc0.SystemState"); function digest(SystemState memory state) internal pure returns (bytes32) { return sha256( abi.encodePacked( TAG_DIGEST, // down state.merkle_root, // data reverseByteOrderUint32(state.pc), // down.length uint16(1) << 8 ) ); } } /// @notice Exit condition indicated by the zkVM at the end of the guest execution. /// @dev Exit codes have a "system" part and a "user" part. Semantically, the system part is set to /// indicate the type of exit (e.g. halt, pause, or system split) and is directly controlled by the /// zkVM. The user part is an exit code, similar to exit codes used in Linux, chosen by the guest /// program to indicate additional information (e.g. 0 to indicate success or 1 to indicate an /// error). struct ExitCode { SystemExitCode system; uint8 user; } /// @notice Exit condition indicated by the zkVM at the end of the execution covered by this proof. /// @dev /// `Halted` indicates normal termination of a program with an interior exit code returned from the /// guest program. A halted program cannot be resumed. /// /// `Paused` indicates the execution ended in a paused state with an interior exit code set by the /// guest program. A paused program can be resumed such that execution picks up where it left /// of, with the same memory state. /// /// `SystemSplit` indicates the execution ended on a host-initiated system split. System split is /// mechanism by which the host can temporarily stop execution of the execution ended in a system /// split has no output and no conclusions can be drawn about whether the program will eventually /// halt. System split is used in continuations to split execution into individually provable segments. enum SystemExitCode { Halted, Paused, SystemSplit } /// @notice Output field in the `ReceiptClaim`, committing to a claimed journal and assumptions list. struct Output { /// @notice Digest of the journal committed to by the guest execution. bytes32 journalDigest; /// @notice Digest of the ordered list of `ReceiptClaim` digests corresponding to the /// calls to `env::verify` and `env::verify_integrity`. /// @dev Verifying the integrity of a `Receipt` corresponding to a `ReceiptClaim` with a /// non-empty assumptions list does not guarantee unconditionally any of the claims over the /// guest execution (i.e. if the assumptions list is non-empty, then the journal digest cannot /// be trusted to correspond to a genuine execution). The claims can be checked by additional /// verifying a `Receipt` for every digest in the assumptions list. bytes32 assumptionsDigest; } library OutputLib { bytes32 constant TAG_DIGEST = sha256("risc0.Output"); function digest(Output memory output) internal pure returns (bytes32) { return sha256( abi.encodePacked( TAG_DIGEST, // down output.journalDigest, output.assumptionsDigest, // down.length uint16(2) << 8 ) ); } } /// @notice Error raised when cryptographic verification of the zero-knowledge proof fails. error VerificationFailed(); /// @notice Verifier interface for RISC Zero receipts of execution. interface IRiscZeroVerifier { /// @notice Verify that the given seal is a valid RISC Zero proof of execution with the /// given image ID and journal digest. Reverts on failure. /// @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 journalDigest The SHA-256 digest of the journal bytes. function verify(bytes calldata seal, bytes32 imageId, bytes32 journalDigest) external view; /// @notice Verify that the given receipt is a valid RISC Zero receipt, ensuring the `seal` is /// valid a cryptographic proof of the execution with the given `claim`. Reverts on failure. /// @param receipt The receipt to be verified. function verifyIntegrity(Receipt calldata receipt) external view; }
// Copyright 2024 RISC Zero, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.9; import {SafeCast} from "openzeppelin/contracts/utils/math/SafeCast.sol"; import {reverseByteOrderUint16} from "./Util.sol"; /// @notice Structural hashing routines used for RISC Zero data structures. /// @dev /// StructHash implements hashing for structs, incorporating type tags for domain separation. /// The goals of this library are: /// * Collision resistance: it should not be possible to find two semantically distinct values that /// produce the same digest. /// * Simplicity: implementations should be simple to understand and write, as these methods must /// be implemented in multiple languages and environments, including zkSNARK circuits. /// * Incremental openings: it should be possible to incrementally open a nested struct without /// needing to open (very many) extra fields (i.e. the struct should be "Merkle-ized"). library StructHash { using SafeCast for uint256; // @notice Compute the struct digest with the given tag digest and digest fields down. function taggedStruct(bytes32 tagDigest, bytes32[] memory down) internal pure returns (bytes32) { bytes memory data = new bytes(0); return taggedStruct(tagDigest, down, data); } // @notice Compute the struct digest with the given tag digest, digest fields down, and data. function taggedStruct(bytes32 tagDigest, bytes32[] memory down, bytes memory data) internal pure returns (bytes32) { uint16 downLen = down.length.toUint16(); // swap the byte order to encode as little-endian. bytes2 downLenLE = bytes2((downLen << 8) | (downLen >> 8)); return sha256(abi.encodePacked(tagDigest, down, data, downLenLE)); } // @notice Add an element (head) to the incremental hash of a list (tail). function taggedListCons(bytes32 tagDigest, bytes32 head, bytes32 tail) internal pure returns (bytes32) { bytes32[] memory down = new bytes32[](2); down[0] = head; down[1] = tail; return taggedStruct(tagDigest, down); } // @notice Hash the list by using taggedListCons to repeatedly add to the head of the list. function taggedList(bytes32 tagDigest, bytes32[] memory list) internal pure returns (bytes32) { bytes32 curr = bytes32(0x0000000000000000000000000000000000000000000000000000000000000000); for (uint256 i = 0; i < list.length; i++) { curr = taggedListCons(tagDigest, list[list.length - 1 - i], curr); } return curr; } }
// Copyright 2024 RISC Zero, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.9; /// @notice reverse the byte order of the uint256 value. /// @dev Solidity uses a big-endian ABI encoding. Reversing the byte order before encoding /// ensure that the encoded value will be little-endian. /// Written by k06a. https://ethereum.stackexchange.com/a/83627 function reverseByteOrderUint256(uint256 input) pure returns (uint256 v) { v = input; // swap bytes v = ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8) | ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8); // swap 2-byte long pairs v = ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16) | ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16); // swap 4-byte long pairs v = ((v & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32) | ((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32); // swap 8-byte long pairs v = ((v & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64) | ((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64); // swap 16-byte long pairs v = (v >> 128) | (v << 128); } /// @notice reverse the byte order of the uint32 value. /// @dev Solidity uses a big-endian ABI encoding. Reversing the byte order before encoding /// ensure that the encoded value will be little-endian. /// Written by k06a. https://ethereum.stackexchange.com/a/83627 function reverseByteOrderUint32(uint32 input) pure returns (uint32 v) { v = input; // swap bytes v = ((v & 0xFF00FF00) >> 8) | ((v & 0x00FF00FF) << 8); // swap 2-byte long pairs v = (v >> 16) | (v << 16); } /// @notice reverse the byte order of the uint16 value. /// @dev Solidity uses a big-endian ABI encoding. Reversing the byte order before encoding /// ensure that the encoded value will be little-endian. /// Written by k06a. https://ethereum.stackexchange.com/a/83627 function reverseByteOrderUint16(uint16 input) pure returns (uint16 v) { v = input; // swap bytes v = (v >> 8) | ((v & 0x00FF) << 8); }
// Copyright 2025 RISC Zero, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.9; /// @notice Selectable interface for RISC Zero verifier. interface IRiscZeroSelectable { /// @notice A short key attached to the seal to select the correct verifier implementation. /// @dev The selector is taken from the hash of the verifier parameters. If two /// receipts have different selectors (i.e. different verifier parameters), then it can /// generally be assumed that they need distinct verifier implementations. This is used as /// part of the RISC Zero versioning mechanism. /// /// A selector is not intended to be collision resistant, in that it is possible to find /// two preimages that result in the same selector. This is acceptable since it's purpose /// to a route a request among a set of trusted verifiers, and to make errors of sending a /// receipt to a mismatching verifiers easier to debug. It is analogous to the ABI /// function selectors. function SELECTOR() external view returns (bytes4); }
{ "remappings": [ "forge-std/=../lib/forge-std/src/", "openzeppelin/=../lib/openzeppelin-contracts/", "@openzeppelin/contracts/=/Users/victorgraf/risc0/ethereum/lib/openzeppelin-contracts/contracts/", "erc4626-tests/=/Users/victorgraf/risc0/ethereum/lib/openzeppelin-contracts/lib/erc4626-tests/", "openzeppelin-contracts/=/Users/victorgraf/risc0/ethereum/lib/openzeppelin-contracts/contracts/" ], "optimizer": { "enabled": true, "runs": 10000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "cancun", "viaIR": true }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"bytes32","name":"control_root","type":"bytes32"},{"internalType":"bytes32","name":"bn254_control_id","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint8","name":"bits","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeCastOverflowedUintDowncast","type":"error"},{"inputs":[{"internalType":"bytes4","name":"received","type":"bytes4"},{"internalType":"bytes4","name":"expected","type":"bytes4"}],"name":"SelectorMismatch","type":"error"},{"inputs":[],"name":"VerificationFailed","type":"error"},{"inputs":[],"name":"BN254_CONTROL_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONTROL_ROOT_0","outputs":[{"internalType":"bytes16","name":"","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONTROL_ROOT_1","outputs":[{"internalType":"bytes16","name":"","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SELECTOR","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"seal","type":"bytes"},{"internalType":"bytes32","name":"imageId","type":"bytes32"},{"internalType":"bytes32","name":"journalDigest","type":"bytes32"}],"name":"verify","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"seal","type":"bytes"},{"internalType":"bytes32","name":"claimDigest","type":"bytes32"}],"internalType":"struct Receipt","name":"receipt","type":"tuple"}],"name":"verifyIntegrity","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[2]","name":"_pA","type":"uint256[2]"},{"internalType":"uint256[2][2]","name":"_pB","type":"uint256[2][2]"},{"internalType":"uint256[2]","name":"_pC","type":"uint256[2]"},{"internalType":"uint256[5]","name":"_pubSignals","type":"uint256[5]"}],"name":"verifyProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101808060405234610c92576040816121ac80380380916100208285610c96565b833981010312610c925780516020918201519091600883811c7eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff169084901b7fff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff001617601081811c7dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff1691901b7fffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000161780821c7bffffffff00000000ffffffff00000000ffffffff00000000ffffffff16911b7fffffffff00000000ffffffff00000000ffffffff00000000ffffffff000000001617604081811c77ffffffffffffffff0000000000000000ffffffffffffffff1691901b7fffffffffffffffff0000000000000000ffffffffffffffff00000000000000001617608081811c91901b176001600160801b031981811660a052608091821b16905260c08190526040517f72697363302e47726f74683136526563656970745665726966696572506172618152656d657465727360d01b602082810191909152905f9060269060025afa15610b11575f5190600881811c7eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff1691901b7fff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff001617601081811c7dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff1691901b7fffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff00001617602081811c7bffffffff00000000ffffffff00000000ffffffff00000000ffffffff1691901b7fffffffff00000000ffffffff00000000ffffffff00000000ffffffff000000001617604081811c77ffffffffffffffff0000000000000000ffffffffffffffff1691901b7fffffffffffffffff0000000000000000ffffffffffffffff00000000000000001617608081811c91901b179160e0604051916103068284610c96565b60068352601f19820136602085013760205f604051828101907f12ac9a25dcd5e1a832a9061a082c15dd1d61aa9c4d553505739d0f5d65dc3be482527f025aa744581ebe7ad91731911c898569106ff5a2d30f3eee2b23c60ee980acd4604082015260408152610377606082610c96565b604051918291518091835e8101838152039060025afa15610b11575f5161039d84610ccd565b5260205f604051828101907f0707b920bc978c02f292fae2036e057be54294114ccc3c8769d883f688a1423f82527f2e32a094b7589554f7bc357bf63481acd2d55555c203383782a4650787ff6642604082015260408152610400606082610c96565b604051918291518091835e8101838152039060025afa15610b11575f5161042684610cda565b5260205f604051828101907f0bca36e2cbe6394b3e249751853f961511011c7148e336f4fd974644850fc34782527f2ede7c9acf48cf3a3729fa3d68714e2a8435d4fa6db8f7f409c153b1fcdf9b8b604082015260408152610489606082610c96565b604051918291518091835e8101838152039060025afa15610b11575f51835160021015610b5257606084015260205f604051828101907f1b8af999dbfbb3927c091cc2aaf201e488cbacc3e2c6b6fb5a25f9112e04f2a782527f2b91a26aa92e1b6f5722949f192a81c850d586d81a60157f3e9cf04f679cccd6604082015260408152610517606082610c96565b604051918291518091835e8101838152039060025afa15610b11575f51835160031015610b5257608084015260205f604051828101907f2b5f494ed674235b8ac1750bdfd5a7615f002d4a1dcefeddd06eda5a076ccd0d82527f2fe520ad2020aab9cbba817fcbb9a863b8a76ff88f14f912c5e71665b2ad5e826040820152604081526105a5606082610c96565b604051918291518091835e8101838152039060025afa15610b11575f51835160041015610b525760a084015260205f604051828101907f0f1c3c0d5d9da0fa03666843cde4e82e869ba5252fce3c25d5940320b1c4d49382527f214bfcff74f425f6fe8c0d07b307482d8bc8bb2f3608f68287aa01bd0b69e809604082015260408152610633606082610c96565b604051918291518091835e8101838152039060025afa15610b11575f51835160051015610b525760c084015260205f601a6040517f72697363305f67726f746831362e566572696679696e674b6579000000000000815260025afa15610b11575f519460205f604051828101907f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e282527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d19266040820152604081526106f8606082610c96565b604051918291518091835e8101838152039060025afa15610b11575f519460205f604051828101907f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c82527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab60408201527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a760608201527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec86080820152608081526107c460a082610c96565b604051918291518091835e8101838152039060025afa15610b11575f519560205f604051828101907f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c282527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60408201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60608201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60808201526080815261089060a082610c96565b604051918291518091835e8101838152039060025afa15610b11575f519760205f604051828101907f03b03cd5effa95ac9bee94f1f5ef907157bda4812ccf0b4c91f42bb629f83a1c82527f1aa085ff28179a12d922dba0547057ccaae94b9d69cfaa4e60401fea7f3e033360408201527f110c10134f200b19f6490846d518c9aea868366efb7228ca5c91d2940d03076260608201527f1e60f31fcbf757e837e867178318832d0b2d74d59e2fea1c7142df187d3fc6d360808201526080815261095c60a082610c96565b604051918291518091835e8101838152039060025afa15610b11575f5160205f601d6040517f72697363305f67726f746831362e566572696679696e674b65792e4943000000815260025afa15610b11575f8051610140526101008190526060610120526020610160525b885180610100511015610b7a575f19810190808211610b66576101005190035f1901908111610b66578951811015610b5257610160519060051b8a0101519060405191610a176101205184610c96565b60028352610160516040903690850137610a3083610ccd565b52610a3a82610cda565b52604051610a4b6101605182610c96565b5f8152601f196101605101366101605183013781519061ffff8211610b3a5791604051928391610140516101605184015260408301815190916101605101905f905b808210610b1c575050509281610ad994600294935180926101605101825e019061ffff60f01b9061ff0060ff8260081c169160081b161760f01b16815203601d19810184520182610c96565b5f60405191805180916101605101845e820191818352806101605193039060025afa15610b11575f51610100805160010190526109c7565b6040513d5f823e3d90fd5b82518452610160518896509384019390920191600190910190610a8d565b506306dfcc6560e41b5f52601060045260245260445ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b505f92918b8b6040519661016051880195865260408801526060870152608086015260a085015260c0840152600560f81b8784015260c28352610bbe60e284610c96565b60405192518091845e820191818352806101605193039060025afa15610b11575f9182519060405194610160518601938452604086015260608501526080840152600360f81b60a084015260828352610c1860a284610c96565b60405192518091845e820191818352806101605193039060025afa15610b11575f516001600160e01b03191681526040516114c19182610ceb833960805182818161062c0152610efc015260a0518281816105d00152610f22015260c0518281816101a00152610f5a01525181818160c70152610e380152f35b5f80fd5b601f909101601f19168101906001600160401b03821190821017610cb957604052565b634e487b7160e01b5f52604160045260245ffd5b805115610b525760200190565b805160011015610b52576040019056fe60806040526004361015610011575f80fd5b5f3560e01c8063053c238d146100945780631599ead51461008f578063258038e21461008a57806334baeab9146100855780638989fa2e146100805780639181e4b11461007b578063ab750e75146100765763ffa1ad7414610071575f80fd5b6107a8565b610650565b6105f4565b610598565b6101de565b610189565b6100f4565b346100f0575f6003193601126100f0577fffffffff000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000001660805260206080f35b5f80fd5b346100f05760206003193601126100f05760043567ffffffffffffffff81116100f05780360360406003198201126100f0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd826004013591018112156100f057810160048101359067ffffffffffffffff82116100f0576024019080360382136100f057602461018793013591610e34565b005b346100f0575f6003193601126100f05760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b906004916044116100f057565b9060c491610104116100f057565b346100f0576101a06003193601126100f0576101f9366101c3565b3660c4116100f05761020a366101d0565b366101a4116100f0576040519061038082016040526101043561022c8161083b565b610124359361023a8561083b565b610144356102478161083b565b610164356102548161083b565b61018435916102628361083b565b60808701977f12ac9a25dcd5e1a832a9061a082c15dd1d61aa9c4d553505739d0f5d65dc3be4885260208801957f025aa744581ebe7ad91731911c898569106ff5a2d30f3eee2b23c60ee980acd487526102bc908961086c565b6102c690886108f8565b6102d09087610984565b6102da9086610a10565b6102e49085610a9c565b803585527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760209182013581030660a085015260443560c085015260643560e085015260843561010085015260a4356101208501527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e26101408501527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d19266101608501527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c6101808501527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab6101a08501527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a76101c08501527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec86101e0850152835161020085015290516102208401527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26102408401527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6102608401527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102808401527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa6102a084015281356102c084015201356102e08201527f03b03cd5effa95ac9bee94f1f5ef907157bda4812ccf0b4c91f42bb629f83a1c6103008201527f1aa085ff28179a12d922dba0547057ccaae94b9d69cfaa4e60401fea7f3e03336103208201527f110c10134f200b19f6490846d518c9aea868366efb7228ca5c91d2940d0307626103408201527f1e60f31fcbf757e837e867178318832d0b2d74d59e2fea1c7142df187d3fc6d36103609091015280805a6107cf1901602092600861030092fa9051165f5260205ff35b346100f0575f6003193601126100f05760206040517fffffffffffffffffffffffffffffffff000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000168152f35b346100f0575f6003193601126100f05760206040517fffffffffffffffffffffffffffffffff000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000168152f35b346100f05760606003193601126100f05760043567ffffffffffffffff81116100f057366023820112156100f05780600401359067ffffffffffffffff82116100f05736602483830101116100f057610187916024359060246044359301610b28565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040810190811067ffffffffffffffff8211176106fc57604052565b6106b3565b60a0810190811067ffffffffffffffff8211176106fc57604052565b6060810190811067ffffffffffffffff8211176106fc57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176106fc57604052565b60405190610789604083610739565b565b6040519061078960a083610739565b906107896040519283610739565b346100f0575f6003193601126100f0576040516107c4816106e0565b60058152604060208201917f332e302e3000000000000000000000000000000000000000000000000000000083527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8351948593602085525180918160208701528686015e5f85828601015201168101030190f35b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001111561086457565b5f805260205ff35b604051917f0707b920bc978c02f292fae2036e057be54294114ccc3c8769d883f688a1423f83527f2e32a094b7589554f7bc357bf63481acd2d55555c203383782a4650787ff664260208401526040830190815260408360608160076107cf195a01fa1561086457604092608091835190526020830151606082015260066107cf195a01fa1561086457565b604051917f0bca36e2cbe6394b3e249751853f961511011c7148e336f4fd974644850fc34783527f2ede7c9acf48cf3a3729fa3d68714e2a8435d4fa6db8f7f409c153b1fcdf9b8b60208401526040830190815260408360608160076107cf195a01fa1561086457604092608091835190526020830151606082015260066107cf195a01fa1561086457565b604051917f1b8af999dbfbb3927c091cc2aaf201e488cbacc3e2c6b6fb5a25f9112e04f2a783527f2b91a26aa92e1b6f5722949f192a81c850d586d81a60157f3e9cf04f679cccd660208401526040830190815260408360608160076107cf195a01fa1561086457604092608091835190526020830151606082015260066107cf195a01fa1561086457565b604051917f2b5f494ed674235b8ac1750bdfd5a7615f002d4a1dcefeddd06eda5a076ccd0d83527f2fe520ad2020aab9cbba817fcbb9a863b8a76ff88f14f912c5e71665b2ad5e8260208401526040830190815260408360608160076107cf195a01fa1561086457604092608091835190526020830151606082015260066107cf195a01fa1561086457565b604051917f0f1c3c0d5d9da0fa03666843cde4e82e869ba5252fce3c25d5940320b1c4d49383527f214bfcff74f425f6fe8c0d07b307482d8bc8bb2f3608f68287aa01bd0b69e80960208401526040830190815260408360608160076107cf195a01fa1561086457604092608091835190526020830151606082015260066107cf195a01fa1561086457565b91610bdd90610789945f6080604051610b4081610701565b828152826020820152604051610b55816106e0565b83815283602082015260408201528260608201520152610b96610b7661077a565b915f83525f6020840152610b8861077a565b9081525f6020820152611426565b90610b9f61078b565b9283527fa3acc27117418996340b84e5a90f3ef4c49d22c79e44aad822ec9c313e1eb8e2602084015260408301525f6060830152608082015261111f565b91610e34565b906004116100f05790600490565b90929192836004116100f05783116100f057600401916003190190565b919091357fffffffff0000000000000000000000000000000000000000000000000000000081169260048110610c42575050565b7fffffffff00000000000000000000000000000000000000000000000000000000929350829060040360031b1b161690565b9080601f830112156100f05760405191610c8f604084610739565b8290604081019283116100f057905b828210610cab5750505090565b8135815260209182019101610c9e565b610100818303126100f05760405191610cd38361071d565b610cdd8183610c74565b835280605f830112156100f0576040918251610cf98482610739565b8060c08301928484116100f05785809101915b848310610d2c575050506020850152610d259190610c74565b9082015290565b602090610d398785610c74565b8152019101908590610d0c565b908160209103126100f0575180151581036100f05790565b905f905b60028210610d6f57505050565b6020806001928551815201930191019091610d62565b905f905b60058210610d9657505050565b6020806001928551815201930191019091610d89565b919493929094610dc1836101a0810197610d5e565b5f604084015b60028210610def5750505081610de86101009260c061078996950190610d5e565b0190610d85565b82515f90825b60028310610e13575050506020604060019201930191019091610dc7565b6020806001928451815201920192019190610df5565b6040513d5f823e3d90fd5b90917f0000000000000000000000000000000000000000000000000000000000000000610e92610e6d610e678686610be3565b90610c0e565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b7fffffffff00000000000000000000000000000000000000000000000000000000821603611029575090610ede610ed684610ece602095611261565b969094610bf1565b810190610cbb565b90610fb282519160408585015194015195610ef960a061079a565b917f000000000000000000000000000000000000000000000000000000000000000060801c83527f000000000000000000000000000000000000000000000000000000000000000060801c8784015260801c604083015260801c60608201527f0000000000000000000000000000000000000000000000000000000000000000608082015260405195869485947f34baeab900000000000000000000000000000000000000000000000000000000865260048601610dac565b0381305afa908115611024575f91610ff5575b5015610fcd57565b7f439cc0cd000000000000000000000000000000000000000000000000000000005f5260045ffd5b611017915060203d60201161101d575b61100f8183610739565b810190610d46565b5f610fc5565b503d611005565b610e29565b61108d9061103a610e678686610be3565b7fb8b38d4c000000000000000000000000000000000000000000000000000000005f527fffffffff0000000000000000000000000000000000000000000000000000000090811660045216602452604490565b5ffd5b6003111561109a57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60205f60126040517f72697363302e52656365697074436c61696d0000000000000000000000000000815260025afa15611024575f5190565b51600381101561109a5790565b805191908290602001825e015f815290565b5f6112516020926112456111316110c7565b61121960608401519380519088810151906040608082015191019061118861116c6111828d6111786111638751611100565b61116c81611090565b60181b63ff0000001690565b9551015160ff1690565b60ff1690565b9261040094604051998a988e8a019692947fffffffff000000000000000000000000000000000000000000000000000000009460aa999686947fffff00000000000000000000000000000000000000000000000000000000000099948b5260208b015260408a01526060890152608088015260e01b1660a086015260e01b1660a484015260f01b1660a88201520190565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282610739565b6040519182809261110d565b039060025afa15611024575f5190565b8060081c9060081b907cff000000ff000000ff000000ff000000ff000000ff000000ff000000ff7dff000000ff000000ff000000ff000000ff000000ff000000ff000000ff007fff000000ff000000ff000000ff000000ff000000ff000000ff000000ff00000084167eff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000084161760101c931691161760101b176113477bffffffff00000000ffffffff00000000ffffffff00000000ffffffff7fffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000831660201c921660201b90565b1761139877ffffffffffffffff0000000000000000ffffffffffffffff6113907fffffffffffffffff0000000000000000ffffffffffffffff0000000000000000841660401c90565b921660401b90565b176113ad6113a68260801c90565b9160801b90565b17907fffffffffffffffffffffffffffffffff0000000000000000000000000000000061141d6113f56113e08560801c90565b6fffffffffffffffffffffffffffffffff1690565b60801b7fffffffffffffffffffffffffffffffff000000000000000000000000000000001690565b9260801b169190565b60205f600c6040517f72697363302e4f75747075740000000000000000000000000000000000000000815260025afa15611024575f80518251602093840151604080518087019490945283019190915260608201527f02000000000000000000000000000000000000000000000000000000000000006080820152606281526112519061124560828261073956fea164736f6c634300081a000aa54dc85ac99f851c92d7c96d7318af41dbe7c0194edfcc37eb4d422a998c1f5604446e66d300eb7fb45c9726bb53c793dda407a62e9601618bb43c5c14657ac0
Deployed Bytecode
0x60806040526004361015610011575f80fd5b5f3560e01c8063053c238d146100945780631599ead51461008f578063258038e21461008a57806334baeab9146100855780638989fa2e146100805780639181e4b11461007b578063ab750e75146100765763ffa1ad7414610071575f80fd5b6107a8565b610650565b6105f4565b610598565b6101de565b610189565b6100f4565b346100f0575f6003193601126100f0577fffffffff000000000000000000000000000000000000000000000000000000007f73c457ba000000000000000000000000000000000000000000000000000000001660805260206080f35b5f80fd5b346100f05760206003193601126100f05760043567ffffffffffffffff81116100f05780360360406003198201126100f0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd826004013591018112156100f057810160048101359067ffffffffffffffff82116100f0576024019080360382136100f057602461018793013591610e34565b005b346100f0575f6003193601126100f05760206040517f04446e66d300eb7fb45c9726bb53c793dda407a62e9601618bb43c5c14657ac08152f35b906004916044116100f057565b9060c491610104116100f057565b346100f0576101a06003193601126100f0576101f9366101c3565b3660c4116100f05761020a366101d0565b366101a4116100f0576040519061038082016040526101043561022c8161083b565b610124359361023a8561083b565b610144356102478161083b565b610164356102548161083b565b61018435916102628361083b565b60808701977f12ac9a25dcd5e1a832a9061a082c15dd1d61aa9c4d553505739d0f5d65dc3be4885260208801957f025aa744581ebe7ad91731911c898569106ff5a2d30f3eee2b23c60ee980acd487526102bc908961086c565b6102c690886108f8565b6102d09087610984565b6102da9086610a10565b6102e49085610a9c565b803585527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760209182013581030660a085015260443560c085015260643560e085015260843561010085015260a4356101208501527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e26101408501527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d19266101608501527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c6101808501527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab6101a08501527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a76101c08501527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec86101e0850152835161020085015290516102208401527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26102408401527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6102608401527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102808401527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa6102a084015281356102c084015201356102e08201527f03b03cd5effa95ac9bee94f1f5ef907157bda4812ccf0b4c91f42bb629f83a1c6103008201527f1aa085ff28179a12d922dba0547057ccaae94b9d69cfaa4e60401fea7f3e03336103208201527f110c10134f200b19f6490846d518c9aea868366efb7228ca5c91d2940d0307626103408201527f1e60f31fcbf757e837e867178318832d0b2d74d59e2fea1c7142df187d3fc6d36103609091015280805a6107cf1901602092600861030092fa9051165f5260205ff35b346100f0575f6003193601126100f05760206040517fffffffffffffffffffffffffffffffff000000000000000000000000000000007f561f8c992a424deb37ccdf4e19c0e7db00000000000000000000000000000000168152f35b346100f0575f6003193601126100f05760206040517fffffffffffffffffffffffffffffffff000000000000000000000000000000007f41af18736dc9d7921c859fc95ac84da500000000000000000000000000000000168152f35b346100f05760606003193601126100f05760043567ffffffffffffffff81116100f057366023820112156100f05780600401359067ffffffffffffffff82116100f05736602483830101116100f057610187916024359060246044359301610b28565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040810190811067ffffffffffffffff8211176106fc57604052565b6106b3565b60a0810190811067ffffffffffffffff8211176106fc57604052565b6060810190811067ffffffffffffffff8211176106fc57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176106fc57604052565b60405190610789604083610739565b565b6040519061078960a083610739565b906107896040519283610739565b346100f0575f6003193601126100f0576040516107c4816106e0565b60058152604060208201917f332e302e3000000000000000000000000000000000000000000000000000000083527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8351948593602085525180918160208701528686015e5f85828601015201168101030190f35b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001111561086457565b5f805260205ff35b604051917f0707b920bc978c02f292fae2036e057be54294114ccc3c8769d883f688a1423f83527f2e32a094b7589554f7bc357bf63481acd2d55555c203383782a4650787ff664260208401526040830190815260408360608160076107cf195a01fa1561086457604092608091835190526020830151606082015260066107cf195a01fa1561086457565b604051917f0bca36e2cbe6394b3e249751853f961511011c7148e336f4fd974644850fc34783527f2ede7c9acf48cf3a3729fa3d68714e2a8435d4fa6db8f7f409c153b1fcdf9b8b60208401526040830190815260408360608160076107cf195a01fa1561086457604092608091835190526020830151606082015260066107cf195a01fa1561086457565b604051917f1b8af999dbfbb3927c091cc2aaf201e488cbacc3e2c6b6fb5a25f9112e04f2a783527f2b91a26aa92e1b6f5722949f192a81c850d586d81a60157f3e9cf04f679cccd660208401526040830190815260408360608160076107cf195a01fa1561086457604092608091835190526020830151606082015260066107cf195a01fa1561086457565b604051917f2b5f494ed674235b8ac1750bdfd5a7615f002d4a1dcefeddd06eda5a076ccd0d83527f2fe520ad2020aab9cbba817fcbb9a863b8a76ff88f14f912c5e71665b2ad5e8260208401526040830190815260408360608160076107cf195a01fa1561086457604092608091835190526020830151606082015260066107cf195a01fa1561086457565b604051917f0f1c3c0d5d9da0fa03666843cde4e82e869ba5252fce3c25d5940320b1c4d49383527f214bfcff74f425f6fe8c0d07b307482d8bc8bb2f3608f68287aa01bd0b69e80960208401526040830190815260408360608160076107cf195a01fa1561086457604092608091835190526020830151606082015260066107cf195a01fa1561086457565b91610bdd90610789945f6080604051610b4081610701565b828152826020820152604051610b55816106e0565b83815283602082015260408201528260608201520152610b96610b7661077a565b915f83525f6020840152610b8861077a565b9081525f6020820152611426565b90610b9f61078b565b9283527fa3acc27117418996340b84e5a90f3ef4c49d22c79e44aad822ec9c313e1eb8e2602084015260408301525f6060830152608082015261111f565b91610e34565b906004116100f05790600490565b90929192836004116100f05783116100f057600401916003190190565b919091357fffffffff0000000000000000000000000000000000000000000000000000000081169260048110610c42575050565b7fffffffff00000000000000000000000000000000000000000000000000000000929350829060040360031b1b161690565b9080601f830112156100f05760405191610c8f604084610739565b8290604081019283116100f057905b828210610cab5750505090565b8135815260209182019101610c9e565b610100818303126100f05760405191610cd38361071d565b610cdd8183610c74565b835280605f830112156100f0576040918251610cf98482610739565b8060c08301928484116100f05785809101915b848310610d2c575050506020850152610d259190610c74565b9082015290565b602090610d398785610c74565b8152019101908590610d0c565b908160209103126100f0575180151581036100f05790565b905f905b60028210610d6f57505050565b6020806001928551815201930191019091610d62565b905f905b60058210610d9657505050565b6020806001928551815201930191019091610d89565b919493929094610dc1836101a0810197610d5e565b5f604084015b60028210610def5750505081610de86101009260c061078996950190610d5e565b0190610d85565b82515f90825b60028310610e13575050506020604060019201930191019091610dc7565b6020806001928451815201920192019190610df5565b6040513d5f823e3d90fd5b90917f73c457ba00000000000000000000000000000000000000000000000000000000610e92610e6d610e678686610be3565b90610c0e565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b7fffffffff00000000000000000000000000000000000000000000000000000000821603611029575090610ede610ed684610ece602095611261565b969094610bf1565b810190610cbb565b90610fb282519160408585015194015195610ef960a061079a565b917f41af18736dc9d7921c859fc95ac84da50000000000000000000000000000000060801c83527f561f8c992a424deb37ccdf4e19c0e7db0000000000000000000000000000000060801c8784015260801c604083015260801c60608201527f04446e66d300eb7fb45c9726bb53c793dda407a62e9601618bb43c5c14657ac0608082015260405195869485947f34baeab900000000000000000000000000000000000000000000000000000000865260048601610dac565b0381305afa908115611024575f91610ff5575b5015610fcd57565b7f439cc0cd000000000000000000000000000000000000000000000000000000005f5260045ffd5b611017915060203d60201161101d575b61100f8183610739565b810190610d46565b5f610fc5565b503d611005565b610e29565b61108d9061103a610e678686610be3565b7fb8b38d4c000000000000000000000000000000000000000000000000000000005f527fffffffff0000000000000000000000000000000000000000000000000000000090811660045216602452604490565b5ffd5b6003111561109a57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60205f60126040517f72697363302e52656365697074436c61696d0000000000000000000000000000815260025afa15611024575f5190565b51600381101561109a5790565b805191908290602001825e015f815290565b5f6112516020926112456111316110c7565b61121960608401519380519088810151906040608082015191019061118861116c6111828d6111786111638751611100565b61116c81611090565b60181b63ff0000001690565b9551015160ff1690565b60ff1690565b9261040094604051998a988e8a019692947fffffffff000000000000000000000000000000000000000000000000000000009460aa999686947fffff00000000000000000000000000000000000000000000000000000000000099948b5260208b015260408a01526060890152608088015260e01b1660a086015260e01b1660a484015260f01b1660a88201520190565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282610739565b6040519182809261110d565b039060025afa15611024575f5190565b8060081c9060081b907cff000000ff000000ff000000ff000000ff000000ff000000ff000000ff7dff000000ff000000ff000000ff000000ff000000ff000000ff000000ff007fff000000ff000000ff000000ff000000ff000000ff000000ff000000ff00000084167eff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000084161760101c931691161760101b176113477bffffffff00000000ffffffff00000000ffffffff00000000ffffffff7fffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000831660201c921660201b90565b1761139877ffffffffffffffff0000000000000000ffffffffffffffff6113907fffffffffffffffff0000000000000000ffffffffffffffff0000000000000000841660401c90565b921660401b90565b176113ad6113a68260801c90565b9160801b90565b17907fffffffffffffffffffffffffffffffff0000000000000000000000000000000061141d6113f56113e08560801c90565b6fffffffffffffffffffffffffffffffff1690565b60801b7fffffffffffffffffffffffffffffffff000000000000000000000000000000001690565b9260801b169190565b60205f600c6040517f72697363302e4f75747075740000000000000000000000000000000000000000815260025afa15611024575f80518251602093840151604080518087019490945283019190915260608201527f02000000000000000000000000000000000000000000000000000000000000006080820152606281526112519061124560828261073956fea164736f6c634300081a000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
a54dc85ac99f851c92d7c96d7318af41dbe7c0194edfcc37eb4d422a998c1f5604446e66d300eb7fb45c9726bb53c793dda407a62e9601618bb43c5c14657ac0
-----Decoded View---------------
Arg [0] : control_root (bytes32): 0xa54dc85ac99f851c92d7c96d7318af41dbe7c0194edfcc37eb4d422a998c1f56
Arg [1] : bn254_control_id (bytes32): 0x04446e66d300eb7fb45c9726bb53c793dda407a62e9601618bb43c5c14657ac0
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : a54dc85ac99f851c92d7c96d7318af41dbe7c0194edfcc37eb4d422a998c1f56
Arg [1] : 04446e66d300eb7fb45c9726bb53c793dda407a62e9601618bb43c5c14657ac0
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.