{
  "address": "0xa280c9d9482df1d80b7d9046774c8d84ec58b1f8",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "key",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "data",
          "type": "bytes"
        },
        {
          "internalType": "bytes",
          "name": "signature",
          "type": "bytes"
        }
      ],
      "name": "verify",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    }
  ],
  "transactionHash": "0x3e4ef1a2b124c3f92f51f87ee220d3d8a97334597dcd0f17c6735655e41adc46",
  "receipt": {
    "to": null,
    "from": "0x4fe4e666be5752f1fdd210f4ab5de2cc26e3e0e8",
    "contractAddress": "0xa280c9d9482df1d80b7d9046774c8d84ec58b1f8",
    "transactionIndex": "0x2b",
    "gasUsed": "0xdacde",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0x049cf16a6bb1f42be35ad31965404c5bb41008e02d12f0a2dfa785a607b23461",
    "transactionHash": "0x40d373eb7e41ef885d86497c81f63ee70e0c453adfc503fc30ec79988d5e37fa",
    "logs": [],
    "blockNumber": "0xc3cb0",
    "cumulativeGasUsed": "0x1c936ad",
    "status": "0x1"
  },
  "args": [],
  "numDeployments": 1,
  "solcInputHash": "2286d90f0970dc1d34ef122ce5b9cee1",
  "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"key\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"verify(bytes,bytes,bytes)\":{\"details\":\"Verifies a signature.\",\"params\":{\"data\":\"The signed data to verify.\",\"key\":\"The public key to verify with.\",\"signature\":\"The signature to verify.\"},\"returns\":{\"_0\":\"True iff the signature is valid.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/dnssec-oracle/algorithms/P256SHA256Algorithm.sol\":\"P256SHA256Algorithm\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1200},\"remappings\":[]},\"sources\":{\"contracts/dnssec-oracle/BytesUtils.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nlibrary BytesUtils {\\n    error OffsetOutOfBoundsError(uint256 offset, uint256 length);\\n\\n    /*\\n     * @dev Returns the keccak-256 hash of a byte range.\\n     * @param self The byte string to hash.\\n     * @param offset The position to start hashing at.\\n     * @param len The number of bytes to hash.\\n     * @return The hash of the byte range.\\n     */\\n    function keccak(\\n        bytes memory self,\\n        uint256 offset,\\n        uint256 len\\n    ) internal pure returns (bytes32 ret) {\\n        require(offset + len <= self.length);\\n        assembly {\\n            ret := keccak256(add(add(self, 32), offset), len)\\n        }\\n    }\\n\\n    /*\\n     * @dev Returns a positive number if `other` comes lexicographically after\\n     *      `self`, a negative number if it comes before, or zero if the\\n     *      contents of the two bytes are equal.\\n     * @param self The first bytes to compare.\\n     * @param other The second bytes to compare.\\n     * @return The result of the comparison.\\n     */\\n    function compare(\\n        bytes memory self,\\n        bytes memory other\\n    ) internal pure returns (int256) {\\n        return compare(self, 0, self.length, other, 0, other.length);\\n    }\\n\\n    /*\\n     * @dev Returns a positive number if `other` comes lexicographically after\\n     *      `self`, a negative number if it comes before, or zero if the\\n     *      contents of the two bytes are equal. Comparison is done per-rune,\\n     *      on unicode codepoints.\\n     * @param self The first bytes to compare.\\n     * @param offset The offset of self.\\n     * @param len    The length of self.\\n     * @param other The second bytes to compare.\\n     * @param otheroffset The offset of the other string.\\n     * @param otherlen    The length of the other string.\\n     * @return The result of the comparison.\\n     */\\n    function compare(\\n        bytes memory self,\\n        uint256 offset,\\n        uint256 len,\\n        bytes memory other,\\n        uint256 otheroffset,\\n        uint256 otherlen\\n    ) internal pure returns (int256) {\\n        if (offset + len > self.length) {\\n            revert OffsetOutOfBoundsError(offset + len, self.length);\\n        }\\n        if (otheroffset + otherlen > other.length) {\\n            revert OffsetOutOfBoundsError(otheroffset + otherlen, other.length);\\n        }\\n\\n        uint256 shortest = len;\\n        if (otherlen < len) shortest = otherlen;\\n\\n        uint256 selfptr;\\n        uint256 otherptr;\\n\\n        assembly {\\n            selfptr := add(self, add(offset, 32))\\n            otherptr := add(other, add(otheroffset, 32))\\n        }\\n        for (uint256 idx = 0; idx < shortest; idx += 32) {\\n            uint256 a;\\n            uint256 b;\\n            assembly {\\n                a := mload(selfptr)\\n                b := mload(otherptr)\\n            }\\n            if (a != b) {\\n                // Mask out irrelevant bytes and check again\\n                uint256 mask;\\n                if (shortest - idx >= 32) {\\n                    mask = type(uint256).max;\\n                } else {\\n                    mask = ~(2 ** (8 * (idx + 32 - shortest)) - 1);\\n                }\\n                int256 diff = int256(a & mask) - int256(b & mask);\\n                if (diff != 0) return diff;\\n            }\\n            selfptr += 32;\\n            otherptr += 32;\\n        }\\n\\n        return int256(len) - int256(otherlen);\\n    }\\n\\n    /*\\n     * @dev Returns true if the two byte ranges are equal.\\n     * @param self The first byte range to compare.\\n     * @param offset The offset into the first byte range.\\n     * @param other The second byte range to compare.\\n     * @param otherOffset The offset into the second byte range.\\n     * @param len The number of bytes to compare\\n     * @return True if the byte ranges are equal, false otherwise.\\n     */\\n    function equals(\\n        bytes memory self,\\n        uint256 offset,\\n        bytes memory other,\\n        uint256 otherOffset,\\n        uint256 len\\n    ) internal pure returns (bool) {\\n        return keccak(self, offset, len) == keccak(other, otherOffset, len);\\n    }\\n\\n    /*\\n     * @dev Returns true if the two byte ranges are equal with offsets.\\n     * @param self The first byte range to compare.\\n     * @param offset The offset into the first byte range.\\n     * @param other The second byte range to compare.\\n     * @param otherOffset The offset into the second byte range.\\n     * @return True if the byte ranges are equal, false otherwise.\\n     */\\n    function equals(\\n        bytes memory self,\\n        uint256 offset,\\n        bytes memory other,\\n        uint256 otherOffset\\n    ) internal pure returns (bool) {\\n        return\\n            keccak(self, offset, self.length - offset) ==\\n            keccak(other, otherOffset, other.length - otherOffset);\\n    }\\n\\n    /*\\n     * @dev Compares a range of 'self' to all of 'other' and returns True iff\\n     *      they are equal.\\n     * @param self The first byte range to compare.\\n     * @param offset The offset into the first byte range.\\n     * @param other The second byte range to compare.\\n     * @return True if the byte ranges are equal, false otherwise.\\n     */\\n    function equals(\\n        bytes memory self,\\n        uint256 offset,\\n        bytes memory other\\n    ) internal pure returns (bool) {\\n        return\\n            self.length == offset + other.length &&\\n            equals(self, offset, other, 0, other.length);\\n    }\\n\\n    /*\\n     * @dev Returns true if the two byte ranges are equal.\\n     * @param self The first byte range to compare.\\n     * @param other The second byte range to compare.\\n     * @return True if the byte ranges are equal, false otherwise.\\n     */\\n    function equals(\\n        bytes memory self,\\n        bytes memory other\\n    ) internal pure returns (bool) {\\n        return\\n            self.length == other.length &&\\n            equals(self, 0, other, 0, self.length);\\n    }\\n\\n    /*\\n     * @dev Returns the 8-bit number at the specified index of self.\\n     * @param self The byte string.\\n     * @param idx The index into the bytes\\n     * @return The specified 8 bits of the string, interpreted as an integer.\\n     */\\n    function readUint8(\\n        bytes memory self,\\n        uint256 idx\\n    ) internal pure returns (uint8 ret) {\\n        return uint8(self[idx]);\\n    }\\n\\n    /*\\n     * @dev Returns the 16-bit number at the specified index of self.\\n     * @param self The byte string.\\n     * @param idx The index into the bytes\\n     * @return The specified 16 bits of the string, interpreted as an integer.\\n     */\\n    function readUint16(\\n        bytes memory self,\\n        uint256 idx\\n    ) internal pure returns (uint16 ret) {\\n        require(idx + 2 <= self.length);\\n        assembly {\\n            ret := and(mload(add(add(self, 2), idx)), 0xFFFF)\\n        }\\n    }\\n\\n    /*\\n     * @dev Returns the 32-bit number at the specified index of self.\\n     * @param self The byte string.\\n     * @param idx The index into the bytes\\n     * @return The specified 32 bits of the string, interpreted as an integer.\\n     */\\n    function readUint32(\\n        bytes memory self,\\n        uint256 idx\\n    ) internal pure returns (uint32 ret) {\\n        require(idx + 4 <= self.length);\\n        assembly {\\n            ret := and(mload(add(add(self, 4), idx)), 0xFFFFFFFF)\\n        }\\n    }\\n\\n    /*\\n     * @dev Returns the 32 byte value at the specified index of self.\\n     * @param self The byte string.\\n     * @param idx The index into the bytes\\n     * @return The specified 32 bytes of the string.\\n     */\\n    function readBytes32(\\n        bytes memory self,\\n        uint256 idx\\n    ) internal pure returns (bytes32 ret) {\\n        require(idx + 32 <= self.length);\\n        assembly {\\n            ret := mload(add(add(self, 32), idx))\\n        }\\n    }\\n\\n    /*\\n     * @dev Returns the 32 byte value at the specified index of self.\\n     * @param self The byte string.\\n     * @param idx The index into the bytes\\n     * @return The specified 32 bytes of the string.\\n     */\\n    function readBytes20(\\n        bytes memory self,\\n        uint256 idx\\n    ) internal pure returns (bytes20 ret) {\\n        require(idx + 20 <= self.length);\\n        assembly {\\n            ret := and(\\n                mload(add(add(self, 32), idx)),\\n                0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000\\n            )\\n        }\\n    }\\n\\n    /*\\n     * @dev Returns the n byte value at the specified index of self.\\n     * @param self The byte string.\\n     * @param idx The index into the bytes.\\n     * @param len The number of bytes.\\n     * @return The specified 32 bytes of the string.\\n     */\\n    function readBytesN(\\n        bytes memory self,\\n        uint256 idx,\\n        uint256 len\\n    ) internal pure returns (bytes32 ret) {\\n        require(len <= 32);\\n        require(idx + len <= self.length);\\n        assembly {\\n            let mask := not(sub(exp(256, sub(32, len)), 1))\\n            ret := and(mload(add(add(self, 32), idx)), mask)\\n        }\\n    }\\n\\n    function memcpy(uint256 dest, uint256 src, uint256 len) private pure {\\n        // Copy word-length chunks while possible\\n        for (; len >= 32; len -= 32) {\\n            assembly {\\n                mstore(dest, mload(src))\\n            }\\n            dest += 32;\\n            src += 32;\\n        }\\n\\n        // Copy remaining bytes\\n        unchecked {\\n            uint256 mask = (256 ** (32 - len)) - 1;\\n            assembly {\\n                let srcpart := and(mload(src), not(mask))\\n                let destpart := and(mload(dest), mask)\\n                mstore(dest, or(destpart, srcpart))\\n            }\\n        }\\n    }\\n\\n    /*\\n     * @dev Copies a substring into a new byte string.\\n     * @param self The byte string to copy from.\\n     * @param offset The offset to start copying at.\\n     * @param len The number of bytes to copy.\\n     */\\n    function substring(\\n        bytes memory self,\\n        uint256 offset,\\n        uint256 len\\n    ) internal pure returns (bytes memory) {\\n        require(offset + len <= self.length);\\n\\n        bytes memory ret = new bytes(len);\\n        uint256 dest;\\n        uint256 src;\\n\\n        assembly {\\n            dest := add(ret, 32)\\n            src := add(add(self, 32), offset)\\n        }\\n        memcpy(dest, src, len);\\n\\n        return ret;\\n    }\\n\\n    // Maps characters from 0x30 to 0x7A to their base32 values.\\n    // 0xFF represents invalid characters in that range.\\n    bytes constant base32HexTable =\\n        hex\\\"00010203040506070809FFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1FFFFFFFFFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\\\";\\n\\n    /**\\n     * @dev Decodes unpadded base32 data of up to one word in length.\\n     * @param self The data to decode.\\n     * @param off Offset into the string to start at.\\n     * @param len Number of characters to decode.\\n     * @return The decoded data, left aligned.\\n     */\\n    function base32HexDecodeWord(\\n        bytes memory self,\\n        uint256 off,\\n        uint256 len\\n    ) internal pure returns (bytes32) {\\n        require(len <= 52);\\n\\n        uint256 ret = 0;\\n        uint8 decoded;\\n        for (uint256 i = 0; i < len; i++) {\\n            bytes1 char = self[off + i];\\n            require(char >= 0x30 && char <= 0x7A);\\n            decoded = uint8(base32HexTable[uint256(uint8(char)) - 0x30]);\\n            require(decoded <= 0x20);\\n            if (i == len - 1) {\\n                break;\\n            }\\n            ret = (ret << 5) | decoded;\\n        }\\n\\n        uint256 bitlen = len * 5;\\n        if (len % 8 == 0) {\\n            // Multiple of 8 characters, no padding\\n            ret = (ret << 5) | decoded;\\n        } else if (len % 8 == 2) {\\n            // Two extra characters - 1 byte\\n            ret = (ret << 3) | (decoded >> 2);\\n            bitlen -= 2;\\n        } else if (len % 8 == 4) {\\n            // Four extra characters - 2 bytes\\n            ret = (ret << 1) | (decoded >> 4);\\n            bitlen -= 4;\\n        } else if (len % 8 == 5) {\\n            // Five extra characters - 3 bytes\\n            ret = (ret << 4) | (decoded >> 1);\\n            bitlen -= 1;\\n        } else if (len % 8 == 7) {\\n            // Seven extra characters - 4 bytes\\n            ret = (ret << 2) | (decoded >> 3);\\n            bitlen -= 3;\\n        } else {\\n            revert();\\n        }\\n\\n        return bytes32(ret << (256 - bitlen));\\n    }\\n\\n    /**\\n     * @dev Finds the first occurrence of the byte `needle` in `self`.\\n     * @param self The string to search\\n     * @param off The offset to start searching at\\n     * @param len The number of bytes to search\\n     * @param needle The byte to search for\\n     * @return The offset of `needle` in `self`, or 2**256-1 if it was not found.\\n     */\\n    function find(\\n        bytes memory self,\\n        uint256 off,\\n        uint256 len,\\n        bytes1 needle\\n    ) internal pure returns (uint256) {\\n        for (uint256 idx = off; idx < off + len; idx++) {\\n            if (self[idx] == needle) {\\n                return idx;\\n            }\\n        }\\n        return type(uint256).max;\\n    }\\n}\\n\",\"keccak256\":\"0x4f10902639b85a17ae10745264feff322e793bfb1bc130a9a90efa7dda47c6cc\"},\"contracts/dnssec-oracle/algorithms/Algorithm.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\n/**\\n * @dev An interface for contracts implementing a DNSSEC (signing) algorithm.\\n */\\ninterface Algorithm {\\n    /**\\n     * @dev Verifies a signature.\\n     * @param key The public key to verify with.\\n     * @param data The signed data to verify.\\n     * @param signature The signature to verify.\\n     * @return True iff the signature is valid.\\n     */\\n    function verify(\\n        bytes calldata key,\\n        bytes calldata data,\\n        bytes calldata signature\\n    ) external view virtual returns (bool);\\n}\\n\",\"keccak256\":\"0xaf6825f9852c69f8e36540821d067b4550dd2263497af9d645309b6a0c457ba6\"},\"contracts/dnssec-oracle/algorithms/EllipticCurve.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\n/**\\n * @title   EllipticCurve\\n *\\n * @author  Tilman Drerup;\\n *\\n * @notice  Implements elliptic curve math; Parametrized for SECP256R1.\\n *\\n *          Includes components of code by Andreas Olofsson, Alexander Vlasov\\n *          (https://github.com/BANKEX/CurveArithmetics), and Avi Asayag\\n *          (https://github.com/orbs-network/elliptic-curve-solidity)\\n *\\n *          Source: https://github.com/tdrerup/elliptic-curve-solidity\\n *\\n * @dev     NOTE: To disambiguate public keys when verifying signatures, activate\\n *          condition 'rs[1] > lowSmax' in validateSignature().\\n */\\ncontract EllipticCurve {\\n    // Set parameters for curve.\\n    uint256 constant a =\\n        0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC;\\n    uint256 constant b =\\n        0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;\\n    uint256 constant gx =\\n        0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;\\n    uint256 constant gy =\\n        0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;\\n    uint256 constant p =\\n        0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF;\\n    uint256 constant n =\\n        0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;\\n\\n    uint256 constant lowSmax =\\n        0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0;\\n\\n    /**\\n     * @dev Inverse of u in the field of modulo m.\\n     */\\n    function inverseMod(uint256 u, uint256 m) internal pure returns (uint256) {\\n        unchecked {\\n            if (u == 0 || u == m || m == 0) return 0;\\n            if (u > m) u = u % m;\\n\\n            int256 t1;\\n            int256 t2 = 1;\\n            uint256 r1 = m;\\n            uint256 r2 = u;\\n            uint256 q;\\n\\n            while (r2 != 0) {\\n                q = r1 / r2;\\n                (t1, t2, r1, r2) = (t2, t1 - int256(q) * t2, r2, r1 - q * r2);\\n            }\\n\\n            if (t1 < 0) return (m - uint256(-t1));\\n\\n            return uint256(t1);\\n        }\\n    }\\n\\n    /**\\n     * @dev Transform affine coordinates into projective coordinates.\\n     */\\n    function toProjectivePoint(\\n        uint256 x0,\\n        uint256 y0\\n    ) internal pure returns (uint256[3] memory P) {\\n        P[2] = addmod(0, 1, p);\\n        P[0] = mulmod(x0, P[2], p);\\n        P[1] = mulmod(y0, P[2], p);\\n    }\\n\\n    /**\\n     * @dev Add two points in affine coordinates and return projective point.\\n     */\\n    function addAndReturnProjectivePoint(\\n        uint256 x1,\\n        uint256 y1,\\n        uint256 x2,\\n        uint256 y2\\n    ) internal pure returns (uint256[3] memory P) {\\n        uint256 x;\\n        uint256 y;\\n        (x, y) = add(x1, y1, x2, y2);\\n        P = toProjectivePoint(x, y);\\n    }\\n\\n    /**\\n     * @dev Transform from projective to affine coordinates.\\n     */\\n    function toAffinePoint(\\n        uint256 x0,\\n        uint256 y0,\\n        uint256 z0\\n    ) internal pure returns (uint256 x1, uint256 y1) {\\n        uint256 z0Inv;\\n        z0Inv = inverseMod(z0, p);\\n        x1 = mulmod(x0, z0Inv, p);\\n        y1 = mulmod(y0, z0Inv, p);\\n    }\\n\\n    /**\\n     * @dev Return the zero curve in projective coordinates.\\n     */\\n    function zeroProj()\\n        internal\\n        pure\\n        returns (uint256 x, uint256 y, uint256 z)\\n    {\\n        return (0, 1, 0);\\n    }\\n\\n    /**\\n     * @dev Return the zero curve in affine coordinates.\\n     */\\n    function zeroAffine() internal pure returns (uint256 x, uint256 y) {\\n        return (0, 0);\\n    }\\n\\n    /**\\n     * @dev Check if the curve is the zero curve.\\n     */\\n    function isZeroCurve(\\n        uint256 x0,\\n        uint256 y0\\n    ) internal pure returns (bool isZero) {\\n        if (x0 == 0 && y0 == 0) {\\n            return true;\\n        }\\n        return false;\\n    }\\n\\n    /**\\n     * @dev Check if a point in affine coordinates is on the curve.\\n     */\\n    function isOnCurve(uint256 x, uint256 y) internal pure returns (bool) {\\n        if (0 == x || x == p || 0 == y || y == p) {\\n            return false;\\n        }\\n\\n        uint256 LHS = mulmod(y, y, p); // y^2\\n        uint256 RHS = mulmod(mulmod(x, x, p), x, p); // x^3\\n\\n        if (a != 0) {\\n            RHS = addmod(RHS, mulmod(x, a, p), p); // x^3 + a*x\\n        }\\n        if (b != 0) {\\n            RHS = addmod(RHS, b, p); // x^3 + a*x + b\\n        }\\n\\n        return LHS == RHS;\\n    }\\n\\n    /**\\n     * @dev Double an elliptic curve point in projective coordinates. See\\n     * https://www.nayuki.io/page/elliptic-curve-point-addition-in-projective-coordinates\\n     */\\n    function twiceProj(\\n        uint256 x0,\\n        uint256 y0,\\n        uint256 z0\\n    ) internal pure returns (uint256 x1, uint256 y1, uint256 z1) {\\n        uint256 t;\\n        uint256 u;\\n        uint256 v;\\n        uint256 w;\\n\\n        if (isZeroCurve(x0, y0)) {\\n            return zeroProj();\\n        }\\n\\n        u = mulmod(y0, z0, p);\\n        u = mulmod(u, 2, p);\\n\\n        v = mulmod(u, x0, p);\\n        v = mulmod(v, y0, p);\\n        v = mulmod(v, 2, p);\\n\\n        x0 = mulmod(x0, x0, p);\\n        t = mulmod(x0, 3, p);\\n\\n        z0 = mulmod(z0, z0, p);\\n        z0 = mulmod(z0, a, p);\\n        t = addmod(t, z0, p);\\n\\n        w = mulmod(t, t, p);\\n        x0 = mulmod(2, v, p);\\n        w = addmod(w, p - x0, p);\\n\\n        x0 = addmod(v, p - w, p);\\n        x0 = mulmod(t, x0, p);\\n        y0 = mulmod(y0, u, p);\\n        y0 = mulmod(y0, y0, p);\\n        y0 = mulmod(2, y0, p);\\n        y1 = addmod(x0, p - y0, p);\\n\\n        x1 = mulmod(u, w, p);\\n\\n        z1 = mulmod(u, u, p);\\n        z1 = mulmod(z1, u, p);\\n    }\\n\\n    /**\\n     * @dev Add two elliptic curve points in projective coordinates. See\\n     * https://www.nayuki.io/page/elliptic-curve-point-addition-in-projective-coordinates\\n     */\\n    function addProj(\\n        uint256 x0,\\n        uint256 y0,\\n        uint256 z0,\\n        uint256 x1,\\n        uint256 y1,\\n        uint256 z1\\n    ) internal pure returns (uint256 x2, uint256 y2, uint256 z2) {\\n        uint256 t0;\\n        uint256 t1;\\n        uint256 u0;\\n        uint256 u1;\\n\\n        if (isZeroCurve(x0, y0)) {\\n            return (x1, y1, z1);\\n        } else if (isZeroCurve(x1, y1)) {\\n            return (x0, y0, z0);\\n        }\\n\\n        t0 = mulmod(y0, z1, p);\\n        t1 = mulmod(y1, z0, p);\\n\\n        u0 = mulmod(x0, z1, p);\\n        u1 = mulmod(x1, z0, p);\\n\\n        if (u0 == u1) {\\n            if (t0 == t1) {\\n                return twiceProj(x0, y0, z0);\\n            } else {\\n                return zeroProj();\\n            }\\n        }\\n\\n        (x2, y2, z2) = addProj2(mulmod(z0, z1, p), u0, u1, t1, t0);\\n    }\\n\\n    /**\\n     * @dev Helper function that splits addProj to avoid too many local variables.\\n     */\\n    function addProj2(\\n        uint256 v,\\n        uint256 u0,\\n        uint256 u1,\\n        uint256 t1,\\n        uint256 t0\\n    ) private pure returns (uint256 x2, uint256 y2, uint256 z2) {\\n        uint256 u;\\n        uint256 u2;\\n        uint256 u3;\\n        uint256 w;\\n        uint256 t;\\n\\n        t = addmod(t0, p - t1, p);\\n        u = addmod(u0, p - u1, p);\\n        u2 = mulmod(u, u, p);\\n\\n        w = mulmod(t, t, p);\\n        w = mulmod(w, v, p);\\n        u1 = addmod(u1, u0, p);\\n        u1 = mulmod(u1, u2, p);\\n        w = addmod(w, p - u1, p);\\n\\n        x2 = mulmod(u, w, p);\\n\\n        u3 = mulmod(u2, u, p);\\n        u0 = mulmod(u0, u2, p);\\n        u0 = addmod(u0, p - w, p);\\n        t = mulmod(t, u0, p);\\n        t0 = mulmod(t0, u3, p);\\n\\n        y2 = addmod(t, p - t0, p);\\n\\n        z2 = mulmod(u3, v, p);\\n    }\\n\\n    /**\\n     * @dev Add two elliptic curve points in affine coordinates.\\n     */\\n    function add(\\n        uint256 x0,\\n        uint256 y0,\\n        uint256 x1,\\n        uint256 y1\\n    ) internal pure returns (uint256, uint256) {\\n        uint256 z0;\\n\\n        (x0, y0, z0) = addProj(x0, y0, 1, x1, y1, 1);\\n\\n        return toAffinePoint(x0, y0, z0);\\n    }\\n\\n    /**\\n     * @dev Double an elliptic curve point in affine coordinates.\\n     */\\n    function twice(\\n        uint256 x0,\\n        uint256 y0\\n    ) internal pure returns (uint256, uint256) {\\n        uint256 z0;\\n\\n        (x0, y0, z0) = twiceProj(x0, y0, 1);\\n\\n        return toAffinePoint(x0, y0, z0);\\n    }\\n\\n    /**\\n     * @dev Multiply an elliptic curve point by a 2 power base (i.e., (2^exp)*P)).\\n     */\\n    function multiplyPowerBase2(\\n        uint256 x0,\\n        uint256 y0,\\n        uint256 exp\\n    ) internal pure returns (uint256, uint256) {\\n        uint256 base2X = x0;\\n        uint256 base2Y = y0;\\n        uint256 base2Z = 1;\\n\\n        for (uint256 i = 0; i < exp; i++) {\\n            (base2X, base2Y, base2Z) = twiceProj(base2X, base2Y, base2Z);\\n        }\\n\\n        return toAffinePoint(base2X, base2Y, base2Z);\\n    }\\n\\n    /**\\n     * @dev Multiply an elliptic curve point by a scalar.\\n     */\\n    function multiplyScalar(\\n        uint256 x0,\\n        uint256 y0,\\n        uint256 scalar\\n    ) internal pure returns (uint256 x1, uint256 y1) {\\n        if (scalar == 0) {\\n            return zeroAffine();\\n        } else if (scalar == 1) {\\n            return (x0, y0);\\n        } else if (scalar == 2) {\\n            return twice(x0, y0);\\n        }\\n\\n        uint256 base2X = x0;\\n        uint256 base2Y = y0;\\n        uint256 base2Z = 1;\\n        uint256 z1 = 1;\\n        x1 = x0;\\n        y1 = y0;\\n\\n        if (scalar % 2 == 0) {\\n            x1 = y1 = 0;\\n        }\\n\\n        scalar = scalar >> 1;\\n\\n        while (scalar > 0) {\\n            (base2X, base2Y, base2Z) = twiceProj(base2X, base2Y, base2Z);\\n\\n            if (scalar % 2 == 1) {\\n                (x1, y1, z1) = addProj(base2X, base2Y, base2Z, x1, y1, z1);\\n            }\\n\\n            scalar = scalar >> 1;\\n        }\\n\\n        return toAffinePoint(x1, y1, z1);\\n    }\\n\\n    /**\\n     * @dev Multiply the curve's generator point by a scalar.\\n     */\\n    function multipleGeneratorByScalar(\\n        uint256 scalar\\n    ) internal pure returns (uint256, uint256) {\\n        return multiplyScalar(gx, gy, scalar);\\n    }\\n\\n    /**\\n     * @dev Validate combination of message, signature, and public key.\\n     */\\n    function validateSignature(\\n        bytes32 message,\\n        uint256[2] memory rs,\\n        uint256[2] memory Q\\n    ) internal pure returns (bool) {\\n        // To disambiguate between public key solutions, include comment below.\\n        if (rs[0] == 0 || rs[0] >= n || rs[1] == 0) {\\n            // || rs[1] > lowSmax)\\n            return false;\\n        }\\n        if (!isOnCurve(Q[0], Q[1])) {\\n            return false;\\n        }\\n\\n        uint256 x1;\\n        uint256 x2;\\n        uint256 y1;\\n        uint256 y2;\\n\\n        uint256 sInv = inverseMod(rs[1], n);\\n        (x1, y1) = multiplyScalar(gx, gy, mulmod(uint256(message), sInv, n));\\n        (x2, y2) = multiplyScalar(Q[0], Q[1], mulmod(rs[0], sInv, n));\\n        uint256[3] memory P = addAndReturnProjectivePoint(x1, y1, x2, y2);\\n\\n        if (P[2] == 0) {\\n            return false;\\n        }\\n\\n        uint256 Px = inverseMod(P[2], p);\\n        Px = mulmod(P[0], mulmod(Px, Px, p), p);\\n\\n        return Px % n == rs[0];\\n    }\\n}\\n\",\"keccak256\":\"0xdee968ffbfcb9a05b7ed7845e2c55f438f5e09a80fc6024c751a1718137e1838\"},\"contracts/dnssec-oracle/algorithms/P256SHA256Algorithm.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nimport \\\"./Algorithm.sol\\\";\\nimport \\\"./EllipticCurve.sol\\\";\\nimport \\\"../BytesUtils.sol\\\";\\n\\ncontract P256SHA256Algorithm is Algorithm, EllipticCurve {\\n    using BytesUtils for *;\\n\\n    /**\\n     * @dev Verifies a signature.\\n     * @param key The public key to verify with.\\n     * @param data The signed data to verify.\\n     * @param signature The signature to verify.\\n     * @return True iff the signature is valid.\\n     */\\n    function verify(\\n        bytes calldata key,\\n        bytes calldata data,\\n        bytes calldata signature\\n    ) external view override returns (bool) {\\n        return\\n            validateSignature(\\n                sha256(data),\\n                parseSignature(signature),\\n                parseKey(key)\\n            );\\n    }\\n\\n    function parseSignature(\\n        bytes memory data\\n    ) internal pure returns (uint256[2] memory) {\\n        require(data.length == 64, \\\"Invalid p256 signature length\\\");\\n        return [uint256(data.readBytes32(0)), uint256(data.readBytes32(32))];\\n    }\\n\\n    function parseKey(\\n        bytes memory data\\n    ) internal pure returns (uint256[2] memory) {\\n        require(data.length == 68, \\\"Invalid p256 key length\\\");\\n        return [uint256(data.readBytes32(4)), uint256(data.readBytes32(36))];\\n    }\\n}\\n\",\"keccak256\":\"0x406e394eb659ee8c75345b9d3795e0061de2bd6567dd8035e76a19588850f0ea\"}},\"version\":1}",
  "bytecode": "0x608060405234801561001057600080fd5b50610f41806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063de8f50a114610030575b600080fd5b61004361003e366004610dd4565b610057565b604051901515815260200160405180910390f35b60006101316002868660405161006e929190610e6e565b602060405180830381855afa15801561008b573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906100ae9190610e7e565b6100ed85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013c92505050565b61012c8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506101cb92505050565b61024a565b979650505050505050565b610144610d56565b815160401461019a5760405162461bcd60e51b815260206004820152601d60248201527f496e76616c69642070323536207369676e6174757265206c656e67746800000060448201526064015b60405180910390fd5b60408051808201909152806101b0846000610445565b81526020908101906101c3908590610445565b905292915050565b6101d3610d56565b81516044146102245760405162461bcd60e51b815260206004820152601760248201527f496e76616c69642070323536206b6579206c656e6774680000000000000000006044820152606401610191565b604080518082019091528061023a846004610445565b81526020016101c3846024610445565b8151600090158061027c575082517fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255111155b8061028957506020830151155b156102965750600061043e565b815160208301516102a79190610469565b6102b35750600061043e565b6000808080806102ea88600160200201517fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551610565565b905061035a7f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2967f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f57fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551848d096105ff565b885160208a01518b5193985091955061039a929091907fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551908590096105ff565b909450915060006103ad868587866106cf565b60408101519091506000036103cb576000965050505050505061043e565b60006103ec8260026020020151600160601b63ffffffff60c01b0319610565565b9050600160601b63ffffffff60c01b0319808283098351098a519091506104337fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255183610ead565b149750505050505050505b9392505050565b8151600090610455836020610ee5565b111561046057600080fd5b50016020015190565b60008215806104855750600160601b63ffffffff60c01b031983145b8061048e575081155b806104a65750600160601b63ffffffff60c01b031982145b156104b35750600061055f565b6000600160601b63ffffffff60c01b031983840990506000600160601b63ffffffff60c01b031985600160601b63ffffffff60c01b0319878809099050600160601b63ffffffff60c01b0319807fffffffff00000001000000000000000000000000fffffffffffffffffffffffc870982089050600160601b63ffffffff60c01b03197f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b820890501490505b92915050565b600082158061057357508183145b8061057c575081155b156105895750600061055f565b818311156105a4578183816105a0576105a0610e97565b0692505b600060018385835b81156105db578183816105c1576105c1610e97565b9495940485810290940393919283830290039190506105ac565b60008512156105f357505050908301915061055f9050565b50929695505050505050565b60008082600003610617576000805b915091506106c7565b826001036106295750839050826106c7565b8260020361063b5761060e85856106f5565b50839050828181600180610650600288610ead565b60000361065f57600094508495505b600187901c96505b86156106b357610678848484610725565b9195509350915061068a600288610ead565b6001036106a75761069f848484898986610983565b919750955090505b600187901c9650610667565b6106be868683610a88565b95509550505050505b935093915050565b6106d7610d74565b6000806106e687878787610ad8565b90925090506101318282610b0d565b600080600061070685856001610725565b91965094509050610718858583610a88565b92509250505b9250929050565b600080600080600080600061073a8a8a610b66565b156107535760006001819650965096505050505061097a565b600160601b63ffffffff60c01b0319888a099250600160601b63ffffffff60c01b0319600284099250600160601b63ffffffff60c01b03198a84099150600160601b63ffffffff60c01b03198983099150600160601b63ffffffff60c01b0319600283099150600160601b63ffffffff60c01b03198a8b099950600160601b63ffffffff60c01b031960038b099350600160601b63ffffffff60c01b03198889099750600160601b63ffffffff60c01b03197fffffffff00000001000000000000000000000000fffffffffffffffffffffffc89099750600160601b63ffffffff60c01b03198885089350600160601b63ffffffff60c01b03198485099050600160601b63ffffffff60c01b0319826002099950600160601b63ffffffff60c01b031961088e8b600160601b63ffffffff60c01b0319610ef8565b82089050600160601b63ffffffff60c01b03196108b982600160601b63ffffffff60c01b0319610ef8565b83089950600160601b63ffffffff60c01b03198a85099950600160601b63ffffffff60c01b0319838a099850600160601b63ffffffff60c01b0319898a099850600160601b63ffffffff60c01b0319896002099850600160601b63ffffffff60c01b03196109358a600160601b63ffffffff60c01b0319610ef8565b8b089550600160601b63ffffffff60c01b03198184099650600160601b63ffffffff60c01b03198384099450600160601b63ffffffff60c01b03198386099450505050505b93509350939050565b60008060008060008060006109988d8d610b66565b156109af5789898996509650965050505050610a7c565b6109b98a8a610b66565b156109d0578c8c8c96509650965050505050610a7c565b600160601b63ffffffff60c01b0319888d099350600160601b63ffffffff60c01b03198b8a099250600160601b63ffffffff60c01b0319888e099150600160601b63ffffffff60c01b03198b8b099050808203610a5257828403610a4857610a398d8d8d610725565b96509650965050505050610a7c565b6000600181610a39565b610a70600160601b63ffffffff60c01b0319898d0983838688610b8a565b91985096509450505050505b96509650969350505050565b6000806000610aa584600160601b63ffffffff60c01b0319610565565b9050600160601b63ffffffff60c01b03198187099250600160601b63ffffffff60c01b0319818609915050935093915050565b6000806000610aed8787600188886001610983565b91985096509050610aff878783610a88565b925092505094509492505050565b610b15610d74565b600160601b63ffffffff60c01b0319600160000860408201819052600160601b63ffffffff60c01b031990840981526040810151600160601b63ffffffff60c01b0319908309602082015292915050565b600082158015610b74575081155b15610b815750600161055f565b50600092915050565b600080808080808080600160601b63ffffffff60c01b0319610bba8b600160601b63ffffffff60c01b0319610ef8565b8a089050600160601b63ffffffff60c01b0319610be58c600160601b63ffffffff60c01b0319610ef8565b8d089450600160601b63ffffffff60c01b03198586099350600160601b63ffffffff60c01b03198182099150600160601b63ffffffff60c01b03198d83099150600160601b63ffffffff60c01b03198c8c089a50600160601b63ffffffff60c01b0319848c099a50600160601b63ffffffff60c01b0319610c748c600160601b63ffffffff60c01b0319610ef8565b83089150600160601b63ffffffff60c01b03198286099750600160601b63ffffffff60c01b03198585099250600160601b63ffffffff60c01b0319848d099b50600160601b63ffffffff60c01b0319610cdb83600160601b63ffffffff60c01b0319610ef8565b8d089b50600160601b63ffffffff60c01b03198c82099050600160601b63ffffffff60c01b0319838a099850600160601b63ffffffff60c01b0319610d2e8a600160601b63ffffffff60c01b0319610ef8565b82089650600160601b63ffffffff60c01b03198d840995505050505050955095509592505050565b60405180604001604052806002906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b60008083601f840112610da457600080fd5b50813567ffffffffffffffff811115610dbc57600080fd5b60208301915083602082850101111561071e57600080fd5b60008060008060008060608789031215610ded57600080fd5b863567ffffffffffffffff80821115610e0557600080fd5b610e118a838b01610d92565b90985096506020890135915080821115610e2a57600080fd5b610e368a838b01610d92565b90965094506040890135915080821115610e4f57600080fd5b50610e5c89828a01610d92565b979a9699509497509295939492505050565b8183823760009101908152919050565b600060208284031215610e9057600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b600082610eca57634e487b7160e01b600052601260045260246000fd5b500690565b634e487b7160e01b600052601160045260246000fd5b8082018082111561055f5761055f610ecf565b8181038181111561055f5761055f610ecf56fea26469706673582212200a7cdc61343825b33e51ff653c60245b511afc3bf209bfd7831b5eded2744b1c64736f6c63430008110033",
  "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063de8f50a114610030575b600080fd5b61004361003e366004610dd4565b610057565b604051901515815260200160405180910390f35b60006101316002868660405161006e929190610e6e565b602060405180830381855afa15801561008b573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906100ae9190610e7e565b6100ed85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061013c92505050565b61012c8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506101cb92505050565b61024a565b979650505050505050565b610144610d56565b815160401461019a5760405162461bcd60e51b815260206004820152601d60248201527f496e76616c69642070323536207369676e6174757265206c656e67746800000060448201526064015b60405180910390fd5b60408051808201909152806101b0846000610445565b81526020908101906101c3908590610445565b905292915050565b6101d3610d56565b81516044146102245760405162461bcd60e51b815260206004820152601760248201527f496e76616c69642070323536206b6579206c656e6774680000000000000000006044820152606401610191565b604080518082019091528061023a846004610445565b81526020016101c3846024610445565b8151600090158061027c575082517fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255111155b8061028957506020830151155b156102965750600061043e565b815160208301516102a79190610469565b6102b35750600061043e565b6000808080806102ea88600160200201517fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551610565565b905061035a7f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2967f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f57fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551848d096105ff565b885160208a01518b5193985091955061039a929091907fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551908590096105ff565b909450915060006103ad868587866106cf565b60408101519091506000036103cb576000965050505050505061043e565b60006103ec8260026020020151600160601b63ffffffff60c01b0319610565565b9050600160601b63ffffffff60c01b0319808283098351098a519091506104337fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255183610ead565b149750505050505050505b9392505050565b8151600090610455836020610ee5565b111561046057600080fd5b50016020015190565b60008215806104855750600160601b63ffffffff60c01b031983145b8061048e575081155b806104a65750600160601b63ffffffff60c01b031982145b156104b35750600061055f565b6000600160601b63ffffffff60c01b031983840990506000600160601b63ffffffff60c01b031985600160601b63ffffffff60c01b0319878809099050600160601b63ffffffff60c01b0319807fffffffff00000001000000000000000000000000fffffffffffffffffffffffc870982089050600160601b63ffffffff60c01b03197f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b820890501490505b92915050565b600082158061057357508183145b8061057c575081155b156105895750600061055f565b818311156105a4578183816105a0576105a0610e97565b0692505b600060018385835b81156105db578183816105c1576105c1610e97565b9495940485810290940393919283830290039190506105ac565b60008512156105f357505050908301915061055f9050565b50929695505050505050565b60008082600003610617576000805b915091506106c7565b826001036106295750839050826106c7565b8260020361063b5761060e85856106f5565b50839050828181600180610650600288610ead565b60000361065f57600094508495505b600187901c96505b86156106b357610678848484610725565b9195509350915061068a600288610ead565b6001036106a75761069f848484898986610983565b919750955090505b600187901c9650610667565b6106be868683610a88565b95509550505050505b935093915050565b6106d7610d74565b6000806106e687878787610ad8565b90925090506101318282610b0d565b600080600061070685856001610725565b91965094509050610718858583610a88565b92509250505b9250929050565b600080600080600080600061073a8a8a610b66565b156107535760006001819650965096505050505061097a565b600160601b63ffffffff60c01b0319888a099250600160601b63ffffffff60c01b0319600284099250600160601b63ffffffff60c01b03198a84099150600160601b63ffffffff60c01b03198983099150600160601b63ffffffff60c01b0319600283099150600160601b63ffffffff60c01b03198a8b099950600160601b63ffffffff60c01b031960038b099350600160601b63ffffffff60c01b03198889099750600160601b63ffffffff60c01b03197fffffffff00000001000000000000000000000000fffffffffffffffffffffffc89099750600160601b63ffffffff60c01b03198885089350600160601b63ffffffff60c01b03198485099050600160601b63ffffffff60c01b0319826002099950600160601b63ffffffff60c01b031961088e8b600160601b63ffffffff60c01b0319610ef8565b82089050600160601b63ffffffff60c01b03196108b982600160601b63ffffffff60c01b0319610ef8565b83089950600160601b63ffffffff60c01b03198a85099950600160601b63ffffffff60c01b0319838a099850600160601b63ffffffff60c01b0319898a099850600160601b63ffffffff60c01b0319896002099850600160601b63ffffffff60c01b03196109358a600160601b63ffffffff60c01b0319610ef8565b8b089550600160601b63ffffffff60c01b03198184099650600160601b63ffffffff60c01b03198384099450600160601b63ffffffff60c01b03198386099450505050505b93509350939050565b60008060008060008060006109988d8d610b66565b156109af5789898996509650965050505050610a7c565b6109b98a8a610b66565b156109d0578c8c8c96509650965050505050610a7c565b600160601b63ffffffff60c01b0319888d099350600160601b63ffffffff60c01b03198b8a099250600160601b63ffffffff60c01b0319888e099150600160601b63ffffffff60c01b03198b8b099050808203610a5257828403610a4857610a398d8d8d610725565b96509650965050505050610a7c565b6000600181610a39565b610a70600160601b63ffffffff60c01b0319898d0983838688610b8a565b91985096509450505050505b96509650969350505050565b6000806000610aa584600160601b63ffffffff60c01b0319610565565b9050600160601b63ffffffff60c01b03198187099250600160601b63ffffffff60c01b0319818609915050935093915050565b6000806000610aed8787600188886001610983565b91985096509050610aff878783610a88565b925092505094509492505050565b610b15610d74565b600160601b63ffffffff60c01b0319600160000860408201819052600160601b63ffffffff60c01b031990840981526040810151600160601b63ffffffff60c01b0319908309602082015292915050565b600082158015610b74575081155b15610b815750600161055f565b50600092915050565b600080808080808080600160601b63ffffffff60c01b0319610bba8b600160601b63ffffffff60c01b0319610ef8565b8a089050600160601b63ffffffff60c01b0319610be58c600160601b63ffffffff60c01b0319610ef8565b8d089450600160601b63ffffffff60c01b03198586099350600160601b63ffffffff60c01b03198182099150600160601b63ffffffff60c01b03198d83099150600160601b63ffffffff60c01b03198c8c089a50600160601b63ffffffff60c01b0319848c099a50600160601b63ffffffff60c01b0319610c748c600160601b63ffffffff60c01b0319610ef8565b83089150600160601b63ffffffff60c01b03198286099750600160601b63ffffffff60c01b03198585099250600160601b63ffffffff60c01b0319848d099b50600160601b63ffffffff60c01b0319610cdb83600160601b63ffffffff60c01b0319610ef8565b8d089b50600160601b63ffffffff60c01b03198c82099050600160601b63ffffffff60c01b0319838a099850600160601b63ffffffff60c01b0319610d2e8a600160601b63ffffffff60c01b0319610ef8565b82089650600160601b63ffffffff60c01b03198d840995505050505050955095509592505050565b60405180604001604052806002906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b60008083601f840112610da457600080fd5b50813567ffffffffffffffff811115610dbc57600080fd5b60208301915083602082850101111561071e57600080fd5b60008060008060008060608789031215610ded57600080fd5b863567ffffffffffffffff80821115610e0557600080fd5b610e118a838b01610d92565b90985096506020890135915080821115610e2a57600080fd5b610e368a838b01610d92565b90965094506040890135915080821115610e4f57600080fd5b50610e5c89828a01610d92565b979a9699509497509295939492505050565b8183823760009101908152919050565b600060208284031215610e9057600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b600082610eca57634e487b7160e01b600052601260045260246000fd5b500690565b634e487b7160e01b600052601160045260246000fd5b8082018082111561055f5761055f610ecf565b8181038181111561055f5761055f610ecf56fea26469706673582212200a7cdc61343825b33e51ff653c60245b511afc3bf209bfd7831b5eded2744b1c64736f6c63430008110033",
  "devdoc": {
    "kind": "dev",
    "methods": {
      "verify(bytes,bytes,bytes)": {
        "details": "Verifies a signature.",
        "params": {
          "data": "The signed data to verify.",
          "key": "The public key to verify with.",
          "signature": "The signature to verify."
        },
        "returns": {
          "_0": "True iff the signature is valid."
        }
      }
    },
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {},
    "version": 1
  },
  "storageLayout": {
    "storage": [],
    "types": null
  }
}