creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/block/klaytn/KlaytnVerifier1.sol": {
        "content": "\n// SPDX-License-Identifier: AML\n// \n// Copyright 2017 Christian Reitwiessner\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal in the Software without restriction, including without limitation the\n// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n// sell copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n// IN THE SOFTWARE.\n\n// 2019 OKIMS\n\npragma solidity ^0.8.0;\n\nlibrary Pairing {\n\n    uint256 constant PRIME_Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n    struct G1Point {\n        uint256 X;\n        uint256 Y;\n    }\n\n    // Encoding of field elements is: X[0] * z + X[1]\n    struct G2Point {\n        uint256[2] X;\n        uint256[2] Y;\n    }\n\n    /*\n     * @return The negation of p, i.e. p.plus(p.negate()) should be zero. \n     */\n    function negate(G1Point memory p) internal pure returns (G1Point memory) {\n\n        // The prime q in the base field F_q for G1\n        if (p.X == 0 && p.Y == 0) {\n            return G1Point(0, 0);\n        } else {\n            return G1Point(p.X, PRIME_Q - (p.Y % PRIME_Q));\n        }\n    }\n\n    /*\n     * @return The sum of two points of G1\n     */\n    function plus(\n        G1Point memory p1,\n        G1Point memory p2\n    ) internal view returns (G1Point memory r) {\n\n        uint256[4] memory input;\n        input[0] = p1.X;\n        input[1] = p1.Y;\n        input[2] = p2.X;\n        input[3] = p2.Y;\n        bool success;\n\n        // solium-disable-next-line security/no-inline-assembly\n        assembly {\n            success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60)\n            // Use \"invalid\" to make gas estimation work\n            switch success case 0 { invalid() }\n        }\n\n        require(success,\"pairing-add-failed\");\n    }\n\n    /*\n     * @return The product of a point on G1 and a scalar, i.e.\n     *         p == p.scalar_mul(1) and p.plus(p) == p.scalar_mul(2) for all\n     *         points p.\n     */\n    function scalar_mul(G1Point memory p, uint256 s) internal view returns (G1Point memory r) {\n\n        uint256[3] memory input;\n        input[0] = p.X;\n        input[1] = p.Y;\n        input[2] = s;\n        bool success;\n        // solium-disable-next-line security/no-inline-assembly\n        assembly {\n            success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60)\n            // Use \"invalid\" to make gas estimation work\n            switch success case 0 { invalid() }\n        }\n        require (success,\"pairing-mul-failed\");\n    }\n\n    /* @return The result of computing the pairing check\n     *         e(p1[0], p2[0]) *  .... * e(p1[n], p2[n]) == 1\n     *         For example,\n     *         pairing([P1(), P1().negate()], [P2(), P2()]) should return true.\n     */\n    function pairing(\n        G1Point memory a1,\n        G2Point memory a2,\n        G1Point memory b1,\n        G2Point memory b2,\n        G1Point memory c1,\n        G2Point memory c2,\n        G1Point memory d1,\n        G2Point memory d2\n    ) internal view returns (bool) {\n\n        G1Point[4] memory p1 = [a1, b1, c1, d1];\n        G2Point[4] memory p2 = [a2, b2, c2, d2];\n        uint256 inputSize = 24;\n        uint256[] memory input = new uint256[](inputSize);\n\n        for (uint256 i = 0; i < 4; i++) {\n            uint256 j = i * 6;\n            input[j + 0] = p1[i].X;\n            input[j + 1] = p1[i].Y;\n            input[j + 2] = p2[i].X[0];\n            input[j + 3] = p2[i].X[1];\n            input[j + 4] = p2[i].Y[0];\n            input[j + 5] = p2[i].Y[1];\n        }\n\n        uint256[1] memory out;\n        bool success;\n\n        // solium-disable-next-line security/no-inline-assembly\n        assembly {\n            success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)\n            // Use \"invalid\" to make gas estimation work\n            switch success case 0 { invalid() }\n        }\n\n        require(success,\"pairing-opcode-failed\");\n\n        return out[0] != 0;\n    }\n}\n\ncontract KlaytnVerifier1 {\n\n    using Pairing for *;\n\n    uint256 constant SNARK_SCALAR_FIELD = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n    uint256 constant PRIME_Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n    struct VerifyingKey {\n        Pairing.G1Point alfa1;\n        Pairing.G2Point beta2;\n        Pairing.G2Point gamma2;\n        Pairing.G2Point delta2;\n        Pairing.G1Point[2] IC;\n    }\n\n    struct Proof {\n        Pairing.G1Point A;\n        Pairing.G2Point B;\n        Pairing.G1Point C;\n    }\n\n    function verifyingKey() internal pure returns (VerifyingKey memory vk) {\n        vk.alfa1 = Pairing.G1Point(uint256(14820542169496133627943893937263966730412016483728569597218019882159838125142), uint256(13884083337586751934602797225794391242107929517789361848254014402346150404719));\n        vk.beta2 = Pairing.G2Point([uint256(6363926084419084023963750704632317434680201707728517109516445212620973330530), uint256(3784849544315453709755642200584789822270866934497043744612686676971133812752)], [uint256(13960821232074503009780070494953275039939224541965795587122494892628066319688), uint256(2416827433127142748292219740478814938144409906197993593832601691144147258567)]);\n        vk.gamma2 = Pairing.G2Point([uint256(12595138751175448726137809497851927616037490255443742602959561966556418627037), uint256(4462727133788807697551507834301684766176140883053107442492142544045795997932)], [uint256(17204587168965435806621518118270706174031582124517911240147044880884488351457), uint256(4014097454921043866477640348308031536287537864148851435944083357241169727836)]);\n        vk.delta2 = Pairing.G2Point([uint256(5284473149886641835840506117101397106866352989498918471849976053158531568495), uint256(13359671861129997743386314623723315838261158324079423982310884041806217063265)], [uint256(8676689093180123110782595640014616396623664056923475252274186990557238271125), uint256(5777413967249073354001723208875099953172839447302390837713593738084643340889)]);   \n        vk.IC[0] = Pairing.G1Point(uint256(13054780285827460406838333795452445911502617906500909194738963288329937552208), uint256(3903035971336420451488176485010676172454286808903136132893523338941122763961));   \n        vk.IC[1] = Pairing.G1Point(uint256(627656387961465479508914084702695384253346517404813223466798774728912136037), uint256(13494071681146698343005787175226489826044441629119500897632006986224283402335));\n    }\n    \n    /*\n     * @returns Whether the proof is valid given the hardcoded verifying key\n     *          above and the public inputs\n     */\n    function verifyProof(\n        uint256[2] memory a,\n        uint256[2][2] memory b,\n        uint256[2] memory c,\n        uint256[1] memory input\n    ) public view returns (bool r) {\n\n        Proof memory proof;\n        proof.A = Pairing.G1Point(a[0], a[1]);\n        proof.B = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]);\n        proof.C = Pairing.G1Point(c[0], c[1]);\n\n        VerifyingKey memory vk = verifyingKey();\n\n        // Compute the linear combination vk_x\n        Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0);\n\n        // Make sure that proof.A, B, and C are each less than the prime q\n        require(proof.A.X < PRIME_Q, \"verifier-aX-gte-prime-q\");\n        require(proof.A.Y < PRIME_Q, \"verifier-aY-gte-prime-q\");\n\n        require(proof.B.X[0] < PRIME_Q, \"verifier-bX0-gte-prime-q\");\n        require(proof.B.Y[0] < PRIME_Q, \"verifier-bY0-gte-prime-q\");\n\n        require(proof.B.X[1] < PRIME_Q, \"verifier-bX1-gte-prime-q\");\n        require(proof.B.Y[1] < PRIME_Q, \"verifier-bY1-gte-prime-q\");\n\n        require(proof.C.X < PRIME_Q, \"verifier-cX-gte-prime-q\");\n        require(proof.C.Y < PRIME_Q, \"verifier-cY-gte-prime-q\");\n\n        // Make sure that every input is less than the snark scalar field\n        for (uint256 i = 0; i < input.length; i++) {\n            require(input[i] < SNARK_SCALAR_FIELD,\"verifier-gte-snark-scalar-field\");\n            vk_x = Pairing.plus(vk_x, Pairing.scalar_mul(vk.IC[i + 1], input[i]));\n        }\n\n        vk_x = Pairing.plus(vk_x, vk.IC[0]);\n\n        return Pairing.pairing(\n            Pairing.negate(proof.A),\n            proof.B,\n            vk.alfa1,\n            vk.beta2,\n            vk_x,\n            vk.gamma2,\n            proof.C,\n            vk.delta2\n        );\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}