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: χ, ζ
Submitted on: 2025-10-06 12:50:43
Comments
Log in to comment.
No comments yet.