Verifier

Description:

Smart contract deployed on Ethereum with Factory features.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "src/Verifier.sol": {
      "content": "    // SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import {IVerifier} from "./interface/IVerifier.sol";

/* solhint-disable max-line-length */
/// @author Project Ooo team
/// @dev It uses a custom memory layout inside the inline assembly block. Each reserved memory cell is declared in the
/// constants below.
/// @dev For a better understanding of the verifier algorithm please refer to the following papers:
/// *
/// * Original Tokamak zkSNARK Paper: https://eprint.iacr.org/2024/507.pdf
/// The notation used in the code is the same as in the papers.
/* solhint-enable max-line-length */
contract Verifier is IVerifier {
    /*//////////////////////////////////////////////////////////////
                                    Proof
    //////////////////////////////////////////////////////////////*/

    /// The encoding order of the `proof` (part1) is
    /// ```
    /// |                  672 bytes                 |
    /// | Polynomial commitments (16th first bytes)  |
    /// ```

    /// The encoding order of the `proof` (part2) is
    /// ```
    /// |               1344 bytes                |   32 bytes  |   32 bytes   |   32 bytes  |   32 bytes  |
    /// | Polynomial commitments (last 32 bytes)  |   R_{x,y}   |   R'_{x,y}   |   R''_{x,y} |   V_{x,y}   |
    /// ```

    // [s^{(0)}(x,y)]_1
    uint256 internal constant PUBLIC_INPUTS_S_0_X_SLOT_PART1 = 0x8000 + 0x200 + 0x040;
    uint256 internal constant PUBLIC_INPUTS_S_0_X_SLOT_PART2 = 0x8000 + 0x200 + 0x060;
    uint256 internal constant PUBLIC_INPUTS_S_0_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x080;
    uint256 internal constant PUBLIC_INPUTS_S_0_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x0a0;

    // [s^{(1)}(x,y)]_1
    uint256 internal constant PUBLIC_INPUTS_S_1_X_SLOT_PART1 = 0x8000 + 0x200 + 0x0c0;
    uint256 internal constant PUBLIC_INPUTS_S_1_X_SLOT_PART2 = 0x8000 + 0x200 + 0x0e0;
    uint256 internal constant PUBLIC_INPUTS_S_1_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x100;
    uint256 internal constant PUBLIC_INPUTS_S_1_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120;

    // U
    uint256 internal constant PROOF_POLY_U_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x020;
    uint256 internal constant PROOF_POLY_U_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x040;
    uint256 internal constant PROOF_POLY_U_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x060;
    uint256 internal constant PROOF_POLY_U_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x080;
    // V
    uint256 internal constant PROOF_POLY_V_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x0a0;
    uint256 internal constant PROOF_POLY_V_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x0c0;
    uint256 internal constant PROOF_POLY_V_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x0e0;
    uint256 internal constant PROOF_POLY_V_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x100;
    // W
    uint256 internal constant PROOF_POLY_W_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x120;
    uint256 internal constant PROOF_POLY_W_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x140;
    uint256 internal constant PROOF_POLY_W_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x160;
    uint256 internal constant PROOF_POLY_W_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x180;
    // O_mid
    uint256 internal constant PROOF_POLY_OMID_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x1a0;
    uint256 internal constant PROOF_POLY_OMID_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x1c0;
    uint256 internal constant PROOF_POLY_OMID_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x1e0;
    uint256 internal constant PROOF_POLY_OMID_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x200;
    // O_prv
    uint256 internal constant PROOF_POLY_OPRV_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x220;
    uint256 internal constant PROOF_POLY_OPRV_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x240;
    uint256 internal constant PROOF_POLY_OPRV_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x260;
    uint256 internal constant PROOF_POLY_OPRV_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x280;
    // Q_{AX}
    uint256 internal constant PROOF_POLY_QAX_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x2a0;
    uint256 internal constant PROOF_POLY_QAX_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x2c0;
    uint256 internal constant PROOF_POLY_QAX_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x2e0;
    uint256 internal constant PROOF_POLY_QAX_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x300;
    // Q_{AY}
    uint256 internal constant PROOF_POLY_QAY_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x320;
    uint256 internal constant PROOF_POLY_QAY_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x340;
    uint256 internal constant PROOF_POLY_QAY_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x360;
    uint256 internal constant PROOF_POLY_QAY_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x380;
    // Q_{CX}
    uint256 internal constant PROOF_POLY_QCX_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x3a0;
    uint256 internal constant PROOF_POLY_QCX_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x3c0;
    uint256 internal constant PROOF_POLY_QCX_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x3e0;
    uint256 internal constant PROOF_POLY_QCX_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x400;
    // Q_{CY}
    uint256 internal constant PROOF_POLY_QCY_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x420;
    uint256 internal constant PROOF_POLY_QCY_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x440;
    uint256 internal constant PROOF_POLY_QCY_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x460;
    uint256 internal constant PROOF_POLY_QCY_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x480;
    // Π_{χ}
    uint256 internal constant PROOF_POLY_PI_CHI_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x4a0;
    uint256 internal constant PROOF_POLY_PI_CHI_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x4c0;
    uint256 internal constant PROOF_POLY_PI_CHI_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x4e0;
    uint256 internal constant PROOF_POLY_PI_CHI_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x500;
    // Π{ζ}
    uint256 internal constant PROOF_POLY_PI_ZETA_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x520;
    uint256 internal constant PROOF_POLY_PI_ZETA_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x540;
    uint256 internal constant PROOF_POLY_PI_ZETA_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x560;
    uint256 internal constant PROOF_POLY_PI_ZETA_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x580;
    // B
    uint256 internal constant PROOF_POLY_B_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x5a0;
    uint256 internal constant PROOF_POLY_B_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x5c0;
    uint256 internal constant PROOF_POLY_B_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x5e0;
    uint256 internal constant PROOF_POLY_B_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x600;
    // R
    uint256 internal constant PROOF_POLY_R_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x620;
    uint256 internal constant PROOF_POLY_R_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x640;
    uint256 internal constant PROOF_POLY_R_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x660;
    uint256 internal constant PROOF_POLY_R_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x680;
    // M_ζ
    uint256 internal constant PROOF_POLY_M_ZETA_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x6a0;
    uint256 internal constant PROOF_POLY_M_ZETA_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x6c0;
    uint256 internal constant PROOF_POLY_M_ZETA_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x6e0;
    uint256 internal constant PROOF_POLY_M_ZETA_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x700;
    // M_χ
    uint256 internal constant PROOF_POLY_M_CHI_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x720;
    uint256 internal constant PROOF_POLY_M_CHI_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x740;
    uint256 internal constant PROOF_POLY_M_CHI_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x760;
    uint256 internal constant PROOF_POLY_M_CHI_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x780;
    // N_ζ
    uint256 internal constant PROOF_POLY_N_ZETA_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x7a0;
    uint256 internal constant PROOF_POLY_N_ZETA_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x7c0;
    uint256 internal constant PROOF_POLY_N_ZETA_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x7e0;
    uint256 internal constant PROOF_POLY_N_ZETA_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x800;
    // N_χ
    uint256 internal constant PROOF_POLY_N_CHI_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x820;
    uint256 internal constant PROOF_POLY_N_CHI_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x840;
    uint256 internal constant PROOF_POLY_N_CHI_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x860;
    uint256 internal constant PROOF_POLY_N_CHI_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x880;
    // O_pub
    uint256 internal constant PROOF_POLY_OPUB_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x8a0;
    uint256 internal constant PROOF_POLY_OPUB_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x8c0;
    uint256 internal constant PROOF_POLY_OPUB_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x8e0;
    uint256 internal constant PROOF_POLY_OPUB_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x900;
    // A
    uint256 internal constant PROOF_POLY_A_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x920;
    uint256 internal constant PROOF_POLY_A_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x940;
    uint256 internal constant PROOF_POLY_A_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0x960;
    uint256 internal constant PROOF_POLY_A_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0x980;
    // R_xy
    uint256 internal constant PROOF_R1XY_SLOT = 0x8000 + 0x200 + 0x120 + 0x9a0;
    // R'_xy
    uint256 internal constant PROOF_R2XY_SLOT = 0x8000 + 0x200 + 0x120 + 0x9c0;
    // R''_xy
    uint256 internal constant PROOF_R3XY_SLOT = 0x8000 + 0x200 + 0x120 + 0x9e0;
    // V_xy
    uint256 internal constant PROOF_VXY_SLOT = 0x8000 + 0x200 + 0x120 + 0xa00;

    /*//////////////////////////////////////////////////////////////
                transcript slot (used for challenge computation)
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant TRANSCRIPT_BEGIN_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x00;
    uint256 internal constant TRANSCRIPT_DST_BYTE_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x03;
    uint256 internal constant TRANSCRIPT_STATE_0_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x04;
    uint256 internal constant TRANSCRIPT_STATE_1_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x24;
    uint256 internal constant TRANSCRIPT_CHALLENGE_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x44;

    /*//////////////////////////////////////////////////////////////
                                Challenges
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant CHALLENGE_THETA_0_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x000;
    uint256 internal constant CHALLENGE_THETA_1_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x020;
    uint256 internal constant CHALLENGE_THETA_2_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x040;
    uint256 internal constant CHALLENGE_KAPPA_0_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x060;
    uint256 internal constant CHALLENGE_KAPPA_1_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x080;
    uint256 internal constant CHALLENGE_KAPPA_2_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x0a0;
    uint256 internal constant CHALLENGE_ZETA_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x0c0;
    uint256 internal constant CHALLENGE_XI_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x0e0;
    uint256 internal constant CHALLENGE_CHI_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100;

    /*//////////////////////////////////////////////////////////////
                        Intermediary verifier state
    //////////////////////////////////////////////////////////////*/

    // [F]_1
    uint256 internal constant INTERMERDIARY_POLY_F_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x020;
    uint256 internal constant INTERMERDIARY_POLY_F_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x040;
    uint256 internal constant INTERMERDIARY_POLY_F_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x060;
    uint256 internal constant INTERMERDIARY_POLY_F_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x080;

    // [G]_1
    uint256 internal constant INTERMERDIARY_POLY_G_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x0a0;
    uint256 internal constant INTERMERDIARY_POLY_G_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x0c0;
    uint256 internal constant INTERMERDIARY_POLY_G_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x0e0;
    uint256 internal constant INTERMERDIARY_POLY_G_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x100;

    // t_n(χ)
    uint256 internal constant INTERMERDIARY_SCALAR_T_N_CHI_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x120;
    // t_smax(ζ)
    uint256 internal constant INTERMERDIARY_SCALAR_T_SMAX_ZETA_SLOT =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x140;
    // t_ml(χ)
    uint256 internal constant INTERMERDIARY_SCALAR_T_MI_CHI_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x160;
    // K_0(χ)
    uint256 internal constant INTERMEDIARY_SCALAR_KO_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x180;
    // A_pub
    uint256 internal constant INTERMEDIARY_SCALAR_APUB_SLOT = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0;

    /*//////////////////////////////////////////////////////////////
                      Aggregated commitment
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant AGG_LHS_A_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x020;
    uint256 internal constant AGG_LHS_A_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x040;
    uint256 internal constant AGG_LHS_A_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x060;
    uint256 internal constant AGG_LHS_A_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x080;

    uint256 internal constant AGG_LHS_B_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x0a0;
    uint256 internal constant AGG_LHS_B_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x0c0;
    uint256 internal constant AGG_LHS_B_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x0e0;
    uint256 internal constant AGG_LHS_B_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x100;

    uint256 internal constant AGG_LHS_C_X_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x120;
    uint256 internal constant AGG_LHS_C_X_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x140;
    uint256 internal constant AGG_LHS_C_Y_SLOT_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x160;
    uint256 internal constant AGG_LHS_C_Y_SLOT_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x180;

    uint256 internal constant PAIRING_AGG_LHS_X_SLOT_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x1a0;
    uint256 internal constant PAIRING_AGG_LHS_X_SLOT_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x1c0;
    uint256 internal constant PAIRING_AGG_LHS_Y_SLOT_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x1e0;
    uint256 internal constant PAIRING_AGG_LHS_Y_SLOT_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x200;

    uint256 internal constant PAIRING_AGG_AUX_X_SLOT_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x220;
    uint256 internal constant PAIRING_AGG_AUX_X_SLOT_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x240;
    uint256 internal constant PAIRING_AGG_AUX_Y_SLOT_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x260;
    uint256 internal constant PAIRING_AGG_AUX_Y_SLOT_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x280;

    uint256 internal constant PAIRING_AGG_LHS_AUX_X_SLOT_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x2a0;
    uint256 internal constant PAIRING_AGG_LHS_AUX_X_SLOT_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x2c0;
    uint256 internal constant PAIRING_AGG_LHS_AUX_Y_SLOT_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x2e0;
    uint256 internal constant PAIRING_AGG_LHS_AUX_Y_SLOT_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x300;

    uint256 internal constant PAIRING_AGG_RHS_1_X_SLOT_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x320;
    uint256 internal constant PAIRING_AGG_RHS_1_X_SLOT_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x340;
    uint256 internal constant PAIRING_AGG_RHS_1_Y_SLOT_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x360;
    uint256 internal constant PAIRING_AGG_RHS_1_Y_SLOT_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x380;

    uint256 internal constant PAIRING_AGG_RHS_2_X_SLOT_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x3a0;
    uint256 internal constant PAIRING_AGG_RHS_2_X_SLOT_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x3c0;
    uint256 internal constant PAIRING_AGG_RHS_2_Y_SLOT_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x3e0;
    uint256 internal constant PAIRING_AGG_RHS_2_Y_SLOT_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x400;

    /*//////////////////////////////////////////////////////////////
                                Pairing data
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant BUFFER_AGGREGATED_POLY_X_SLOT_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x420;
    uint256 internal constant BUFFER_AGGREGATED_POLY_X_SLOT_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x440;
    uint256 internal constant BUFFER_AGGREGATED_POLY_Y_SLOT_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x460;
    uint256 internal constant BUFFER_AGGREGATED_POLY_Y_SLOT_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480;

    /*//////////////////////////////////////////////////////////////
                            Verification keys
    //////////////////////////////////////////////////////////////*/

    // [K^_1(X)L^-1(X)]_1
    uint256 internal constant VK_POLY_KXLX_X_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x020;
    uint256 internal constant VK_POLY_KXLX_X_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x040;
    uint256 internal constant VK_POLY_KXLX_Y_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x060;
    uint256 internal constant VK_POLY_KXLX_Y_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x080;

    // [x]_1
    uint256 internal constant VK_POLY_X_X_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x0a0;
    uint256 internal constant VK_POLY_X_X_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x0c0;
    uint256 internal constant VK_POLY_X_Y_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x0e0;
    uint256 internal constant VK_POLY_X_Y_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x100;

    // [y]_1
    uint256 internal constant VK_POLY_Y_X_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x120;
    uint256 internal constant VK_POLY_Y_X_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x140;
    uint256 internal constant VK_POLY_Y_Y_PART1 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x160;
    uint256 internal constant VK_POLY_Y_Y_PART2 = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x180;

    // [1]_1
    uint256 internal constant VK_IDENTITY_X_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x1a0;
    uint256 internal constant VK_IDENTITY_X_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x1c0;
    uint256 internal constant VK_IDENTITY_Y_PART1 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x1e0;
    uint256 internal constant VK_IDENTITY_Y_PART2 =
        0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x200;

    /*//////////////////////////////////////////////////////////////
                                trusted-setup param
    //////////////////////////////////////////////////////////////*/

    // smax
    uint256 internal constant PARAM_SMAX = 0x8000 + 0x200 + 0x120 + 0xa20 + 0x80 + 0x100 + 0x1a0 + 0x480 + 0x200 + 0x020;

    /*//////////////////////////////////////////////////////////////
                                Constants
    //////////////////////////////////////////////////////////////*/

    // Scalar field size
    // Q_MOD is the base field modulus (48 bytes long). To fit with the EVM, we sliced it into two 32bytes variables => 16 first bytes are zeros
    uint256 internal constant Q_MOD_PART1 = 0x000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd7;
    uint256 internal constant Q_MOD_PART2 = 0x64774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab;
    // R_MOD is the main subgroup order
    uint256 internal constant R_MOD = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001;

    /// @dev flip of 0xe000000000000000000000000000000000000000000000000000000000000000;
    uint256 internal constant FR_MASK = 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

    // n
    uint256 internal constant CONSTANT_N = 1024;
    // ω_64
    uint256 internal constant OMEGA_64 = 0x0e4840ac57f86f5e293b1d67bc8de5d9a12a70a615d0b8e4d2fc5e69ac5db47f;
    // m_i
    uint256 internal constant CONSTANT_MI = 1024;

    // ω_{m_i}^{-1}
    uint256 internal constant OMEGA_MI_1 = 0x2bcd9508a3dad316105f067219141f4450a32c41aa67e0beb0ad80034eb71aa6;

    // ω_smax_64^{-1}
    uint256 internal constant OMEGA_SMAX_64_MINUS_1 = 0x199cdaee7b3c79d6566009b5882952d6a41e85011d426b52b891fa3f982b68c5;
    // ω_smax_128^{-1}
    uint256 internal constant OMEGA_SMAX_128_MINUS_1 =
        0x1996fa8d52f970ba51420be43501370b166fb582ac74db12571ba2fccf28601b;
    // ω_smax_256^{-1}
    uint256 internal constant OMEGA_SMAX_256_MINUS_1 =
        0x6d64ed25272e58ee91b000235a5bfd4fc03cae032393991be9561c176a2f777a;
    // ω_smax_512^{-1}
    uint256 internal constant OMEGA_SMAX_512_MINUS_1 =
        0x1907a56e80f82b2df675522e37ad4eca1c510ebfb4543a3efb350dbef02a116e;
    // ω_smax_1024^{-1}
    uint256 internal constant OMEGA_SMAX_1024_MINUS_1 =
        0x2bcd9508a3dad316105f067219141f4450a32c41aa67e0beb0ad80034eb71aa6;
    // ω_smax_2048^{-1}
    uint256 internal constant OMEGA_SMAX_2048_MINUS_1 =
        0x394fda0d65ba213edeae67bc36f376e13cc5bb329aa58ff53dc9e5600f6fb2ac;

    /*//////////////////////////////////////////////////////////////
                            G2 elements
        //////////////////////////////////////////////////////////////*/

    // G2 Points for zkEVM Verifier (BLS12-381) - Standard Naming Convention
    // Each point uses 8 uint256 slots (256 bytes total)
    // Format: X0_PART1, X0_PART2, X1_PART1, X1_PART2, Y0_PART1, Y0_PART2, Y1_PART1, Y1_PART2

    //H: G2serde(Affine { x: 0x1116094a7c01d4fd8abcfea69c658c92c037765bee00556b8d4063c33540b316ac68a2d913d3adc3b43c7d7cc7505cfc17206c8ae661f247979b3f1daa7fb6d5f7ce9c17b5ed1d7e8b421a2508b3f09a603e6a5fab3fcde7364fd178d656ac36, y: 0x15bf297a4b9842fb1a3a6f2dbf6b94de06997b11b2f72436c22efbb48d2f74b0de7239ea182a2ee50c23ae3d0be6fdee09459611409874fe4b04b1a7e42cb84eb4ae01728dc55dbd1343fda8d0fe94a299fc757acc1d2602a49a005b4ff90190 })
    // [1]_2 (Identity/Generator point H)
    uint256 internal constant IDENTITY2_X0_PART1 = 0x000000000000000000000000000000001116094a7c01d4fd8abcfea69c658c92;
    uint256 internal constant IDENTITY2_X0_PART2 = 0xc037765bee00556b8d4063c33540b316ac68a2d913d3adc3b43c7d7cc7505cfc;
    uint256 internal constant IDENTITY2_X1_PART1 = 0x0000000000000000000000000000000017206c8ae661f247979b3f1daa7fb6d5;
    uint256 internal constant IDENTITY2_X1_PART2 = 0xf7ce9c17b5ed1d7e8b421a2508b3f09a603e6a5fab3fcde7364fd178d656ac36;
    uint256 internal constant IDENTITY2_Y0_PART1 = 0x0000000000000000000000000000000015bf297a4b9842fb1a3a6f2dbf6b94de;
    uint256 internal constant IDENTITY2_Y0_PART2 = 0x06997b11b2f72436c22efbb48d2f74b0de7239ea182a2ee50c23ae3d0be6fdee;
    uint256 internal constant IDENTITY2_Y1_PART1 = 0x0000000000000000000000000000000009459611409874fe4b04b1a7e42cb84e;
    uint256 internal constant IDENTITY2_Y1_PART2 = 0xb4ae01728dc55dbd1343fda8d0fe94a299fc757acc1d2602a49a005b4ff90190;

    //alpha: G2serde(Affine { x: 0x05fc26da747c6cfef0305b496594b460e39e12dca4aebacb2d4bb6d2c4b02b2c50fe7ffe6f33940434a15a9425aa82ed0494bd39f21522f3fe14c8f9283e3fa1e05e39e804bb1881ef4529958798c9b68126138e3594797bc2f7042824b7d97e, y: 0x11161b94b2a44106ed5b9226279a2469c0eccdfedd34359d8577b9d980b238e80b97ad277d2c3010e94054edfa20e2e00e0075cf9d5766c2f27a41f2ebaf2aa2029de98dae9e4ab91c03b2c36a905d1e31072a0999bcde2a3c7722870cf0a2ec })
    // [α]_2
    uint256 internal constant ALPHA_X0_PART1 = 0x0000000000000000000000000000000005fc26da747c6cfef0305b496594b460;
    uint256 internal constant ALPHA_X0_PART2 = 0xe39e12dca4aebacb2d4bb6d2c4b02b2c50fe7ffe6f33940434a15a9425aa82ed;
    uint256 internal constant ALPHA_X1_PART1 = 0x000000000000000000000000000000000494bd39f21522f3fe14c8f9283e3fa1;
    uint256 internal constant ALPHA_X1_PART2 = 0xe05e39e804bb1881ef4529958798c9b68126138e3594797bc2f7042824b7d97e;
    uint256 internal constant ALPHA_Y0_PART1 = 0x0000000000000000000000000000000011161b94b2a44106ed5b9226279a2469;
    uint256 internal constant ALPHA_Y0_PART2 = 0xc0eccdfedd34359d8577b9d980b238e80b97ad277d2c3010e94054edfa20e2e0;
    uint256 internal constant ALPHA_Y1_PART1 = 0x000000000000000000000000000000000e0075cf9d5766c2f27a41f2ebaf2aa2;
    uint256 internal constant ALPHA_Y1_PART2 = 0x029de98dae9e4ab91c03b2c36a905d1e31072a0999bcde2a3c7722870cf0a2ec;

    //alpha2: G2serde(Affine { x: 0x133162dff634e8ff94132dd738659db83d0618c48e8c6c8d5b0805ad237364eeaf06286440b00c8e68faeec4ed9c154b1065e41eba7012b1b416f58dd3bbdda89bf3a06944476337565ab07746065e3807f5a04f933453e48f3edb96b86f5e52, y: 0x19f032956715814f77a9bd9e06ccb681bf2af52adbbed8df7b01b04966db248c80b76328459349995d0780cfe4ac11ba0b13ca416c480313f7dfba208414d08412adecdc9f8b84e0ec2dcb4e532e2d6d1f6e6d2308bc7b4e38072e51d40c3d04 })
    // [α^2]_2
    uint256 internal constant ALPHA_POWER2_X0_PART1 = 0x00000000000000000000000000000000133162dff634e8ff94132dd738659db8;
    uint256 internal constant ALPHA_POWER2_X0_PART2 = 0x3d0618c48e8c6c8d5b0805ad237364eeaf06286440b00c8e68faeec4ed9c154b;
    uint256 internal constant ALPHA_POWER2_X1_PART1 = 0x000000000000000000000000000000001065e41eba7012b1b416f58dd3bbdda8;
    uint256 internal constant ALPHA_POWER2_X1_PART2 = 0x9bf3a06944476337565ab07746065e3807f5a04f933453e48f3edb96b86f5e52;
    uint256 internal constant ALPHA_POWER2_Y0_PART1 = 0x0000000000000000000000000000000019f032956715814f77a9bd9e06ccb681;
    uint256 internal constant ALPHA_POWER2_Y0_PART2 = 0xbf2af52adbbed8df7b01b04966db248c80b76328459349995d0780cfe4ac11ba;
    uint256 internal constant ALPHA_POWER2_Y1_PART1 = 0x000000000000000000000000000000000b13ca416c480313f7dfba208414d084;
    uint256 internal constant ALPHA_POWER2_Y1_PART2 = 0x12adecdc9f8b84e0ec2dcb4e532e2d6d1f6e6d2308bc7b4e38072e51d40c3d04;

    //alpha3: G2serde(Affine { x: 0x03f4debb62e445a8d577dfcb3b9e9e6fbfeff7390c23dae3c84bbe70394c5d8c8bfcd81f39ab65db1647ac9e7905a830048e5721d748709bdb68b01af622428ada2799bdb21845dad8e0e80ec4c02c89eb0a65f5f7f2b64a9d2f104ff9912c1a, y: 0x0c99a7e666f2e9bd896335d5ea1cd0d696fcc1fcc2658dc666f97f238a6ad6cb07997380d33e28beffb74262751b651011892c5548e7c5b9ed9d6e75d2507ff3285d8c4d9ac82b91766ae09f185bd4824f95abef13b87d3d96ed05635d7936b6 })
    // [α^3]_2
    uint256 internal constant ALPHA_POWER3_X0_PART1 = 0x0000000000000000000000000000000003f4debb62e445a8d577dfcb3b9e9e6f;
    uint256 internal constant ALPHA_POWER3_X0_PART2 = 0xbfeff7390c23dae3c84bbe70394c5d8c8bfcd81f39ab65db1647ac9e7905a830;
    uint256 internal constant ALPHA_POWER3_X1_PART1 = 0x00000000000000000000000000000000048e5721d748709bdb68b01af622428a;
    uint256 internal constant ALPHA_POWER3_X1_PART2 = 0xda2799bdb21845dad8e0e80ec4c02c89eb0a65f5f7f2b64a9d2f104ff9912c1a;
    uint256 internal constant ALPHA_POWER3_Y0_PART1 = 0x000000000000000000000000000000000c99a7e666f2e9bd896335d5ea1cd0d6;
    uint256 internal constant ALPHA_POWER3_Y0_PART2 = 0x96fcc1fcc2658dc666f97f238a6ad6cb07997380d33e28beffb74262751b6510;
    uint256 internal constant ALPHA_POWER3_Y1_PART1 = 0x0000000000000000000000000000000011892c5548e7c5b9ed9d6e75d2507ff3;
    uint256 internal constant ALPHA_POWER3_Y1_PART2 = 0x285d8c4d9ac82b91766ae09f185bd4824f95abef13b87d3d96ed05635d7936b6;

    //alpha4: G2serde(Affine { x: 0x119487452ff2249b913d3615596b23ed798963dce3e84bb1cda6d8275420d78d6b8c689444b44d6abf94336be9344f050fd4fedaf2dea68d920f1de7dd6136c094d9e733600996a597cd54aa910474408470624188e655f7f7fd28e490d561d8, y: 0x036d8893301ebf86f558727a258d0c01e274a405033f63d35a80b7547f9f893ff9502295e54dae44f0f40052d89c93f615774c7ad74887b825aa76fbc677f95caaf2fc055bc4cf92385d115876a2032e71455bcbc47323cfa19b1b0f44a681dc })
    // [α^4]_2
    uint256 internal constant ALPHA_POWER4_X0_PART1 = 0x00000000000000000000000000000000119487452ff2249b913d3615596b23ed;
    uint256 internal constant ALPHA_POWER4_X0_PART2 = 0x798963dce3e84bb1cda6d8275420d78d6b8c689444b44d6abf94336be9344f05;
    uint256 internal constant ALPHA_POWER4_X1_PART1 = 0x000000000000000000000000000000000fd4fedaf2dea68d920f1de7dd6136c0;
    uint256 internal constant ALPHA_POWER4_X1_PART2 = 0x94d9e733600996a597cd54aa910474408470624188e655f7f7fd28e490d561d8;
    uint256 internal constant ALPHA_POWER4_Y0_PART1 = 0x00000000000000000000000000000000036d8893301ebf86f558727a258d0c01;
    uint256 internal constant ALPHA_POWER4_Y0_PART2 = 0xe274a405033f63d35a80b7547f9f893ff9502295e54dae44f0f40052d89c93f6;
    uint256 internal constant ALPHA_POWER4_Y1_PART1 = 0x0000000000000000000000000000000015774c7ad74887b825aa76fbc677f95c;
    uint256 internal constant ALPHA_POWER4_Y1_PART2 = 0xaaf2fc055bc4cf92385d115876a2032e71455bcbc47323cfa19b1b0f44a681dc;

    //-gamma: G2serde(Affine { x: 0x0c5f05ae1cd7c8c9d23904a90041ba698baf0a264bfd553d2c4f9b51ac51795839aef12df95d82ca94bb88b705ac9c6518356bdcacde783dd402ae3b1b7004e365385d828b938721c6e17ecff44403ceeed486592da4e2acb6ad1a99d1ac7a10, y: 0x02c8345a6ed2c39c85d0060afda056f4afd58411c2f9bd04796de3d47fcf2437001ebafd8c378514f7bfc58d597bbdaa17227dbdfedcb0e7bab68b1a59ae7265b4e308f8c0343efe071a972e1c7eb3a6ee204a485782bcbc19d04ef85afc35ba })
    // -[γ]_2 (negated for pairing)
    uint256 internal constant GAMMA_X0_PART1 = 0x000000000000000000000000000000000c5f05ae1cd7c8c9d23904a90041ba69;
    uint256 internal constant GAMMA_X0_PART2 = 0x8baf0a264bfd553d2c4f9b51ac51795839aef12df95d82ca94bb88b705ac9c65;
    uint256 internal constant GAMMA_X1_PART1 = 0x0000000000000000000000000000000018356bdcacde783dd402ae3b1b7004e3;
    uint256 internal constant GAMMA_X1_PART2 = 0x65385d828b938721c6e17ecff44403ceeed486592da4e2acb6ad1a99d1ac7a10;
    uint256 internal constant GAMMA_Y0_PART1 = 0x0000000000000000000000000000000002c8345a6ed2c39c85d0060afda056f4;
    uint256 internal constant GAMMA_Y0_PART2 = 0xafd58411c2f9bd04796de3d47fcf2437001ebafd8c378514f7bfc58d597bbdaa;
    uint256 internal constant GAMMA_Y1_PART1 = 0x0000000000000000000000000000000017227dbdfedcb0e7bab68b1a59ae7265;
    uint256 internal constant GAMMA_Y1_PART2 = 0xb4e308f8c0343efe071a972e1c7eb3a6ee204a485782bcbc19d04ef85afc35ba;

    //-eta: G2serde(Affine { x: 0x0dee20e8a1a4601b8b8498881220ca31036ee005b261f0cda1a47cd364094ac493a9446f69c00c18b85920798b7189790d952a8d8d2e7ab7774f04402897938d621ea0baf138e19617c320a2ec5de9d7694efef008994bc7a1b9f96939e38141, y: 0x008fe985823f536253d44624957d6cb56688c976fb9500a5de0f60e5b0ea13ded0f9b52bea37878fab734649ddc9416014584ce9324f72a304457fcd578a051a906515cd3d07ad3c146e9c4fceb44599219770bd16033d3e328cdfe9ba0040f4 })
    // -[η]_2 (negated for pairing)
    uint256 internal constant ETA_X0_PART1 = 0x000000000000000000000000000000000dee20e8a1a4601b8b8498881220ca31;
    uint256 internal constant ETA_X0_PART2 = 0x036ee005b261f0cda1a47cd364094ac493a9446f69c00c18b85920798b718979;
    uint256 internal constant ETA_X1_PART1 = 0x000000000000000000000000000000000d952a8d8d2e7ab7774f04402897938d;
    uint256 internal constant ETA_X1_PART2 = 0x621ea0baf138e19617c320a2ec5de9d7694efef008994bc7a1b9f96939e38141;
    uint256 internal constant ETA_Y0_PART1 = 0x00000000000000000000000000000000008fe985823f536253d44624957d6cb5;
    uint256 internal constant ETA_Y0_PART2 = 0x6688c976fb9500a5de0f60e5b0ea13ded0f9b52bea37878fab734649ddc94160;
    uint256 internal constant ETA_Y1_PART1 = 0x0000000000000000000000000000000014584ce9324f72a304457fcd578a051a;
    uint256 internal constant ETA_Y1_PART2 = 0x906515cd3d07ad3c146e9c4fceb44599219770bd16033d3e328cdfe9ba0040f4;

    //-delta: G2serde(Affine { x: 0x0d82e8b936233a9bfaf7587777b2ae7e2daa56831d2105076d0140015a9a299a42656cfa6149dc45246c121a37f05ffe04718ed40c6f593d1bdd16b161bd662fe33f1d39c3eab8548a90e0b8d15b2f68fcc73b63694e46f773c101ce369e57f6, y: 0x0ced763d46e2c7a1b36e7906825b663f16b6ee1eb58e77f918d2476a2afe5481b95c9fbfe525a77ece5004631ae82f9304a088624a997f337758547f065202f0900c0af7e6dedb86f4e4ce228d6e36e855f7a22a6a026478290b35b12161d339 })
    // -[δ]_2 (negated for pairing)
    uint256 internal constant DELTA_X0_PART1 = 0x000000000000000000000000000000000d82e8b936233a9bfaf7587777b2ae7e;
    uint256 internal constant DELTA_X0_PART2 = 0x2daa56831d2105076d0140015a9a299a42656cfa6149dc45246c121a37f05ffe;
    uint256 internal constant DELTA_X1_PART1 = 0x0000000000000000000000000000000004718ed40c6f593d1bdd16b161bd662f;
    uint256 internal constant DELTA_X1_PART2 = 0xe33f1d39c3eab8548a90e0b8d15b2f68fcc73b63694e46f773c101ce369e57f6;
    uint256 internal constant DELTA_Y0_PART1 = 0x000000000000000000000000000000000ced763d46e2c7a1b36e7906825b663f;
    uint256 internal constant DELTA_Y0_PART2 = 0x16b6ee1eb58e77f918d2476a2afe5481b95c9fbfe525a77ece5004631ae82f93;
    uint256 internal constant DELTA_Y1_PART1 = 0x0000000000000000000000000000000004a088624a997f337758547f065202f0;
    uint256 internal constant DELTA_Y1_PART2 = 0x900c0af7e6dedb86f4e4ce228d6e36e855f7a22a6a026478290b35b12161d339;

    //-x: G2serde(Affine { x: 0x05fc26da747c6cfef0305b496594b460e39e12dca4aebacb2d4bb6d2c4b02b2c50fe7ffe6f33940434a15a9425aa82ed0494bd39f21522f3fe14c8f9283e3fa1e05e39e804bb1881ef4529958798c9b68126138e3594797bc2f7042824b7d97e, y: 0x08eaf65586dba5935dc015901bb1886da38a7d861650dd21e1b918c775febd3c131452d73427cfeed0beab1205dec7cb0c009c1a9c287fd758a165c3579c823561d961f744e6c8064b2d1fdd8c209905eda4d5f5179721d57d87dd78f30f07bf })
    // -[x]_2 (negated for pairing)
    uint256 internal constant X_X0_PART1 = 0x0000000000000000000000000000000005fc26da747c6cfef0305b496594b460;
    uint256 internal constant X_X0_PART2 = 0xe39e12dca4aebacb2d4bb6d2c4b02b2c50fe7ffe6f33940434a15a9425aa82ed;
    uint256 internal constant X_X1_PART1 = 0x000000000000000000000000000000000494bd39f21522f3fe14c8f9283e3fa1;
    uint256 internal constant X_X1_PART2 = 0xe05e39e804bb1881ef4529958798c9b68126138e3594797bc2f7042824b7d97e;
    uint256 internal constant X_Y0_PART1 = 0x0000000000000000000000000000000008eaf65586dba5935dc015901bb1886d;
    uint256 internal constant X_Y0_PART2 = 0xa38a7d861650dd21e1b918c775febd3c131452d73427cfeed0beab1205dec7cb;
    uint256 internal constant X_Y1_PART1 = 0x000000000000000000000000000000000c009c1a9c287fd758a165c3579c8235;
    uint256 internal constant X_Y1_PART2 = 0x61d961f744e6c8064b2d1fdd8c209905eda4d5f5179721d57d87dd78f30f07bf;

    //-y: G2serde(Affine { x: 0x0de2cd58780b23995a0e7795b1bde089da3ce45ff2cbce991549908da59ec96266cc2f9654c1b266a658997482afb0e10366edab3105b9b73a7730d96163c2c9e90109fc5ab19667422a2b9487c0be72dd9dd43d36956c324fcdcf53675a9f80, y: 0x141fa81ff24c54735cc358459366792096241a20e596a6e4ed95f8b8b149c7d20aeff35306317d6f8d18caf9953eebba14379f9fd21f1e8b838e6d58334313082e99282b71132b41f1e4c97dcccd725b09968dda8f9e56c24bddd4412e61299e })
    // -[y]_2 (negated for pairing)
    uint256 internal constant Y_X0_PART1 = 0x000000000000000000000000000000000de2cd58780b23995a0e7795b1bde089;
    uint256 internal constant Y_X0_PART2 = 0xda3ce45ff2cbce991549908da59ec96266cc2f9654c1b266a658997482afb0e1;
    uint256 internal constant Y_X1_PART1 = 0x000000000000000000000000000000000366edab3105b9b73a7730d96163c2c9;
    uint256 internal constant Y_X1_PART2 = 0xe90109fc5ab19667422a2b9487c0be72dd9dd43d36956c324fcdcf53675a9f80;
    uint256 internal constant Y_Y0_PART1 = 0x00000000000000000000000000000000141fa81ff24c54735cc3584593667920;
    uint256 internal constant Y_Y0_PART2 = 0x96241a20e596a6e4ed95f8b8b149c7d20aeff35306317d6f8d18caf9953eebba;
    uint256 internal constant Y_Y1_PART1 = 0x0000000000000000000000000000000014379f9fd21f1e8b838e6d5833431308;
    uint256 internal constant Y_Y1_PART2 = 0x2e99282b71132b41f1e4c97dcccd725b09968dda8f9e56c24bddd4412e61299e;

    /// @notice Load verification keys to memory in runtime.
    /// @dev The constants are loaded into memory in a specific layout declared in the constants starting from
    /// `VK_` prefix.
    /// NOTE: Function may corrupt the memory state if some memory was used before this function was called.
    function _loadVerificationKey() internal pure virtual {
        assembly {
            /*
            "lagrange_KL": {
                "x": "0x03689a8e363b698896c0a973e3c471ced0b93696e2366fb2cf69ae4c9094b5e9991b069814ace3702ed81ff4d5e1d1cb",
                "y": "0x0da7bd666ee533222c3d2c2542188d1c16ebaf4ab4c1fd8258bb2fef5e8dfb97bc8a9527bc325ef3ea3466c9be9d2809"
            }
            */
            // preproccessed KL commitment vk
            mstore(VK_POLY_KXLX_X_PART1, 0x0000000000000000000000000000000003689a8e363b698896c0a973e3c471ce)
            mstore(VK_POLY_KXLX_X_PART2, 0xd0b93696e2366fb2cf69ae4c9094b5e9991b069814ace3702ed81ff4d5e1d1cb)
            mstore(VK_POLY_KXLX_Y_PART1, 0x000000000000000000000000000000000da7bd666ee533222c3d2c2542188d1c)
            mstore(VK_POLY_KXLX_Y_PART2, 0x16ebaf4ab4c1fd8258bb2fef5e8dfb97bc8a9527bc325ef3ea3466c9be9d2809)

            /*
            "G": {
                "x": "0x0b001b4cc05fa01578be7d4e821d6ff58f2a05c584fba3cb31a37942dece65eadec9a878add2282f7c2513abb8d4ab05",
                "y": "0x15e237775397ed22eef43dd36cdca277c9cf6fa7e4ffff0a5bb4b20a82392caacf0f63fb6cdb02bccf2f5af14970d6b9"
            },
            */
            // [1]_1 (Generator/Identity point)
            mstore(VK_IDENTITY_X_PART1, 0x000000000000000000000000000000000b001b4cc05fa01578be7d4e821d6ff5)
            mstore(VK_IDENTITY_X_PART2, 0x8f2a05c584fba3cb31a37942dece65eadec9a878add2282f7c2513abb8d4ab05)
            mstore(VK_IDENTITY_Y_PART1, 0x0000000000000000000000000000000015e237775397ed22eef43dd36cdca277)
            mstore(VK_IDENTITY_Y_PART2, 0xc9cf6fa7e4ffff0a5bb4b20a82392caacf0f63fb6cdb02bccf2f5af14970d6b9)

            /*
            "x": {
                "x": "0x0d45aca9cf6986877b859616c9613dfe38633f32c81a5a5e426f37beb4f1f9a8db94bcb17673c014031ed6f80406ae12",
                "y": "0x014de0221674a94bd5e60383f1f262d100c79178775b99480ec1a267fb28c905389357c2c111b94becf8676365f64133"
            },
            */
            // [x]_1 (Polynomial evaluation point)
            mstore(VK_POLY_X_X_PART1, 0x000000000000000000000000000000000d45aca9cf6986877b859616c9613dfe)
            mstore(VK_POLY_X_X_PART2, 0x38633f32c81a5a5e426f37beb4f1f9a8db94bcb17673c014031ed6f80406ae12)
            mstore(VK_POLY_X_Y_PART1, 0x00000000000000000000000000000000014de0221674a94bd5e60383f1f262d1)
            mstore(VK_POLY_X_Y_PART2, 0x00c79178775b99480ec1a267fb28c905389357c2c111b94becf8676365f64133)

            /*
            "y": {
                "x": "0x09cf106b4240325df41d6a76331883cbe61a678d7d877bf670446001be74d27580424e05a37af26bb85f99b380758888",
                "y": "0x0889c802a90694c68dfbcf207205778a7493cda2cbb6f9fb0b5ad39dbeef2fac91d847cc01d6040164ef30d840395af0"
            }
            */
            // [y]_1 (Polynomial evaluation point)
            mstore(VK_POLY_Y_X_PART1, 0x0000000000000000000000000000000009cf106b4240325df41d6a76331883cb)
            mstore(VK_POLY_Y_X_PART2, 0xe61a678d7d877bf670446001be74d27580424e05a37af26bb85f99b380758888)
            mstore(VK_POLY_Y_Y_PART1, 0x000000000000000000000000000000000889c802a90694c68dfbcf207205778a)
            mstore(VK_POLY_Y_Y_PART2, 0x7493cda2cbb6f9fb0b5ad39dbeef2fac91d847cc01d6040164ef30d840395af0)
        }
    }

    function verify(
        uint128[] calldata, //_proof part1 (16 bytes)
        uint256[] calldata, // _proof part2 (32 bytes)
        uint128[] calldata, // _preprocessedPart1 (16 bytes)
        uint256[] calldata, // _preprocessedPart2 (32 bytes)
        uint256[] calldata, // publicInputs (used for computing A_pub)
        uint256 // smax
    ) public view virtual returns (bool final_result) {
        // No memory was accessed yet, so keys can be loaded into the right place and not corrupt any other memory.
        _loadVerificationKey();

        // Beginning of the big inline assembly block that makes all the verification work.
        // Note: We use the custom memory layout, so the return value should be returned from the assembly, not
        // Solidity code.
        assembly {
            /*//////////////////////////////////////////////////////////////
                                        Utils
            //////////////////////////////////////////////////////////////*/

            /// @dev Reverts execution with a provided revert reason.
            /// @param len The byte length of the error message string, which is expected to be no more than 32.
            /// @param reason The 1-word revert reason string, encoded in ASCII.
            function revertWithMessage(len, reason) {
                // "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)")))
                mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)
                // Data offset
                mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)
                // Length of revert string
                mstore(0x24, len)
                // Revert reason
                mstore(0x44, reason)
                // Revert
                revert(0x00, 0x64)
            }

            /// @dev Performs modular exponentiation using the formula (value ^ power) mod R_MOD.
            function modexp(value, power) -> res {
                mstore(0x00, 0x20)
                mstore(0x20, 0x20)
                mstore(0x40, 0x20)
                mstore(0x60, value)
                mstore(0x80, power)
                mstore(0xa0, R_MOD)
                if iszero(staticcall(gas(), 5, 0, 0xc0, 0x00, 0x20)) {
                    revertWithMessage(24, "modexp precompile failed")
                }
                res := mload(0x00)
            }

            /// @dev Performs a G1 point multiplication operation and stores the result in a given memory destination.
            function g1pointMulIntoDest(point, s, dest) {
                mstore(0x00, mload(point))
                mstore(0x20, mload(add(point, 0x20)))
                mstore(0x40, mload(add(point, 0x40)))
                mstore(0x60, mload(add(point, 0x60)))
                mstore(0x80, s)
                // BLS12-381 G1MSM at address 0x0c
                if iszero(staticcall(gas(), 0x0c, 0, 0xa0, dest, 0x80)) {
                    revertWithMessage(30, "g1pointMulIntoDest: G1MSM failed")
                }
            }

            /// @dev Performs a G1 point addition operation and stores the result in a given memory destination.
            function g1pointAddIntoDest(p1, p2, dest) {
                mstore(0x00, mload(p1))
                mstore(0x20, mload(add(p1, 0x20)))
                mstore(0x40, mload(add(p1, 0x40)))
                mstore(0x60, mload(add(p1, 0x60)))
                mstore(0x80, mload(p2))
                mstore(0xa0, mload(add(p2, 0x20)))
                mstore(0xc0, mload(add(p2, 0x40)))
                mstore(0xe0, mload(add(p2, 0x60)))
                //  BLS12-381 G1ADDat address 0x0b
                if iszero(staticcall(gas(), 0x0b, 0x00, 0x100, dest, 0x80)) {
                    revertWithMessage(30, "g1pointAddIntoDest: G1ADD failed")
                }
            }

            /// @dev Performs a G1 point multiplication and addition operations and stores the result in a given memory destination.
            function g1pointMulAndAddIntoDest(point, s, dest) {
                mstore(0x00, mload(point))
                mstore(0x20, mload(add(point, 0x20)))
                mstore(0x40, mload(add(point, 0x40)))
                mstore(0x60, mload(add(point, 0x60)))
                mstore(0x80, s)
                let success := staticcall(gas(), 0x0c, 0, 0xa0, 0, 0x80)

                mstore(0x80, mload(dest))
                mstore(0xa0, mload(add(dest, 0x20)))
                mstore(0xc0, mload(add(dest, 0x40)))
                mstore(0xe0, mload(add(dest, 0x60)))
                success := and(success, staticcall(gas(), 0x0b, 0x00, 0x100, dest, 0x80))

                if iszero(success) { revertWithMessage(22, "g1pointMulAndAddIntoDest") }
            }

            /// @dev Performs a point subtraction operation and updates the first point with the result.
            function g1pointSubAssign(p1, p2) {
                // We'll use the fact that for BLS12-381 with 48-byte coordinates,
                // the precompile expects the full 384-bit representation

                // Copy p1 to memory
                mstore(0x00, mload(p1))
                mstore(0x20, mload(add(p1, 0x20)))
                mstore(0x40, mload(add(p1, 0x40)))
                mstore(0x60, mload(add(p1, 0x60)))

                // Copy p2's x-coordinate
                mstore(0x80, mload(p2))
                mstore(0xa0, mload(add(p2, 0x20)))

                // For the y-coordinate, we need to negate it
                // In BLS12-381, -y = q - y where q is the field modulus
                let y_low := mload(add(p2, 0x60))
                let y_high := mload(add(p2, 0x40))

                // Perform q - y
                let neg_y_low, neg_y_high

                // Since we're working with 384-bit numbers split into two 256-bit parts,
                // and the high 128 bits of the high part are always zero for valid field elements
                let borrow := 0

                // Subtract low part
                switch lt(Q_MOD_PART2, y_low)
                case 1 {
                    // Need to borrow from high part
                    neg_y_low := sub(Q_MOD_PART2, y_low)
                    neg_y_low := add(neg_y_low, not(0)) // Add 2^256
                    neg_y_low := add(neg_y_low, 1)
                    borrow := 1
                }
                default { neg_y_low := sub(Q_MOD_PART2, y_low) }

                // Subtract high part with borrow
                neg_y_high := sub(sub(Q_MOD_PART1, y_high), borrow)

                mstore(0xc0, neg_y_high)
                mstore(0xe0, neg_y_low)

                // Perform the addition
                if iszero(staticcall(gas(), 0x0b, 0x00, 0x100, p1, 0x80)) {
                    revertWithMessage(28, "pointSubAssign: G1ADD failed")
                }
            }

            /// @dev Performs a point subtraction operation and updates dest with the result.
            function g1pointSubIntoDest(p1, p2, dest) {
                // We'll use the fact that for BLS12-381 with 48-byte coordinates,
                // the precompile expects the full 384-bit representation

                // Copy p1 to memory
                mstore(0x00, mload(p1))
                mstore(0x20, mload(add(p1, 0x20)))
                mstore(0x40, mload(add(p1, 0x40)))
                mstore(0x60, mload(add(p1, 0x60)))

                // Copy p2's x-coordinate
                mstore(0x80, mload(p2))
                mstore(0xa0, mload(add(p2, 0x20)))

                // For the y-coordinate, we need to negate it
                // In BLS12-381, -y = q - y where q is the field modulus
                let y_low := mload(add(p2, 0x60))
                let y_high := mload(add(p2, 0x40))

                // Perform q - y
                let neg_y_low, neg_y_high

                // Since we're working with 384-bit numbers split into two 256-bit parts,
                // and the high 128 bits of the high part are always zero for valid field elements
                let borrow := 0

                // Subtract low part
                switch lt(Q_MOD_PART2, y_low)
                case 1 {
                    // Need to borrow from high part
                    neg_y_low := sub(Q_MOD_PART2, y_low)
                    neg_y_low := add(neg_y_low, not(0)) // Add 2^256
                    neg_y_low := add(neg_y_low, 1)
                    borrow := 1
                }
                default { neg_y_low := sub(Q_MOD_PART2, y_low) }

                // Subtract high part with borrow
                neg_y_high := sub(sub(Q_MOD_PART1, y_high), borrow)

                mstore(0xc0, neg_y_high)
                mstore(0xe0, neg_y_low)

                // Perform the addition
                if iszero(staticcall(gas(), 0x0b, 0x00, 0x100, dest, 0x80)) {
                    revertWithMessage(28, "pointSubAssign: G1ADD failed")
                }
            }

            /*//////////////////////////////////////////////////////////////
                                        Transcript helpers
                //////////////////////////////////////////////////////////////*/

            /// @dev Updates the transcript state with a new challenge value.
            function updateTranscript(value) {
                mstore8(TRANSCRIPT_DST_BYTE_SLOT, 0x00)
                mstore(TRANSCRIPT_CHALLENGE_SLOT, value)
                let newState0 := keccak256(TRANSCRIPT_BEGIN_SLOT, 0x64)
                mstore8(TRANSCRIPT_DST_BYTE_SLOT, 0x01)
                let newState1 := keccak256(TRANSCRIPT_BEGIN_SLOT, 0x64)
                mstore(TRANSCRIPT_STATE_1_SLOT, newState1)
                mstore(TRANSCRIPT_STATE_0_SLOT, newState0)
            }

            /// @dev Retrieves a transcript challenge.
            function getTranscriptChallenge(numberOfChallenge) -> challenge {
                mstore8(TRANSCRIPT_DST_BYTE_SLOT, 0x02)
                mstore(TRANSCRIPT_CHALLENGE_SLOT, shl(224, numberOfChallenge))
                challenge := and(keccak256(TRANSCRIPT_BEGIN_SLOT, 0x48), FR_MASK)
            }

            /*//////////////////////////////////////////////////////////////
                                        1. Load Proof
                //////////////////////////////////////////////////////////////*/

            function loadProof() {
                let offset := calldataload(0x04)
                let offset2 := calldataload(0x24)
                let offset3 := calldataload(0x44)
                let offset4 := calldataload(0x64)
                let part1LengthInWords := calldataload(add(offset, 0x04))
                let part2LengthInWords := calldataload(add(offset2, 0x04))
                let isValid := and(eq(part1LengthInWords, 38), eq(part2LengthInWords, 42))

                // revert if the length of the proof is not valid
                if iszero(isValid) { revertWithMessage(27, "loadProof: Proof is invalid") }

                // S PERMUTATION POLYNOMIALS
                {
                    let x0 := calldataload(add(offset3, 0x024))
                    let y0 := calldataload(add(offset3, 0x044))
                    let x1 := calldataload(add(offset3, 0x064))
                    let y1 := calldataload(add(offset3, 0x084))
                    mstore(PUBLIC_INPUTS_S_0_X_SLOT_PART1, x0)
                    mstore(PUBLIC_INPUTS_S_0_Y_SLOT_PART1, y0)
                    mstore(PUBLIC_INPUTS_S_1_X_SLOT_PART1, x1)
                    mstore(PUBLIC_INPUTS_S_1_Y_SLOT_PART1, y1)
                    x0 := calldataload(add(offset4, 0x024))
                    y0 := calldataload(add(offset4, 0x044))
                    x1 := calldataload(add(offset4, 0x064))
                    y1 := calldataload(add(offset4, 0x084))
                    mstore(PUBLIC_INPUTS_S_0_X_SLOT_PART2, x0)
                    mstore(PUBLIC_INPUTS_S_0_Y_SLOT_PART2, y0)
                    mstore(PUBLIC_INPUTS_S_1_X_SLOT_PART2, x1)
                    mstore(PUBLIC_INPUTS_S_1_Y_SLOT_PART2, y1)
                }
                // PROOF U, V & W
                {
                    let x0 := calldataload(add(offset, 0x024))
                    let y0 := calldataload(add(offset, 0x044))
                    let x1 := calldataload(add(offset, 0x064))
                    let y1 := calldataload(add(offset, 0x084))
                    let x2 := calldataload(add(offset, 0x0a4))
                    let y2 := calldataload(add(offset, 0x0c4))
                    mstore(PROOF_POLY_U_X_SLOT_PART1, x0)
                    mstore(PROOF_POLY_U_Y_SLOT_PART1, y0)
                    mstore(PROOF_POLY_V_X_SLOT_PART1, x1)
                    mstore(PROOF_POLY_V_Y_SLOT_PART1, y1)
                    mstore(PROOF_POLY_W_X_SLOT_PART1, x2)
                    mstore(PROOF_POLY_W_Y_SLOT_PART1, y2)
                    x0 := calldataload(add(offset2, 0x024))
                    y0 := calldataload(add(offset2, 0x044))
                    x1 := calldataload(add(offset2, 0x064))
                    y1 := calldataload(add(offset2, 0x084))
                    x2 := calldataload(add(offset2, 0x0a4))
                    y2 := calldataload(add(offset2, 0x0c4))
                    mstore(PROOF_POLY_U_X_SLOT_PART2, x0)
                    mstore(PROOF_POLY_U_Y_SLOT_PART2, y0)
                    mstore(PROOF_POLY_V_X_SLOT_PART2, x1)
                    mstore(PROOF_POLY_V_Y_SLOT_PART2, y1)
                    mstore(PROOF_POLY_W_X_SLOT_PART2, x2)
                    mstore(PROOF_POLY_W_Y_SLOT_PART2, y2)
                }
                // PROOF O_MID & O_PRV
                {
                    let x0 := calldataload(add(offset, 0x0e4))
                    let y0 := calldataload(add(offset, 0x104))
                    let x1 := calldataload(add(offset, 0x124))
                    let y1 := calldataload(add(offset, 0x144))
                    mstore(PROOF_POLY_OMID_X_SLOT_PART1, x0)
                    mstore(PROOF_POLY_OMID_Y_SLOT_PART1, y0)
                    mstore(PROOF_POLY_OPRV_X_SLOT_PART1, x1)
                    mstore(PROOF_POLY_OPRV_Y_SLOT_PART1, y1)
                    x0 := calldataload(add(offset2, 0x0e4))
                    y0 := calldataload(add(offset2, 0x104))
                    x1 := calldataload(add(offset2, 0x124))
                    y1 := calldataload(add(offset2, 0x144))
                    mstore(PROOF_POLY_OMID_X_SLOT_PART2, x0)
                    mstore(PROOF_POLY_OMID_Y_SLOT_PART2, y0)
                    mstore(PROOF_POLY_OPRV_X_SLOT_PART2, x1)
                    mstore(PROOF_POLY_OPRV_Y_SLOT_PART2, y1)
                }
                // PROOF Q_AX, Q_AY, Q_CX & Q_CY
                {
                    let x0 := calldataload(add(offset, 0x164))
                    let y0 := calldataload(add(offset, 0x184))
                    let x1 := calldataload(add(offset, 0x1a4))
                    let y1 := calldataload(add(offset, 0x1c4))
                    let x2 := calldataload(add(offset, 0x1e4))
                    let y2 := calldataload(add(offset, 0x204))
                    let x3 := calldataload(add(offset, 0x224))
                    let y3 := calldataload(add(offset, 0x244))
                    mstore(PROOF_POLY_QAX_X_SLOT_PART1, x0)
                    mstore(PROOF_POLY_QAX_Y_SLOT_PART1, y0)
                    mstore(PROOF_POLY_QAY_X_SLOT_PART1, x1)
                    mstore(PROOF_POLY_QAY_Y_SLOT_PART1, y1)
                    mstore(PROOF_POLY_QCX_X_SLOT_PART1, x2)
                    mstore(PROOF_POLY_QCX_Y_SLOT_PART1, y2)
                    mstore(PROOF_POLY_QCY_X_SLOT_PART1, x3)
                    mstore(PROOF_POLY_QCY_Y_SLOT_PART1, y3)
                    x0 := calldataload(add(offset2, 0x164))
                    y0 := calldataload(add(offset2, 0x184))
                    x1 := calldataload(add(offset2, 0x1a4))
                    y1 := calldataload(add(offset2, 0x1c4))
                    x2 := calldataload(add(offset2, 0x1e4))
                    y2 := calldataload(add(offset2, 0x204))
                    x3 := calldataload(add(offset2, 0x224))
                    y3 := calldataload(add(offset2, 0x244))
                    mstore(PROOF_POLY_QAX_X_SLOT_PART2, x0)
                    mstore(PROOF_POLY_QAX_Y_SLOT_PART2, y0)
                    mstore(PROOF_POLY_QAY_X_SLOT_PART2, x1)
                    mstore(PROOF_POLY_QAY_Y_SLOT_PART2, y1)
                    mstore(PROOF_POLY_QCX_X_SLOT_PART2, x2)
                    mstore(PROOF_POLY_QCX_Y_SLOT_PART2, y2)
                    mstore(PROOF_POLY_QCY_X_SLOT_PART2, x3)
                    mstore(PROOF_POLY_QCY_Y_SLOT_PART2, y3)
                }
                // PROOF Π_{χ}, Π_{ζ}
                {
                    let x0 := calldataload(add(offset, 0x264))
                    let y0 := calldataload(add(offset, 0x284))
                    let x1 := calldataload(add(offset, 0x2a4))
                    let y1 := calldataload(add(offset, 0x2c4))
                    mstore(PROOF_POLY_PI_CHI_X_SLOT_PART1, x0)
                    mstore(PROOF_POLY_PI_CHI_Y_SLOT_PART1, y0)
                    mstore(PROOF_POLY_PI_ZETA_X_SLOT_PART1, x1)
                    mstore(PROOF_POLY_PI_ZETA_Y_SLOT_PART1, y1)
                    x0 := calldataload(add(offset2, 0x264))
                    y0 := calldataload(add(offset2, 0x284))
                    x1 := calldataload(add(offset2, 0x2a4))
                    y1 := calldataload(add(offset2, 0x2c4))
                    mstore(PROOF_POLY_PI_CHI_X_SLOT_PART2, x0)
                    mstore(PROOF_POLY_PI_CHI_Y_SLOT_PART2, y0)
                    mstore(PROOF_POLY_PI_ZETA_X_SLOT_PART2, x1)
                    mstore(PROOF_POLY_PI_ZETA_Y_SLOT_PART2, y1)
                }
                // PROOF B & R
                {
                    let x0 := calldataload(add(offset, 0x2e4))
                    let y0 := calldataload(add(offset, 0x304))
                    let x1 := calldataload(add(offset, 0x324))
                    let y1 := calldataload(add(offset, 0x344))
                    mstore(PROOF_POLY_B_X_SLOT_PART1, x0)
                    mstore(PROOF_POLY_B_Y_SLOT_PART1, y0)
                    mstore(PROOF_POLY_R_X_SLOT_PART1, x1)
                    mstore(PROOF_POLY_R_Y_SLOT_PART1, y1)
                    x0 := calldataload(add(offset2, 0x2e4))
                    y0 := calldataload(add(offset2, 0x304))
                    x1 := calldataload(add(offset2, 0x324))
                    y1 := calldataload(add(offset2, 0x344))
                    mstore(PROOF_POLY_B_X_SLOT_PART2, x0)
                    mstore(PROOF_POLY_B_Y_SLOT_PART2, y0)
                    mstore(PROOF_POLY_R_X_SLOT_PART2, x1)
                    mstore(PROOF_POLY_R_Y_SLOT_PART2, y1)
                }
                // PROOF M_ζ, M_χ, N_ζ & N_χ
                {
                    let x0 := calldataload(add(offset, 0x364))
                    let y0 := calldataload(add(offset, 0x384))
                    let x1 := calldataload(add(offset, 0x3a4))
                    let y1 := calldataload(add(offset, 0x3c4))
                    let x2 := calldataload(add(offset, 0x3e4))
                    let y2 := calldataload(add(offset, 0x404))
                    let x3 := calldataload(add(offset, 0x424))
                    let y3 := calldataload(add(offset, 0x444))
                    mstore(PROOF_POLY_M_ZETA_X_SLOT_PART1, x0)
                    mstore(PROOF_POLY_M_ZETA_Y_SLOT_PART1, y0)
                    mstore(PROOF_POLY_M_CHI_X_SLOT_PART1, x1)
                    mstore(PROOF_POLY_M_CHI_Y_SLOT_PART1, y1)
                    mstore(PROOF_POLY_N_ZETA_X_SLOT_PART1, x2)
                    mstore(PROOF_POLY_N_ZETA_Y_SLOT_PART1, y2)
                    mstore(PROOF_POLY_N_CHI_X_SLOT_PART1, x3)
                    mstore(PROOF_POLY_N_CHI_Y_SLOT_PART1, y3)
                    x0 := calldataload(add(offset2, 0x364))
                    y0 := calldataload(add(offset2, 0x384))
                    x1 := calldataload(add(offset2, 0x3a4))
                    y1 := calldataload(add(offset2, 0x3c4))
                    x2 := calldataload(add(offset2, 0x3e4))
                    y2 := calldataload(add(offset2, 0x404))
                    x3 := calldataload(add(offset2, 0x424))
                    y3 := calldataload(add(offset2, 0x444))
                    mstore(PROOF_POLY_M_ZETA_X_SLOT_PART2, x0)
                    mstore(PROOF_POLY_M_ZETA_Y_SLOT_PART2, y0)
                    mstore(PROOF_POLY_M_CHI_X_SLOT_PART2, x1)
                    mstore(PROOF_POLY_M_CHI_Y_SLOT_PART2, y1)
                    mstore(PROOF_POLY_N_ZETA_X_SLOT_PART2, x2)
                    mstore(PROOF_POLY_N_ZETA_Y_SLOT_PART2, y2)
                    mstore(PROOF_POLY_N_CHI_X_SLOT_PART2, x3)
                    mstore(PROOF_POLY_N_CHI_Y_SLOT_PART2, y3)
                }
                // PROOF O_PUB & A
                {
                    let x0 := calldataload(add(offset, 0x464))
                    let y0 := calldataload(add(offset, 0x484))
                    let x1 := calldataload(add(offset, 0x4a4))
                    let y1 := calldataload(add(offset, 0x4c4))
                    mstore(PROOF_POLY_OPUB_X_SLOT_PART1, x0)
                    mstore(PROOF_POLY_OPUB_Y_SLOT_PART1, y0)
                    mstore(PROOF_POLY_A_X_SLOT_PART1, x1)
                    mstore(PROOF_POLY_A_Y_SLOT_PART1, y1)
                    x0 := calldataload(add(offset2, 0x464))
                    y0 := calldataload(add(offset2, 0x484))
                    x1 := calldataload(add(offset2, 0x4a4))
                    y1 := calldataload(add(offset2, 0x4c4))
                    mstore(PROOF_POLY_OPUB_X_SLOT_PART2, x0)
                    mstore(PROOF_POLY_OPUB_Y_SLOT_PART2, y0)
                    mstore(PROOF_POLY_A_X_SLOT_PART2, x1)
                    mstore(PROOF_POLY_A_Y_SLOT_PART2, y1)
                }

                mstore(PROOF_R1XY_SLOT, mod(calldataload(add(offset2, 0x4e4)), R_MOD))
                mstore(PROOF_R2XY_SLOT, mod(calldataload(add(offset2, 0x504)), R_MOD))
                mstore(PROOF_R3XY_SLOT, mod(calldataload(add(offset2, 0x524)), R_MOD))
                mstore(PROOF_VXY_SLOT, mod(calldataload(add(offset2, 0x544)), R_MOD))

                // load smax
                let smax := calldataload(0xa4)
                let isValidSmax
                {
                    isValidSmax :=
                        or(
                            or(or(eq(smax, 64), eq(smax, 128)), or(eq(smax, 256), eq(smax, 512))),
                            or(eq(smax, 1024), eq(smax, 2048))
                        )
                    mstore(PARAM_SMAX, smax)
                }

                // Revert if smax is not valid
                if iszero(isValidSmax) { revertWithMessage(27, "loadProof: smax is invalid") }
            }

            /*//////////////////////////////////////////////////////////////
                                    2. Transcript initialization
                //////////////////////////////////////////////////////////////*/

            /// @notice Recomputes all challenges
            /// @dev The process is the following:
            /// Commit:   [U], [V], [W], [Q_AX], [Q_AY], [B]
            /// Get:      θ_0, θ_1, θ_2
            /// Commit:   [R]
            /// Get:      κ0
            /// Commit:   [Q_CX], [Q_CY]
            /// Get:      χ, ζ
         

Tags:
Factory|addr:0x0e929219887d4a6c2ee2dc36973f047f9d3b3097|verified:true|block:23517884|tx:0x02e82363afbd84b3e114d8901521f255745ddd3bd5e02ef0a73b2e23abd3c4e0|first_check:1759747841

Submitted on: 2025-10-06 12:50:43

Comments

Log in to comment.

No comments yet.