false
false
0
The new Blockscout UI is now open source! Learn how to deploy it here

Contract Address Details

0x993d0FbA7E0231F804f9C22B56AF5E8D1C33e269

Contract Name
SigVerifyLib
Creator
0x4779d1–4df7b8 at 0xba3348–c49161
Balance
0 ETH
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
8678
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
SigVerifyLib




Optimization enabled
true
Compiler version
v0.8.30+commit.73712a01




Optimization runs
200
EVM Version
prague




Verified at
2025-12-15T12:46:01.945337Z

Constructor Arguments

0x0000000000000000000000009c57419c4297f9fdfb22dcbf06037a3fd92fb232

Arg [0] (address) : 0x9c57419c4297f9fdfb22dcbf06037a3fd92fb232

              

contracts/layer1/automata-attestation/utils/SigVerifyLib.sol

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.24;

import "../interfaces/ISigVerifyLib.sol";
import "./BytesUtils.sol";

/// @title SigVerifyLib
/// @custom:security-contact security@taiko.xyz
// Library for verifying signatures
contract SigVerifyLib is ISigVerifyLib {
    using BytesUtils for bytes;

    address private immutable __es256Verifier;

    constructor(address es256Verifier) {
        __es256Verifier = es256Verifier;
    }

    function verifyES256Signature(
        bytes calldata tbs,
        bytes calldata signature,
        bytes calldata publicKey
    )
        external
        view
        returns (bool sigValid)
    {
        // Parse signature
        if (signature.length != 64) {
            return false;
        }
        uint256 r = uint256(bytes32(signature.substring(0, 32)));
        uint256 s = uint256(bytes32(signature.substring(32, 32)));
        // Parse public key
        if (publicKey.length != 64) {
            return false;
        }
        uint256 gx = uint256(bytes32(publicKey.substring(0, 32)));
        uint256 gy = uint256(bytes32(publicKey.substring(32, 32)));

        // Verify signature
        bytes memory args = abi.encode(sha256(tbs), r, s, gx, gy);
        (bool success, bytes memory ret) = __es256Verifier.staticcall(args);
        assert(success); // never reverts, always returns 0 or 1

        return abi.decode(ret, (uint256)) == 1;
    }
}
        

contracts/layer1/automata-attestation/interfaces/ISigVerifyLib.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

/// @title ISigVerifyLib
/// @custom:security-contact security@taiko.xyz
interface ISigVerifyLib {
    function verifyES256Signature(
        bytes memory tbs,
        bytes memory signature,
        bytes memory publicKey
    )
        external
        view
        returns (bool sigValid);
}
          

contracts/layer1/automata-attestation/utils/BytesUtils.sol

// SPDX-License-Identifier: BSD 2-Clause License
pragma solidity ^0.8.24;

