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
- 2026-06-23T13:32:08.712797Z
Constructor Arguments
0x000000000000000000000000936d8dcd9b731d3fe146bf3e1520e9d790a3a67d
Arg [0] (address) : 0x936d8dcd9b731d3fe146bf3e1520e9d790a3a67d
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.26;
// 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":false,"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":{},"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
0x60a0604052348015600e575f5ffd5b506040516105e43803806105e4833981016040819052602b91603b565b6001600160a01b03166080526066565b5f60208284031215604a575f5ffd5b81516001600160a01b0381168114605f575f5ffd5b9392505050565b60805161056661007e5f395f61024f01526105665ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c80639a6570541461002d575b5f5ffd5b61004061003b3660046103e2565b610054565b604051901515815260200160405180910390f35b5f6040841461006457505f6102f5565b5f6100aa5f602088888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509294939250506102ff9050565b6100b390610481565b5f1c90505f6100fd60208089898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509294939250506102ff9050565b61010690610481565b90506040841461011a575f925050506102f5565b5f6101605f602088888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509294939250506102ff9050565b61016990610481565b5f1c90505f6101b360208089898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509294939250506102ff9050565b6101bc90610481565b5f1c90505f60028c8c6040516101d39291906104a7565b602060405180830381855afa1580156101ee573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061021191906104b6565b6040805160208101929092528101869052606081018590526080810184905260a0810183905260c00160405160208183030381529060405290505f5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168360405161028591906104cd565b5f60405180830381855afa9150503d805f81146102bd576040519150601f19603f3d011682016040523d82523d5f602084013e6102c2565b606091505b5091509150816102d4576102d46104e3565b808060200190518101906102e891906104b6565b6001149750505050505050505b9695505050505050565b825160609061030e83856104f7565b111561032d576040516343733a0960e11b815260040160405180910390fd5b5f8267ffffffffffffffff8111156103475761034761051c565b6040519080825280601f01601f191660200182016040528015610371576020820181803683370190505b50905060208082019086860101610389828287610394565b509095945050505050565b8082845e505050565b5f5f83601f8401126103ad575f5ffd5b50813567ffffffffffffffff8111156103c4575f5ffd5b6020830191508360208285010111156103db575f5ffd5b9250929050565b5f5f5f5f5f5f606087890312156103f7575f5ffd5b863567ffffffffffffffff81111561040d575f5ffd5b61041989828a0161039d565b909750955050602087013567ffffffffffffffff811115610438575f5ffd5b61044489828a0161039d565b909550935050604087013567ffffffffffffffff811115610463575f5ffd5b61046f89828a0161039d565b979a9699509497509295939492505050565b805160208083015191908110156104a1575f198160200360031b1b821691505b50919050565b818382375f9101908152919050565b5f602082840312156104c6575f5ffd5b5051919050565b5f82518060208501845e5f920191825250919050565b634e487b7160e01b5f52600160045260245ffd5b8082018082111561051657634e487b7160e01b5f52601160045260245ffd5b92915050565b634e487b7160e01b5f52604160045260245ffdfea264697066735822122089f98c8af4e54458c9476a97fd23ee013d01838f3963967f5b361d982cf782b264736f6c634300081e0033000000000000000000000000936d8dcd9b731d3fe146bf3e1520e9d790a3a67d
Deployed ByteCode
0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c80639a6570541461002d575b5f5ffd5b61004061003b3660046103e2565b610054565b604051901515815260200160405180910390f35b5f6040841461006457505f6102f5565b5f6100aa5f602088888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509294939250506102ff9050565b6100b390610481565b5f1c90505f6100fd60208089898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509294939250506102ff9050565b61010690610481565b90506040841461011a575f925050506102f5565b5f6101605f602088888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509294939250506102ff9050565b61016990610481565b5f1c90505f6101b360208089898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509294939250506102ff9050565b6101bc90610481565b5f1c90505f60028c8c6040516101d39291906104a7565b602060405180830381855afa1580156101ee573d5f5f3e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061021191906104b6565b6040805160208101929092528101869052606081018590526080810184905260a0810183905260c00160405160208183030381529060405290505f5f7f000000000000000000000000936d8dcd9b731d3fe146bf3e1520e9d790a3a67d6001600160a01b03168360405161028591906104cd565b5f60405180830381855afa9150503d805f81146102bd576040519150601f19603f3d011682016040523d82523d5f602084013e6102c2565b606091505b5091509150816102d4576102d46104e3565b808060200190518101906102e891906104b6565b6001149750505050505050505b9695505050505050565b825160609061030e83856104f7565b111561032d576040516343733a0960e11b815260040160405180910390fd5b5f8267ffffffffffffffff8111156103475761034761051c565b6040519080825280601f01601f191660200182016040528015610371576020820181803683370190505b50905060208082019086860101610389828287610394565b509095945050505050565b8082845e505050565b5f5f83601f8401126103ad575f5ffd5b50813567ffffffffffffffff8111156103c4575f5ffd5b6020830191508360208285010111156103db575f5ffd5b9250929050565b5f5f5f5f5f5f606087890312156103f7575f5ffd5b863567ffffffffffffffff81111561040d575f5ffd5b61041989828a0161039d565b909750955050602087013567ffffffffffffffff811115610438575f5ffd5b61044489828a0161039d565b909550935050604087013567ffffffffffffffff811115610463575f5ffd5b61046f89828a0161039d565b979a9699509497509295939492505050565b805160208083015191908110156104a1575f198160200360031b1b821691505b50919050565b818382375f9101908152919050565b5f602082840312156104c6575f5ffd5b5051919050565b5f82518060208501845e5f920191825250919050565b634e487b7160e01b5f52600160045260245ffd5b8082018082111561051657634e487b7160e01b5f52601160045260245ffd5b92915050565b634e487b7160e01b5f52604160045260245ffdfea264697066735822122089f98c8af4e54458c9476a97fd23ee013d01838f3963967f5b361d982cf782b264736f6c634300081e0033