creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/common/BN256G2.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// solium-disable security/no-assign-params\n\npragma solidity 0.8.19;\nimport \"../interfaces/common/IBN256G2.sol\";\n\n/**\n * @title Elliptic curve operations on twist points on bn256 (G2)\n * @dev Adaptation of https://github.com/musalbas/solidity-BN256G2 to 0.6.0 and then 0.8.19\n */\n// slither-disable-next-line missing-inheritance\ncontract BN256G2 is IBN256G2 {\n    uint256 internal constant FIELD_MODULUS = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47;\n    uint256 internal constant TWISTBX = 0x2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5;\n    uint256 internal constant TWISTBY = 0x9713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2;\n    uint256 internal constant PTXX = 0;\n    uint256 internal constant PTXY = 1;\n    uint256 internal constant PTYX = 2;\n    uint256 internal constant PTYY = 3;\n    uint256 internal constant PTZX = 4;\n    uint256 internal constant PTZY = 5;\n\n    // This is the generator negated, to use for pairing\n    uint256 public constant G2_NEG_X_RE = 0x198E9393920D483A7260BFB731FB5D25F1AA493335A9E71297E485B7AEF312C2;\n    uint256 public constant G2_NEG_X_IM = 0x1800DEEF121F1E76426A00665E5C4479674322D4F75EDADD46DEBD5CD992F6ED;\n    // slither-disable-next-line similar-names\n    uint256 public constant G2_NEG_Y_RE = 0x275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec;\n    // slither-disable-next-line similar-names\n    uint256 public constant G2_NEG_Y_IM = 0x1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d;\n\n    /**\n     * @notice Add two twist points\n     * @param pt1xx Coefficient 1 of x on point 1\n     * @param pt1xy Coefficient 2 of x on point 1\n     * @param pt1yx Coefficient 1 of y on point 1\n     * @param pt1yy Coefficient 2 of y on point 1\n     * @param pt2xx Coefficient 1 of x on point 2\n     * @param pt2xy Coefficient 2 of x on point 2\n     * @param pt2yx Coefficient 1 of y on point 2\n     * @param pt2yy Coefficient 2 of y on point 2\n     * @return (pt3xx, pt3xy, pt3yx, pt3yy)\n     */\n    function ecTwistAdd(\n        uint256 pt1xx,\n        uint256 pt1xy,\n        uint256 pt1yx,\n        uint256 pt1yy,\n        uint256 pt2xx,\n        uint256 pt2xy,\n        uint256 pt2yx,\n        uint256 pt2yy\n    ) external view returns (uint256, uint256, uint256, uint256) {\n        if (pt1xx == 0 && pt1xy == 0 && pt1yx == 0 && pt1yy == 0) {\n            if (!(pt2xx == 0 && pt2xy == 0 && pt2yx == 0 && pt2yy == 0)) {\n                require(_isOnCurve(pt2xx, pt2xy, pt2yx, pt2yy), \"point not in curve\");\n            }\n            return (pt2xx, pt2xy, pt2yx, pt2yy);\n        } else if (pt2xx == 0 && pt2xy == 0 && pt2yx == 0 && pt2yy == 0) {\n            require(_isOnCurve(pt1xx, pt1xy, pt1yx, pt1yy), \"point not in curve\");\n            return (pt1xx, pt1xy, pt1yx, pt1yy);\n        }\n\n        require(_isOnCurve(pt1xx, pt1xy, pt1yx, pt1yy), \"point not in curve\");\n\n        require(_isOnCurve(pt2xx, pt2xy, pt2yx, pt2yy), \"point not in curve\");\n\n        uint256[6] memory pt3 = ecTwistAddJacobian(pt1xx, pt1xy, pt1yx, pt1yy, 1, 0, pt2xx, pt2xy, pt2yx, pt2yy, 1, 0);\n\n        return _fromJacobian(pt3[PTXX], pt3[PTXY], pt3[PTYX], pt3[PTYY], pt3[PTZX], pt3[PTZY]);\n    }\n\n    /**\n     * @notice Multiply a twist point by a scalar\n     * @param s     Scalar to multiply by\n     * @param pt1xx Coefficient 1 of x\n     * @param pt1xy Coefficient 2 of x\n     * @param pt1yx Coefficient 1 of y\n     * @param pt1yy Coefficient 2 of y\n     * @return (pt2xx, pt2xy, pt2yx, pt2yy)\n     */\n    function ecTwistMul(\n        uint256 s,\n        uint256 pt1xx,\n        uint256 pt1xy,\n        uint256 pt1yx,\n        uint256 pt1yy\n    ) external view returns (uint256, uint256, uint256, uint256) {\n        uint256 pt1zx = 1;\n        if (pt1xx == 0 && pt1xy == 0 && pt1yx == 0 && pt1yy == 0) {\n            pt1xx = 1;\n            pt1yx = 1;\n            pt1zx = 0;\n        } else {\n            require(_isOnCurve(pt1xx, pt1xy, pt1yx, pt1yy), \"point not in curve\");\n        }\n        uint256[6] memory pt2 = _ecTwistMulJacobian(s, pt1xx, pt1xy, pt1yx, pt1yy, pt1zx, 0);\n\n        return _fromJacobian(pt2[PTXX], pt2[PTXY], pt2[PTYX], pt2[PTYY], pt2[PTZX], pt2[PTZY]);\n    }\n\n    /**\n     * @notice Get the field modulus\n     * @return The field modulus\n     */\n    function getFieldModulus() external pure returns (uint256) {\n        return FIELD_MODULUS;\n    }\n\n    /**\n     * @notice a-b mod n\n     * @param a First operand\n     * @param b Second operand\n     * @param n modulus\n     * @return The result of the operation\n     */\n    function submod(uint256 a, uint256 b, uint256 n) internal pure returns (uint256) {\n        return addmod(a, n - b, n);\n    }\n\n    /**\n     * @notice FQ2*FQ2 multiplication operation\n     * @param xx First FQ2 operands first coordinate\n     * @param xy First FQ2 operands second coordinate\n     * @param yx Second FQ2 operands first coordinate\n     * @param yy Second FQ2 operands second coordinate\n     * @return [xx*yx-xy*yy, xx*yy+xy*yx]\n     */\n    function _fq2mul(uint256 xx, uint256 xy, uint256 yx, uint256 yy) internal pure returns (uint256, uint256) {\n        return (\n            submod(mulmod(xx, yx, FIELD_MODULUS), mulmod(xy, yy, FIELD_MODULUS), FIELD_MODULUS),\n            addmod(mulmod(xx, yy, FIELD_MODULUS), mulmod(xy, yx, FIELD_MODULUS), FIELD_MODULUS)\n        );\n    }\n\n    /**\n     * @notice Fq2*k multiplication operation\n     * @param xx FQ2 operands first coordinate\n     * @param xy FQ2 operands second coordinate\n     * @param k scalar to multiply with\n     * @return [xx*k, xy*k]\n     */\n    function _fq2muc(uint256 xx, uint256 xy, uint256 k) internal pure returns (uint256, uint256) {\n        return (mulmod(xx, k, FIELD_MODULUS), mulmod(xy, k, FIELD_MODULUS));\n    }\n\n    /**\n     * @notice FQ2+FQ2 addition operation\n     * @param xx First FQ2 operands first coordinate\n     * @param xy First FQ2 operands second coordinate\n     * @param yx Second FQ2 operands first coordinate\n     * @param yy Second FQ2 operands second coordinate\n     * @return [xx+yx, xy+yy]\n     */\n    // function _fq2add(\n    //     uint256 xx,\n    //     uint256 xy,\n    //     uint256 yx,\n    //     uint256 yy\n    // ) internal pure returns (uint256, uint256) {\n    //     return (addmod(xx, yx, FIELD_MODULUS), addmod(xy, yy, FIELD_MODULUS));\n    // }\n\n    /**\n     * @notice FQ2-FQ2 subtraction operation\n     * @param xx First FQ2 operands first coordinate\n     * @param xy First FQ2 operands second coordinate\n     * @param yx Second FQ2 operands first coordinate\n     * @param yy Second FQ2 operands second coordinate\n     * @return [xx-yx, xy-yy]\n     */\n    function _fq2sub(uint256 xx, uint256 xy, uint256 yx, uint256 yy) internal pure returns (uint256, uint256) {\n        return (submod(xx, yx, FIELD_MODULUS), submod(xy, yy, FIELD_MODULUS));\n    }\n\n    /**\n     * @notice FQ2/FQ2 division operation\n     * @param xx First FQ2 operands first coordinate\n     * @param xy First FQ2 operands second coordinate\n     * @param yx Second FQ2 operands first coordinate\n     * @param yy Second FQ2 operands second coordinate\n     * @return [xx, xy] * Inv([yx, yy])\n     */\n    // function _fq2div(\n    //     uint256 xx,\n    //     uint256 xy,\n    //     uint256 yx,\n    //     uint256 yy\n    // ) internal view returns (uint256, uint256) {\n    //     (yx, yy) = _fq2inv(yx, yy);\n    //     return _fq2mul(xx, xy, yx, yy);\n    // }\n\n    /**\n     * @notice 1/FQ2 inverse operation\n     * @param x FQ2 operands first coordinate\n     * @param y FQ2 operands second coordinate\n     * @return Inv([xx, xy])\n     */\n    function _fq2inv(uint256 x, uint256 y) internal view returns (uint256, uint256) {\n        uint256 inv = _modInv(\n            addmod(mulmod(y, y, FIELD_MODULUS), mulmod(x, x, FIELD_MODULUS), FIELD_MODULUS),\n            FIELD_MODULUS\n        );\n        return (mulmod(x, inv, FIELD_MODULUS), FIELD_MODULUS - mulmod(y, inv, FIELD_MODULUS));\n    }\n\n    /**\n     * @notice Checks if FQ2 is on G2\n     * @param xx First FQ2 operands first coordinate\n     * @param xy First FQ2 operands second coordinate\n     * @param yx Second FQ2 operands first coordinate\n     * @param yy Second FQ2 operands second coordinate\n     * @return True if the FQ2 is on G2\n     */\n    function _isOnCurve(uint256 xx, uint256 xy, uint256 yx, uint256 yy) internal pure returns (bool) {\n        uint256 yyx;\n        uint256 yyy;\n        uint256 xxxx;\n        uint256 xxxy;\n        (yyx, yyy) = _fq2mul(yx, yy, yx, yy);\n        (xxxx, xxxy) = _fq2mul(xx, xy, xx, xy);\n        (xxxx, xxxy) = _fq2mul(xxxx, xxxy, xx, xy);\n        (yyx, yyy) = _fq2sub(yyx, yyy, xxxx, xxxy);\n        (yyx, yyy) = _fq2sub(yyx, yyy, TWISTBX, TWISTBY);\n        return yyx == 0 && yyy == 0;\n    }\n\n    /**\n     * @notice Calculates the modular inverse of a over n\n     * @param a The operand to calculate the inverse of\n     * @param n The modulus\n     * @return result Inv(a)modn\n     **/\n    function _modInv(uint256 a, uint256 n) internal view returns (uint256 result) {\n        bool success;\n        // prettier-ignore\n        // slither-disable-next-line assembly\n        assembly { // solhint-disable-line no-inline-assembly\n            let freemem := mload(0x40)\n            mstore(freemem, 0x20)\n            mstore(add(freemem, 0x20), 0x20)\n            mstore(add(freemem, 0x40), 0x20)\n            mstore(add(freemem, 0x60), a)\n            mstore(add(freemem, 0x80), sub(n, 2))\n            mstore(add(freemem, 0xA0), n)\n            success := staticcall(\n                sub(gas(), 2000),\n                5,\n                freemem,\n                0xC0,\n                freemem,\n                0x20\n            )\n            result := mload(freemem)\n        }\n        require(success, \"error with modular inverse\");\n    }\n\n    /**\n  * @notice Converts a point from jacobian to affine\n  * @param pt1xx First point x real coordinate\n  * @param pt1xy First point x imaginary coordinate\n  * @param pt1yx First point y real coordinate\n  * @param pt1yy First point y imaginary coordinate\n  * @param pt1zx First point z real coordinate\n  * @param pt1zy First point z imaginary coordinate\n  * @return pt2xx (x real affine coordinate)\n            pt2xy (x imaginary affine coordinate)\n            pt2yx (y real affine coordinate)\n            pt1zy (y imaginary affine coordinate)\n  **/\n    function _fromJacobian(\n        uint256 pt1xx,\n        uint256 pt1xy,\n        uint256 pt1yx,\n        uint256 pt1yy,\n        uint256 pt1zx,\n        uint256 pt1zy\n    ) internal view returns (uint256, uint256, uint256, uint256) {\n        uint256 invzx;\n        uint256 invzy;\n        uint256[4] memory pt2;\n        (invzx, invzy) = _fq2inv(pt1zx, pt1zy);\n        (pt2[0], pt2[1]) = _fq2mul(pt1xx, pt1xy, invzx, invzy);\n        (pt2[2], pt2[3]) = _fq2mul(pt1yx, pt1yy, invzx, invzy);\n        return (pt2[0], pt2[1], pt2[2], pt2[3]);\n    }\n\n    /**\n     * @notice Adds two points in jacobian coordinates\n     * @param pt1xx First point x real coordinate\n     * @param pt1xy First point x imaginary coordinate\n     * @param pt1yx First point y real coordinate\n     * @param pt1yy First point y imaginary coordinate\n     * @param pt1zx First point z real coordinate\n     * @param pt1zy First point z imaginary coordinate\n     * @param pt2xx Second point x real coordinate\n     * @param pt2xy Second point x imaginary coordinate\n     * @param pt2yx Second point y real coordinate\n     * @param pt2yy Second point y imaginary coordinate\n     * @param pt2zx Second point z real coordinate\n     * @param pt2zy Second point z imaginary coordinate\n     * @return pt3 = pt1+pt2 in jacobian\n     **/\n    function ecTwistAddJacobian(\n        uint256 pt1xx,\n        uint256 pt1xy,\n        uint256 pt1yx,\n        uint256 pt1yy,\n        uint256 pt1zx,\n        uint256 pt1zy,\n        uint256 pt2xx,\n        uint256 pt2xy,\n        uint256 pt2yx,\n        uint256 pt2yy,\n        uint256 pt2zx,\n        uint256 pt2zy\n    ) internal pure returns (uint256[6] memory pt3) {\n        if (pt1zx == 0 && pt1zy == 0) {\n            (pt3[PTXX], pt3[PTXY], pt3[PTYX], pt3[PTYY], pt3[PTZX], pt3[PTZY]) = (\n                pt2xx,\n                pt2xy,\n                pt2yx,\n                pt2yy,\n                pt2zx,\n                pt2zy\n            );\n            return pt3;\n        } else if (pt2zx == 0 && pt2zy == 0) {\n            (pt3[PTXX], pt3[PTXY], pt3[PTYX], pt3[PTYY], pt3[PTZX], pt3[PTZY]) = (\n                pt1xx,\n                pt1xy,\n                pt1yx,\n                pt1yy,\n                pt1zx,\n                pt1zy\n            );\n            return pt3;\n        }\n\n        (pt2yx, pt2yy) = _fq2mul(pt2yx, pt2yy, pt1zx, pt1zy); // U1 = y2 * z1\n        (pt3[PTYX], pt3[PTYY]) = _fq2mul(pt1yx, pt1yy, pt2zx, pt2zy); // U2 = y1 * z2\n        (pt2xx, pt2xy) = _fq2mul(pt2xx, pt2xy, pt1zx, pt1zy); // V1 = x2 * z1\n        (pt3[PTZX], pt3[PTZY]) = _fq2mul(pt1xx, pt1xy, pt2zx, pt2zy); // V2 = x1 * z2\n\n        if (pt2xx == pt3[PTZX] && pt2xy == pt3[PTZY]) {\n            if (pt2yx == pt3[PTYX] && pt2yy == pt3[PTYY]) {\n                (pt3[PTXX], pt3[PTXY], pt3[PTYX], pt3[PTYY], pt3[PTZX], pt3[PTZY]) = _ecTwistDoubleJacobian(\n                    pt1xx,\n                    pt1xy,\n                    pt1yx,\n                    pt1yy,\n                    pt1zx,\n                    pt1zy\n                );\n                return pt3;\n            }\n            (pt3[PTXX], pt3[PTXY], pt3[PTYX], pt3[PTYY], pt3[PTZX], pt3[PTZY]) = (1, 0, 1, 0, 0, 0);\n            return pt3;\n        }\n\n        (pt2zx, pt2zy) = _fq2mul(pt1zx, pt1zy, pt2zx, pt2zy); // W = z1 * z2\n        (pt1xx, pt1xy) = _fq2sub(pt2yx, pt2yy, pt3[PTYX], pt3[PTYY]); // U = U1 - U2\n        (pt1yx, pt1yy) = _fq2sub(pt2xx, pt2xy, pt3[PTZX], pt3[PTZY]); // V = V1 - V2\n        (pt1zx, pt1zy) = _fq2mul(pt1yx, pt1yy, pt1yx, pt1yy); // V_squared = V * V\n        (pt2yx, pt2yy) = _fq2mul(pt1zx, pt1zy, pt3[PTZX], pt3[PTZY]); // V_squared_times_V2 = V_squared * V2\n        (pt1zx, pt1zy) = _fq2mul(pt1zx, pt1zy, pt1yx, pt1yy); // V_cubed = V * V_squared\n        (pt3[PTZX], pt3[PTZY]) = _fq2mul(pt1zx, pt1zy, pt2zx, pt2zy); // newz = V_cubed * W\n        (pt2xx, pt2xy) = _fq2mul(pt1xx, pt1xy, pt1xx, pt1xy); // U * U\n        (pt2xx, pt2xy) = _fq2mul(pt2xx, pt2xy, pt2zx, pt2zy); // U * U * W\n        (pt2xx, pt2xy) = _fq2sub(pt2xx, pt2xy, pt1zx, pt1zy); // U * U * W - V_cubed\n        (pt2zx, pt2zy) = _fq2muc(pt2yx, pt2yy, 2); // 2 * V_squared_times_V2\n        (pt2xx, pt2xy) = _fq2sub(pt2xx, pt2xy, pt2zx, pt2zy); // A = U * U * W - V_cubed - 2 * V_squared_times_V2\n        (pt3[PTXX], pt3[PTXY]) = _fq2mul(pt1yx, pt1yy, pt2xx, pt2xy); // newx = V * A\n        (pt1yx, pt1yy) = _fq2sub(pt2yx, pt2yy, pt2xx, pt2xy); // V_squared_times_V2 - A\n        (pt1yx, pt1yy) = _fq2mul(pt1xx, pt1xy, pt1yx, pt1yy); // U * (V_squared_times_V2 - A)\n        (pt1xx, pt1xy) = _fq2mul(pt1zx, pt1zy, pt3[PTYX], pt3[PTYY]); // V_cubed * U2\n        (pt3[PTYX], pt3[PTYY]) = _fq2sub(pt1yx, pt1yy, pt1xx, pt1xy); // newy = U * (V_squared_times_V2 - A) - V_cubed * U2\n    }\n\n    /**\n     * @notice Doubls a point in jacobian coordinates\n     * @param pt1xx Point x real coordinate\n     * @param pt1xy Point x imaginary coordinate\n     * @param pt1yx Point y real coordinate\n     * @param pt1yy Point y imaginary coordinate\n     * @param pt1zx Point z real coordinate\n     * @param pt1zy Point z imaginary coordinate\n     * @return pt2xx, pt2xy, pt2yx, pt2yy, pt2zx, pt2zy the coordinates of pt2 = 2*pt1\n     **/\n    function _ecTwistDoubleJacobian(\n        uint256 pt1xx,\n        uint256 pt1xy,\n        uint256 pt1yx,\n        uint256 pt1yy,\n        uint256 pt1zx,\n        uint256 pt1zy\n    ) internal pure returns (uint256, uint256, uint256, uint256, uint256, uint256) {\n        uint256[6] memory pt2;\n        (pt2[0], pt2[1]) = _fq2muc(pt1xx, pt1xy, 3); // 3 * x\n        (pt2[0], pt2[1]) = _fq2mul(pt2[0], pt2[1], pt1xx, pt1xy); // W = 3 * x * x\n        (pt1zx, pt1zy) = _fq2mul(pt1yx, pt1yy, pt1zx, pt1zy); // S = y * z\n        (pt2[2], pt2[3]) = _fq2mul(pt1xx, pt1xy, pt1yx, pt1yy); // x * y\n        (pt2[2], pt2[3]) = _fq2mul(pt2[2], pt2[3], pt1zx, pt1zy); // B = x * y * S\n        (pt1xx, pt1xy) = _fq2mul(pt2[0], pt2[1], pt2[0], pt2[1]); // W * W\n        (pt2[4], pt2[5]) = _fq2muc(pt2[2], pt2[3], 8); // 8 * B\n        (pt1xx, pt1xy) = _fq2sub(pt1xx, pt1xy, pt2[4], pt2[5]); // H = W * W - 8 * B\n        (pt2[4], pt2[5]) = _fq2mul(pt1zx, pt1zy, pt1zx, pt1zy); // S_squared = S * S\n        (pt2[2], pt2[3]) = _fq2muc(pt2[2], pt2[3], 4); // 4 * B\n        (pt2[2], pt2[3]) = _fq2sub(pt2[2], pt2[3], pt1xx, pt1xy); // 4 * B - H\n        (pt2[2], pt2[3]) = _fq2mul(pt2[2], pt2[3], pt2[0], pt2[1]); // W * (4 * B - H)\n        (pt2[0], pt2[1]) = _fq2muc(pt1yx, pt1yy, 8); // 8 * y\n        (pt2[0], pt2[1]) = _fq2mul(pt2[0], pt2[1], pt1yx, pt1yy); // 8 * y * y\n        (pt2[0], pt2[1]) = _fq2mul(pt2[0], pt2[1], pt2[4], pt2[5]); // 8 * y * y * S_squared\n        (pt2[2], pt2[3]) = _fq2sub(pt2[2], pt2[3], pt2[0], pt2[1]); // newy = W * (4 * B - H) - 8 * y * y * S_squared\n        (pt2[0], pt2[1]) = _fq2muc(pt1xx, pt1xy, 2); // 2 * H\n        (pt2[0], pt2[1]) = _fq2mul(pt2[0], pt2[1], pt1zx, pt1zy); // newx = 2 * H * S\n        (pt2[4], pt2[5]) = _fq2mul(pt1zx, pt1zy, pt2[4], pt2[5]); // S * S_squared\n        (pt2[4], pt2[5]) = _fq2muc(pt2[4], pt2[5], 8); // newz = 8 * S * S_squared\n\n        return (pt2[0], pt2[1], pt2[2], pt2[3], pt2[4], pt2[5]);\n    }\n\n    /**\n     * @notice Doubls a point in jacobian coordinates\n     * @param d scalar to multiply the point with\n     * @param pt1xx Point x real coordinate\n     * @param pt1xy Point x imaginary coordinate\n     * @param pt1yx Point y real coordinate\n     * @param pt1yy Point y imaginary coordinate\n     * @param pt1zx Point z real coordinate\n     * @param pt1zy Point z imaginary coordinate\n     * @return pt2 a point representing pt2 = d*pt1 in jacobian coordinates\n     **/\n    function _ecTwistMulJacobian(\n        uint256 d,\n        uint256 pt1xx,\n        uint256 pt1xy,\n        uint256 pt1yx,\n        uint256 pt1yy,\n        uint256 pt1zx,\n        uint256 pt1zy\n    ) internal pure returns (uint256[6] memory pt2) {\n        while (d != 0) {\n            if ((d & 1) != 0) {\n                pt2 = ecTwistAddJacobian(\n                    pt2[PTXX],\n                    pt2[PTXY],\n                    pt2[PTYX],\n                    pt2[PTYY],\n                    pt2[PTZX],\n                    pt2[PTZY],\n                    pt1xx,\n                    pt1xy,\n                    pt1yx,\n                    pt1yy,\n                    pt1zx,\n                    pt1zy\n                );\n            }\n            (pt1xx, pt1xy, pt1yx, pt1yy, pt1zx, pt1zy) = _ecTwistDoubleJacobian(\n                pt1xx,\n                pt1xy,\n                pt1yx,\n                pt1yy,\n                pt1zx,\n                pt1zy\n            );\n\n            d = d / 2;\n        }\n        return pt2;\n    }\n}\n"
      },
      "contracts/interfaces/common/IBN256G2.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\n\ninterface IBN256G2 {\n    function ecTwistAdd(\n        uint256 pt1xx,\n        uint256 pt1xy,\n        uint256 pt1yx,\n        uint256 pt1yy,\n        uint256 pt2xx,\n        uint256 pt2xy,\n        uint256 pt2yx,\n        uint256 pt2yy\n    ) external view returns (uint256, uint256, uint256, uint256);\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 115
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}