// Inspired by ensdomains/dnssec-oracle - BSD-2-Clause license
// https://github.com/ensdomains/dnssec-oracle/blob/master/contracts/BytesUtils.sol
/// @title BytesUtils
/// @custom:security-contact security@taiko.xyz
library BytesUtils {
    error INVALID_OFFSET();
    error INVALID_IDX();
    error UNEXPECTED_LEN();
    error UNEXPECTED_IDX();
    error UNEXPECTED_OFFSET();

    /*
    * @dev Returns the keccak-256 hash of a byte range.
    * @param self The byte string to hash.
    * @param offset The position to start hashing at.
    * @param len The number of bytes to hash.
    * @return The hash of the byte range.
    */
    function keccak(
        bytes memory self,
        uint256 offset,
        uint256 len
    )
        internal
        pure
        returns (bytes32 ret)
    {
        require(offset + len <= self.length, INVALID_OFFSET());
        assembly {
            ret := keccak256(add(add(self, 32), offset), len)
        }
    }

    /*
    * @dev Returns true if the two byte ranges are equal.
    * @param self The first byte range to compare.
    * @param offset The offset into the first byte range.
    * @param other The second byte range to compare.
    * @param otherOffset The offset into the second byte range.
    * @param len The number of bytes to compare
    * @return true if the byte ranges are equal, false otherwise.
    */
    function equals(
        bytes memory self,
        uint256 offset,
        bytes memory other,
        uint256 otherOffset,
        uint256 len
    )
        internal
        pure
        returns (bool)
    {
        return keccak(self, offset, len) == keccak(other, otherOffset, len);
    }

    /*
    * @dev Returns the 8-bit number at the specified index of self.
    * @param self The byte string.
    * @param idx The index into the bytes
    * @return The specified 8 bits of the string, interpreted as an integer.
    */
    function readUint8(bytes memory self, uint256 idx) internal pure returns (uint8 ret) {
        return uint8(self[idx]);
    }

    /*
    * @dev Returns the 16-bit number at the specified index of self.
    * @param self The byte string.
    * @param idx The index into the bytes
    * @return The specified 16 bits of the string, interpreted as an integer.
    */
    function readUint16(bytes memory self, uint256 idx) internal pure returns (uint16 ret) {
        require(idx + 2 <= self.length, INVALID_IDX());
        assembly {
            ret := and(mload(add(add(self, 2), idx)), 0xFFFF)
        }
    }

    /*
    * @dev Returns the n byte value at the specified index of self.
    * @param self The byte string.
    * @param idx The index into the bytes.
    * @param len The number of bytes.
    * @return The specified 32 bytes of the string.
    */
    function readBytesN(
        bytes memory self,
        uint256 idx,
        uint256 len
    )
        internal
        pure
        returns (bytes32 ret)
    {
        require(len <= 32, UNEXPECTED_LEN());
        require(idx + len <= self.length, UNEXPECTED_IDX());
        assembly {
            let mask := not(sub(exp(256, sub(32, len)), 1))
            ret := and(mload(add(add(self, 32), idx)), mask)
        }
    }

    function memcpy(uint256 dest, uint256 src, uint256 len) private pure {
        assembly {
            mcopy(dest, src, len)
        }
    }

    /*
    * @dev Copies a substring into a new byte string.
    * @param self The byte string to copy from.
    * @param offset The offset to start copying at.
    * @param len The number of bytes to copy.
    */
    function substring(
        bytes memory self,
        uint256 offset,
        uint256 len
    )
        internal
        pure
        returns (bytes memory)
    {
        require(offset + len <= self.length, UNEXPECTED_OFFSET());

        bytes memory ret = new bytes(len);
        uint256 dest;
        uint256 src;

        assembly {
            dest := add(ret, 32)
            src := add(add(self, 32), offset)
        }
        memcpy(dest, src, len);

        return ret;
    }

    function compareBytes(bytes memory a, bytes memory b) internal pure returns (bool) {
        return keccak256(a) == keccak256(b);
    }
}
          

Compiler Settings

{"viaIR":true,"remappings":["openzeppelin/=node_modules/@openzeppelin/","@openzeppelin/=node_modules/@openzeppelin/","@openzeppelin-upgrades/contracts/=node_modules/@openzeppelin/contracts-upgradeable/","@risc0/contracts/=node_modules/risc0-ethereum/contracts/src/","@solady/=node_modules/solady/","solady/src/=node_modules/solady/src/","solady/utils/=node_modules/solady/src/utils/","@optimism/=node_modules/optimism/","@sp1-contracts/=node_modules/sp1-contracts/contracts/","forge-std/=node_modules/forge-std/","@p256-verifier/contracts/=node_modules/p256-verifier/src/","@eth-fabric/urc/=node_modules/urc/src/","ds-test/=node_modules/ds-test/","src/=contracts/","test/=test/","script/=script/","optimism/=node_modules/optimism/","p256-verifier/=node_modules/p256-verifier/","risc0-ethereum/=node_modules/risc0-ethereum/","sp1-contracts/=node_modules/sp1-contracts/","urc/=node_modules/urc/"],"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{"contracts/layer1/core/libs/LibInboxSetup.sol":{"LibInboxSetup":"0xf88Ef5437749A225621101BE8C1BE1A0cE967758"},"contracts/layer1/core/libs/LibForcedInclusion.sol":{"LibForcedInclusion":"0xd1a27F331c17eD8Cbb6DAbce67A42d6b8a6B0e14"}},"evmVersion":"prague"}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"es256Verifier","internalType":"address"}]},{"type":"error","name":"UNEXPECTED_OFFSET","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"sigValid","internalType":"bool"}],"name":"verifyES256Signature","inputs":[{"type":"bytes","name":"tbs","internalType":"bytes"},{"type":"bytes","name":"signature","internalType":"bytes"},{"type":"bytes","name":"publicKey","internalType":"bytes"}]}]
              

Contract Creation Code

Verify & Publish
0x60a034606657601f61045f38819003918201601f19168301916001600160401b03831184841017606a57808492602094604052833981010312606657516001600160a01b03811681036066576080526040516103e0908161007f8239608051816102e20152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe60806040526004361015610011575f80fd5b5f3560e01c639a65705414610024575f80fd5b346100b15760603660031901126100b15760043567ffffffffffffffff81116100b1576100559036906004016100b5565b60243567ffffffffffffffff81116100b1576100759036906004016100b5565b9190926044359267ffffffffffffffff84116100b15760209461009f6100a79536906004016100b5565b949093610203565b6040519015158152f35b5f80fd5b9181601f840112156100b15782359167ffffffffffffffff83116100b157602083818601950101116100b157565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff82111761011957604052565b6100e3565b67ffffffffffffffff811161011957601f01601f191660200190565b9291926101468261011e565b9161015460405193846100f7565b8294818452818301116100b1578281602093845f960137010152565b602081519101519060208110610184575090565b5f199060200360031b1b1690565b908092918237015f815290565b6040513d5f823e3d90fd5b3d156101d4573d906101bb8261011e565b916101c960405193846100f7565b82523d5f602084013e565b606090565b156101e057565b634e487b7160e01b5f52600160045260245ffd5b908160209103126100b1575190565b92916040830361032c5761022d61023a61023f9261023261022d61022836898561013a565b610336565b610170565b95369161013a565b610377565b936040860361032c5760209161027061022d61023a5f9461026861022d6102288d36908561013a565b9a369161013a565b9461028060405180938193610192565b039060025afa1561032757600193610323936102de5f94936102d086958651956040519586946020860198899192608093969594919660a084019784526020840152604083015260608201520152565b03601f1981018352826100f7565b51907f00000000000000000000000000000000000000000000000000000000000000005afa61031461030e6101aa565b916101d9565b602080825183010191016101f4565b1490565b61019f565b5050505050505f90565b80516020116103685760408051919061034f81846100f7565b602083526020809281850192601f190136843701905e90565b6343733a0960e11b5f5260045ffd5b80516040116103685760408051919061039081846100f7565b60208352604060209283850192601f190136843701905e9056fea26469706673582212207932b1e3dde6c453506eca0dcb2e0c74033b6fff6c0798d60eb8db6e8e028f4764736f6c634300081e00330000000000000000000000009c57419c4297f9fdfb22dcbf06037a3fd92fb232

Deployed ByteCode

0x60806040526004361015610011575f80fd5b5f3560e01c639a65705414610024575f80fd5b346100b15760603660031901126100b15760043567ffffffffffffffff81116100b1576100559036906004016100b5565b60243567ffffffffffffffff81116100b1576100759036906004016100b5565b9190926044359267ffffffffffffffff84116100b15760209461009f6100a79536906004016100b5565b949093610203565b6040519015158152f35b5f80fd5b9181601f840112156100b15782359167ffffffffffffffff83116100b157602083818601950101116100b157565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff82111761011957604052565b6100e3565b67ffffffffffffffff811161011957601f01601f191660200190565b9291926101468261011e565b9161015460405193846100f7565b8294818452818301116100b1578281602093845f960137010152565b602081519101519060208110610184575090565b5f199060200360031b1b1690565b908092918237015f815290565b6040513d5f823e3d90fd5b3d156101d4573d906101bb8261011e565b916101c960405193846100f7565b82523d5f602084013e565b606090565b156101e057565b634e487b7160e01b5f52600160045260245ffd5b908160209103126100b1575190565b92916040830361032c5761022d61023a61023f9261023261022d61022836898561013a565b610336565b610170565b95369161013a565b610377565b936040860361032c5760209161027061022d61023a5f9461026861022d6102288d36908561013a565b9a369161013a565b9461028060405180938193610192565b039060025afa1561032757600193610323936102de5f94936102d086958651956040519586946020860198899192608093969594919660a084019784526020840152604083015260608201520152565b03601f1981018352826100f7565b51907f0000000000000000000000009c57419c4297f9fdfb22dcbf06037a3fd92fb2325afa61031461030e6101aa565b916101d9565b602080825183010191016101f4565b1490565b61019f565b5050505050505f90565b80516020116103685760408051919061034f81846100f7565b602083526020809281850192601f190136843701905e90565b6343733a0960e11b5f5260045ffd5b80516040116103685760408051919061039081846100f7565b60208352604060209283850192601f190136843701905e9056fea26469706673582212207932b1e3dde6c453506eca0dcb2e0c74033b6fff6c0798d60eb8db6e8e028f4764736f6c634300081e0033

External libraries