Skip to content

Instantly share code, notes, and snippets.

@leonardoalt
Created April 4, 2024 08:20
Show Gist options
  • Save leonardoalt/382603dec4da0425d073ffeed9356e7c to your computer and use it in GitHub Desktop.
Save leonardoalt/382603dec4da0425d073ffeed9356e7c to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Halo2Verifier {
uint256 internal constant PROOF_LEN_CPTR = 0x44;
uint256 internal constant PROOF_CPTR = 0x64;
uint256 internal constant NUM_INSTANCE_CPTR = 0x1304;
uint256 internal constant INSTANCE_CPTR = 0x1324;
uint256 internal constant FIRST_QUOTIENT_X_CPTR = 0x0764;
uint256 internal constant LAST_QUOTIENT_X_CPTR = 0x0864;
uint256 internal constant VK_MPTR = 0x0640;
uint256 internal constant VK_DIGEST_MPTR = 0x0640;
uint256 internal constant NUM_INSTANCES_MPTR = 0x0660;
uint256 internal constant K_MPTR = 0x0680;
uint256 internal constant N_INV_MPTR = 0x06a0;
uint256 internal constant OMEGA_MPTR = 0x06c0;
uint256 internal constant OMEGA_INV_MPTR = 0x06e0;
uint256 internal constant OMEGA_INV_TO_L_MPTR = 0x0700;
uint256 internal constant HAS_ACCUMULATOR_MPTR = 0x0720;
uint256 internal constant ACC_OFFSET_MPTR = 0x0740;
uint256 internal constant NUM_ACC_LIMBS_MPTR = 0x0760;
uint256 internal constant NUM_ACC_LIMB_BITS_MPTR = 0x0780;
uint256 internal constant G1_X_MPTR = 0x07a0;
uint256 internal constant G1_Y_MPTR = 0x07c0;
uint256 internal constant G2_X_1_MPTR = 0x07e0;
uint256 internal constant G2_X_2_MPTR = 0x0800;
uint256 internal constant G2_Y_1_MPTR = 0x0820;
uint256 internal constant G2_Y_2_MPTR = 0x0840;
uint256 internal constant NEG_S_G2_X_1_MPTR = 0x0860;
uint256 internal constant NEG_S_G2_X_2_MPTR = 0x0880;
uint256 internal constant NEG_S_G2_Y_1_MPTR = 0x08a0;
uint256 internal constant NEG_S_G2_Y_2_MPTR = 0x08c0;
uint256 internal constant CHALLENGE_MPTR = 0x1220;
uint256 internal constant THETA_MPTR = 0x1240;
uint256 internal constant BETA_MPTR = 0x1260;
uint256 internal constant GAMMA_MPTR = 0x1280;
uint256 internal constant Y_MPTR = 0x12a0;
uint256 internal constant X_MPTR = 0x12c0;
uint256 internal constant ZETA_MPTR = 0x12e0;
uint256 internal constant NU_MPTR = 0x1300;
uint256 internal constant MU_MPTR = 0x1320;
uint256 internal constant ACC_LHS_X_MPTR = 0x1340;
uint256 internal constant ACC_LHS_Y_MPTR = 0x1360;
uint256 internal constant ACC_RHS_X_MPTR = 0x1380;
uint256 internal constant ACC_RHS_Y_MPTR = 0x13a0;
uint256 internal constant X_N_MPTR = 0x13c0;
uint256 internal constant X_N_MINUS_1_INV_MPTR = 0x13e0;
uint256 internal constant L_LAST_MPTR = 0x1400;
uint256 internal constant L_BLIND_MPTR = 0x1420;
uint256 internal constant L_0_MPTR = 0x1440;
uint256 internal constant INSTANCE_EVAL_MPTR = 0x1460;
uint256 internal constant QUOTIENT_EVAL_MPTR = 0x1480;
uint256 internal constant QUOTIENT_X_MPTR = 0x14a0;
uint256 internal constant QUOTIENT_Y_MPTR = 0x14c0;
uint256 internal constant G1_SCALAR_MPTR = 0x14e0;
uint256 internal constant PAIRING_LHS_X_MPTR = 0x1500;
uint256 internal constant PAIRING_LHS_Y_MPTR = 0x1520;
uint256 internal constant PAIRING_RHS_X_MPTR = 0x1540;
uint256 internal constant PAIRING_RHS_Y_MPTR = 0x1560;
function verifyProof(
bytes calldata proof,
uint256[] calldata instances
) public returns (bool) {
assembly ("memory-safe") {
// Read EC point (x, y) at (proof_cptr, proof_cptr + 0x20),
// and check if the point is on affine plane,
// and store them in (hash_mptr, hash_mptr + 0x20).
// Return updated (success, proof_cptr, hash_mptr).
function read_ec_point(success, proof_cptr, hash_mptr, q) -> ret0, ret1, ret2 {
let x := calldataload(proof_cptr)
let y := calldataload(add(proof_cptr, 0x20))
ret0 := and(success, lt(x, q))
ret0 := and(ret0, lt(y, q))
ret0 := and(ret0, eq(mulmod(y, y, q), addmod(mulmod(x, mulmod(x, x, q), q), 3, q)))
mstore(hash_mptr, x)
mstore(add(hash_mptr, 0x20), y)
ret1 := add(proof_cptr, 0x40)
ret2 := add(hash_mptr, 0x40)
}
// Squeeze challenge by keccak256(memory[0..hash_mptr]),
// and store hash mod r as challenge in challenge_mptr,
// and push back hash in 0x00 as the first input for next squeeze.
// Return updated (challenge_mptr, hash_mptr).
function squeeze_challenge(challenge_mptr, hash_mptr, r) -> ret0, ret1 {
let hash := keccak256(0x00, hash_mptr)
mstore(challenge_mptr, mod(hash, r))
mstore(0x00, hash)
ret0 := add(challenge_mptr, 0x20)
ret1 := 0x20
}
// Squeeze challenge without absorbing new input from calldata,
// by putting an extra 0x01 in memory[0x20] and squeeze by keccak256(memory[0..21]),
// and store hash mod r as challenge in challenge_mptr,
// and push back hash in 0x00 as the first input for next squeeze.
// Return updated (challenge_mptr).
function squeeze_challenge_cont(challenge_mptr, r) -> ret {
mstore8(0x20, 0x01)
let hash := keccak256(0x00, 0x21)
mstore(challenge_mptr, mod(hash, r))
mstore(0x00, hash)
ret := add(challenge_mptr, 0x20)
}
// Batch invert values in memory[mptr_start..mptr_end] in place.
// Return updated (success).
function batch_invert(success, mptr_start, mptr_end, r) -> ret {
let gp_mptr := mptr_end
let gp := mload(mptr_start)
let mptr := add(mptr_start, 0x20)
for
{}
lt(mptr, sub(mptr_end, 0x20))
{}
{
gp := mulmod(gp, mload(mptr), r)
mstore(gp_mptr, gp)
mptr := add(mptr, 0x20)
gp_mptr := add(gp_mptr, 0x20)
}
gp := mulmod(gp, mload(mptr), r)
mstore(gp_mptr, 0x20)
mstore(add(gp_mptr, 0x20), 0x20)
mstore(add(gp_mptr, 0x40), 0x20)
mstore(add(gp_mptr, 0x60), gp)
mstore(add(gp_mptr, 0x80), sub(r, 2))
mstore(add(gp_mptr, 0xa0), r)
ret := and(success, staticcall(gas(), 0x05, gp_mptr, 0xc0, gp_mptr, 0x20))
let all_inv := mload(gp_mptr)
let first_mptr := mptr_start
let second_mptr := add(first_mptr, 0x20)
gp_mptr := sub(gp_mptr, 0x20)
for
{}
lt(second_mptr, mptr)
{}
{
let inv := mulmod(all_inv, mload(gp_mptr), r)
all_inv := mulmod(all_inv, mload(mptr), r)
mstore(mptr, inv)
mptr := sub(mptr, 0x20)
gp_mptr := sub(gp_mptr, 0x20)
}
let inv_first := mulmod(all_inv, mload(second_mptr), r)
let inv_second := mulmod(all_inv, mload(first_mptr), r)
mstore(first_mptr, inv_first)
mstore(second_mptr, inv_second)
}
// Add (x, y) into point at (0x00, 0x20).
// Return updated (success).
function ec_add_acc(success, x, y) -> ret {
mstore(0x40, x)
mstore(0x60, y)
ret := and(success, staticcall(gas(), 0x06, 0x00, 0x80, 0x00, 0x40))
}
// Scale point at (0x00, 0x20) by scalar.
function ec_mul_acc(success, scalar) -> ret {
mstore(0x40, scalar)
ret := and(success, staticcall(gas(), 0x07, 0x00, 0x60, 0x00, 0x40))
}
// Add (x, y) into point at (0x80, 0xa0).
// Return updated (success).
function ec_add_tmp(success, x, y) -> ret {
mstore(0xc0, x)
mstore(0xe0, y)
ret := and(success, staticcall(gas(), 0x06, 0x80, 0x80, 0x80, 0x40))
}
// Scale point at (0x80, 0xa0) by scalar.
// Return updated (success).
function ec_mul_tmp(success, scalar) -> ret {
mstore(0xc0, scalar)
ret := and(success, staticcall(gas(), 0x07, 0x80, 0x60, 0x80, 0x40))
}
// Perform pairing check.
// Return updated (success).
function ec_pairing(success, lhs_x, lhs_y, rhs_x, rhs_y) -> ret {
mstore(0x00, lhs_x)
mstore(0x20, lhs_y)
mstore(0x40, mload(G2_X_1_MPTR))
mstore(0x60, mload(G2_X_2_MPTR))
mstore(0x80, mload(G2_Y_1_MPTR))
mstore(0xa0, mload(G2_Y_2_MPTR))
mstore(0xc0, rhs_x)
mstore(0xe0, rhs_y)
mstore(0x100, mload(NEG_S_G2_X_1_MPTR))
mstore(0x120, mload(NEG_S_G2_X_2_MPTR))
mstore(0x140, mload(NEG_S_G2_Y_1_MPTR))
mstore(0x160, mload(NEG_S_G2_Y_2_MPTR))
ret := and(success, staticcall(gas(), 0x08, 0x00, 0x180, 0x00, 0x20))
ret := and(ret, mload(0x00))
}
// Modulus
let q := 21888242871839275222246405745257275088696311157297823662689037894645226208583 // BN254 base field
let r := 21888242871839275222246405745257275088548364400416034343698204186575808495617 // BN254 scalar field
// Initialize success as true
let success := true
{
// Load vk_digest and num_instances of vk into memory
mstore(0x0640, 0x0d4f9f3a3f3837aeafd839e7e9d304779d0d0ef390946e8534dc6eaddbc4a164) // vk_digest
mstore(0x0660, 0x0000000000000000000000000000000000000000000000000000000000000000) // num_instances
// Check valid length of proof
success := and(success, eq(0x12a0, calldataload(PROOF_LEN_CPTR)))
// Check valid length of instances
let num_instances := mload(NUM_INSTANCES_MPTR)
success := and(success, eq(num_instances, calldataload(NUM_INSTANCE_CPTR)))
// Absorb vk diegst
mstore(0x00, mload(VK_DIGEST_MPTR))
// Read instances and witness commitments and generate challenges
let hash_mptr := 0x20
let instance_cptr := INSTANCE_CPTR
for
{ let instance_cptr_end := add(instance_cptr, mul(0x20, num_instances)) }
lt(instance_cptr, instance_cptr_end)
{}
{
let instance := calldataload(instance_cptr)
success := and(success, lt(instance, r))
mstore(hash_mptr, instance)
instance_cptr := add(instance_cptr, 0x20)
hash_mptr := add(hash_mptr, 0x20)
}
let proof_cptr := PROOF_CPTR
let challenge_mptr := CHALLENGE_MPTR
// Phase 1
for
{ let proof_cptr_end := add(proof_cptr, 0x04c0) }
lt(proof_cptr, proof_cptr_end)
{}
{
success, proof_cptr, hash_mptr := read_ec_point(success, proof_cptr, hash_mptr, q)
}
challenge_mptr, hash_mptr := squeeze_challenge(challenge_mptr, hash_mptr, r)
challenge_mptr := squeeze_challenge_cont(challenge_mptr, r)
// Phase 2
for
{ let proof_cptr_end := add(proof_cptr, 0x80) }
lt(proof_cptr, proof_cptr_end)
{}
{
success, proof_cptr, hash_mptr := read_ec_point(success, proof_cptr, hash_mptr, q)
}
challenge_mptr, hash_mptr := squeeze_challenge(challenge_mptr, hash_mptr, r)
challenge_mptr := squeeze_challenge_cont(challenge_mptr, r)
// Phase 3
for
{ let proof_cptr_end := add(proof_cptr, 0x01c0) }
lt(proof_cptr, proof_cptr_end)
{}
{
success, proof_cptr, hash_mptr := read_ec_point(success, proof_cptr, hash_mptr, q)
}
challenge_mptr, hash_mptr := squeeze_challenge(challenge_mptr, hash_mptr, r)
// Phase 4
for
{ let proof_cptr_end := add(proof_cptr, 0x0140) }
lt(proof_cptr, proof_cptr_end)
{}
{
success, proof_cptr, hash_mptr := read_ec_point(success, proof_cptr, hash_mptr, q)
}
challenge_mptr, hash_mptr := squeeze_challenge(challenge_mptr, hash_mptr, r)
// Read evaluations
for
{ let proof_cptr_end := add(proof_cptr, 0x09e0) }
lt(proof_cptr, proof_cptr_end)
{}
{
let eval := calldataload(proof_cptr)
success := and(success, lt(eval, r))
mstore(hash_mptr, eval)
proof_cptr := add(proof_cptr, 0x20)
hash_mptr := add(hash_mptr, 0x20)
}
// Read batch opening proof and generate challenges
challenge_mptr, hash_mptr := squeeze_challenge(challenge_mptr, hash_mptr, r) // zeta
challenge_mptr := squeeze_challenge_cont(challenge_mptr, r) // nu
success, proof_cptr, hash_mptr := read_ec_point(success, proof_cptr, hash_mptr, q) // W
challenge_mptr, hash_mptr := squeeze_challenge(challenge_mptr, hash_mptr, r) // mu
success, proof_cptr, hash_mptr := read_ec_point(success, proof_cptr, hash_mptr, q) // W'
// Load full vk into memory
mstore(0x0640, 0x0d4f9f3a3f3837aeafd839e7e9d304779d0d0ef390946e8534dc6eaddbc4a164) // vk_digest
mstore(0x0660, 0x0000000000000000000000000000000000000000000000000000000000000000) // num_instances
mstore(0x0680, 0x0000000000000000000000000000000000000000000000000000000000000006) // k
mstore(0x06a0, 0x2fa2bd3915acd9a9116f049fa77b52fbb39318a757d28acefed26dbda0400001) // n_inv
mstore(0x06c0, 0x1c4c3a258629905ef6036a4037c3aa6ae18d1d2452d64bd2684cfa8ede70fdc7) // omega
mstore(0x06e0, 0x0a4cd1802e9062efb4f3694119d8b1e65030515c5c875ca2cb138b8879c29672) // omega_inv
mstore(0x0700, 0x1910cf3d7f4cf2e06d3d2e6646e7ee7b2ead518c3fe97ec9a1ab0fadd65640b2) // omega_inv_to_l
mstore(0x0720, 0x0000000000000000000000000000000000000000000000000000000000000000) // has_accumulator
mstore(0x0740, 0x0000000000000000000000000000000000000000000000000000000000000000) // acc_offset
mstore(0x0760, 0x0000000000000000000000000000000000000000000000000000000000000000) // num_acc_limbs
mstore(0x0780, 0x0000000000000000000000000000000000000000000000000000000000000000) // num_acc_limb_bits
mstore(0x07a0, 0x0000000000000000000000000000000000000000000000000000000000000001) // g1_x
mstore(0x07c0, 0x0000000000000000000000000000000000000000000000000000000000000002) // g1_y
mstore(0x07e0, 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2) // g2_x_1
mstore(0x0800, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed) // g2_x_2
mstore(0x0820, 0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b) // g2_y_1
mstore(0x0840, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa) // g2_y_2
mstore(0x0860, 0x1cf5b0981f9221ad3c470321c8168db63710f6b86fbe96a13b99d1341f6a1fb0) // neg_s_g2_x_1
mstore(0x0880, 0x1b9413878f71b3254818f2988a9570c860f23a7e28653bb7156e7ed7bd0c9733) // neg_s_g2_x_2
mstore(0x08a0, 0x2882080fe5321c33e6fd4e54234e4c10dd759ec3b9622c377f081e52acd0e397) // neg_s_g2_y_1
mstore(0x08c0, 0x25e436ca6accdc342d22e03c770856f7df1b14660d34d84ecb6476e5195515f4) // neg_s_g2_y_2
mstore(0x08e0, 0x1f6b1774d2636b093b3ba6351222e746beeec38ca5cde3aa66ca25f91023332b) // fixed_comms[0].x
mstore(0x0900, 0x265bc8aad33f162217ac0153c0cc2114aa575bda88b2e5c1691ed1cc86d81e87) // fixed_comms[0].y
mstore(0x0920, 0x02af8ae53922896c369719b87b86b99d3691b7dcdfab6248c329605f3c31c496) // fixed_comms[1].x
mstore(0x0940, 0x297359257a1b0f9a5a3d7b761035d65e35f0ed561382e455de483c529b847a89) // fixed_comms[1].y
mstore(0x0960, 0x28394f93cc81c111db84768bc6238de8a3c72672383b1401aa68987bf083b214) // fixed_comms[2].x
mstore(0x0980, 0x251da9a395d3b75945649be029260f7b3f979bda20e0e88d2c4a0f257ff9aa8a) // fixed_comms[2].y
mstore(0x09a0, 0x27a66998c699ec0c930da5c765acb8d361911bd91fc0021377cc289c4bdb87db) // fixed_comms[3].x
mstore(0x09c0, 0x2b3054c9a579e24b0d0c7ddd32cb53010b572671bffa7392bc9a8cfb8d4245e5) // fixed_comms[3].y
mstore(0x09e0, 0x09b90eead6eb9953131ad5ff8a0a6759c811f14a1a6e67f21790283868d56527) // fixed_comms[4].x
mstore(0x0a00, 0x151bf0f5b1c61ab33a03da931220902c21f5c1e3a2996c682c10e61fef475918) // fixed_comms[4].y
mstore(0x0a20, 0x12a0d0df7e4489e681aa554d7b9bdf98f881d6596a927a4fa679c5b42f93b22f) // fixed_comms[5].x
mstore(0x0a40, 0x24c3fcc28c143ef2bb6ad0e2e54ca5281e297e50f950487bcbaea4024f03c80a) // fixed_comms[5].y
mstore(0x0a60, 0x1f6b1774d2636b093b3ba6351222e746beeec38ca5cde3aa66ca25f91023332b) // fixed_comms[6].x
mstore(0x0a80, 0x265bc8aad33f162217ac0153c0cc2114aa575bda88b2e5c1691ed1cc86d81e87) // fixed_comms[6].y
mstore(0x0aa0, 0x02af8ae53922896c369719b87b86b99d3691b7dcdfab6248c329605f3c31c496) // fixed_comms[7].x
mstore(0x0ac0, 0x297359257a1b0f9a5a3d7b761035d65e35f0ed561382e455de483c529b847a89) // fixed_comms[7].y
mstore(0x0ae0, 0x0cd54c770e0d191dc9c7e30bd0a99c5189bd3ffefe7adb5ce0f49aa8b4110710) // fixed_comms[8].x
mstore(0x0b00, 0x2dbe79f1cc6ea31e199640f865929a533488379be33a23e84c436e73cfa0be97) // fixed_comms[8].y
mstore(0x0b20, 0x0357f08d38552d17f1a27f4954f0956e985f697a5cba77b2bc4e40684bcc83e5) // fixed_comms[9].x
mstore(0x0b40, 0x0b70c07dd4d717326ec701507254fac28e91ff79757fe520c73aee9ef90d2448) // fixed_comms[9].y
mstore(0x0b60, 0x218ef15a677d36f91b9e7cd1155cfd2e78f2e5d0e1d9a3902c6e67ebe81902ad) // fixed_comms[10].x
mstore(0x0b80, 0x1c4088a3c06e10072012f486c0f33619dd3d22c5aab900310ea939360fc30efa) // fixed_comms[10].y
mstore(0x0ba0, 0x187edec38196f4da0076dbc3ae4d8ca06a515b6273804cc58393589376180110) // fixed_comms[11].x
mstore(0x0bc0, 0x0ce894b953a2c2d3e976b383207b6dac1e8564c75be74520e6164e39b7ab48c1) // fixed_comms[11].y
mstore(0x0be0, 0x09641faa425d336984c6058aee55005149340c8b5a4c32c4f16c883bb353999c) // fixed_comms[12].x
mstore(0x0c00, 0x19e15d234bc579d85f59cffd6479dd904b2d852e9f507e158a2d7fc688587a69) // fixed_comms[12].y
mstore(0x0c20, 0x27a66998c699ec0c930da5c765acb8d361911bd91fc0021377cc289c4bdb87db) // fixed_comms[13].x
mstore(0x0c40, 0x2b3054c9a579e24b0d0c7ddd32cb53010b572671bffa7392bc9a8cfb8d4245e5) // fixed_comms[13].y
mstore(0x0c60, 0x09b90eead6eb9953131ad5ff8a0a6759c811f14a1a6e67f21790283868d56527) // fixed_comms[14].x
mstore(0x0c80, 0x151bf0f5b1c61ab33a03da931220902c21f5c1e3a2996c682c10e61fef475918) // fixed_comms[14].y
mstore(0x0ca0, 0x02af8ae53922896c369719b87b86b99d3691b7dcdfab6248c329605f3c31c496) // fixed_comms[15].x
mstore(0x0cc0, 0x297359257a1b0f9a5a3d7b761035d65e35f0ed561382e455de483c529b847a89) // fixed_comms[15].y
mstore(0x0ce0, 0x241e72550ff4bc45ecb032879ab77a959a47a1b5c53aa3f7c39874742f17d8db) // fixed_comms[16].x
mstore(0x0d00, 0x2d2306307628daefcf6c46671227063b52f9c4b15f3c55a0ac462f9e62ecc144) // fixed_comms[16].y
mstore(0x0d20, 0x0bcb41fe59f3fd579237767327a96ded921fa74adb2028af06a6b2ee9beb9600) // permutation_comms[0].x
mstore(0x0d40, 0x18849a12cb8691b19156dadb6af70a47be5308c7b714ab4b1c042c7c4554f82d) // permutation_comms[0].y
mstore(0x0d60, 0x2a7bd3e7dd812da1d1d6ecdeb85516263ce11e5190b28c952e92d261f1963fd1) // permutation_comms[1].x
mstore(0x0d80, 0x2264cc46c64a4eda3492596ba58961720d537d16a53ede9ed6f636f408956b4e) // permutation_comms[1].y
mstore(0x0da0, 0x2cdcacbb070fe09ab4a7a42b6f903c09f8856d680f40f73f9493b12d0de506f0) // permutation_comms[2].x
mstore(0x0dc0, 0x136d0c5c583e531a2f6647d2098be7cbca85bdbf566cb1d639fced804b95e337) // permutation_comms[2].y
mstore(0x0de0, 0x1ee83a6f74ce0005f72b397e5c418dd78c55d7ad359ab8b471c943108867fe8a) // permutation_comms[3].x
mstore(0x0e00, 0x229156859025e69a526e324b1108969a8f52afd383fefd393a6b71ba57fc7411) // permutation_comms[3].y
mstore(0x0e20, 0x261ec98c7b6ca3a0d4156800d01e8caaa212e9f4a3caa98aeffef53f7860d509) // permutation_comms[4].x
mstore(0x0e40, 0x2b7089bb090fcd0ff526ac33186475f70108435cc70ea139ab71ad3592347388) // permutation_comms[4].y
mstore(0x0e60, 0x0a09a86598cab46b7000362e878e1f9af446da7c48465b9e46c617d933543210) // permutation_comms[5].x
mstore(0x0e80, 0x0a6598e6312f315bd058bd6ef45f4bb41ce2c42e675561a7a4271eda457ad9f8) // permutation_comms[5].y
mstore(0x0ea0, 0x1198e54fd38a6bfa182e03d42ab0b97dffc4d25f81320f4e73923765c93edbfa) // permutation_comms[6].x
mstore(0x0ec0, 0x0f499a347ae1fecc96ffc5c10d52ab40ae8c31007ecf9dcc871423f46e31688e) // permutation_comms[6].y
mstore(0x0ee0, 0x21ec5411f275a56dcaca7ccb3a14b5787286c0610dddf07e60a49c548ee7291d) // permutation_comms[7].x
mstore(0x0f00, 0x234280b327ee44505a0c465e3942a57839ddd8cf0a6b809b04eb021c9ed7d8ff) // permutation_comms[7].y
mstore(0x0f20, 0x1e4f06d1b828598602b3ad5f1ca94c54f46bdc805b8a6b2b729facb9f207eeee) // permutation_comms[8].x
mstore(0x0f40, 0x0e6d4ec113290812c452da4c414624b15b2efb61d8a5f784bbea35e5a890873e) // permutation_comms[8].y
mstore(0x0f60, 0x262998371736938a342626910e9a1bbc65cb5b66c4fcf55264037241cc0da32a) // permutation_comms[9].x
mstore(0x0f80, 0x2d7efdc1b5f1c4d27ce3375ab28f4041b3a28a74830757e05b4f5ed5ff822c06) // permutation_comms[9].y
mstore(0x0fa0, 0x0c44ff7cb3a8d89914d50043de08bd799cb5eb12d686baf1cbf308a78c16864c) // permutation_comms[10].x
mstore(0x0fc0, 0x13a62408edc81fc9b6d33a3e32285ef354d25e521222c6692e686c57d4c39a08) // permutation_comms[10].y
mstore(0x0fe0, 0x172ba4731c2fd541eabab5f37902dd724bbc6234632a0f6eb99286a1cf5bff23) // permutation_comms[11].x
mstore(0x1000, 0x0ae9408639a036b5d74b115be2796cecb3993111db6ca5bc49e669c3e8f04f86) // permutation_comms[11].y
mstore(0x1020, 0x06f167b2f1ca4f2db6de892fd5c5d7b5853c3b373d25d1610d9d1f05c244cd2f) // permutation_comms[12].x
mstore(0x1040, 0x2374187f270083546d0350b241608f25bd282725fc82c0fcf1156103993849ee) // permutation_comms[12].y
mstore(0x1060, 0x2980111a7b6203e2bb27335322e3e1533f7c7f7a7e5c3f79b2da2c5cf1e900c2) // permutation_comms[13].x
mstore(0x1080, 0x14c66771ebc7fbcad643daeb58a2d91df6db5afc0156a55719b6649ccdf91ee2) // permutation_comms[13].y
mstore(0x10a0, 0x25cfe2b0df59fa03b74ec0e719f7cde85ac02a6a8559d81a3cecb8ef935d4c79) // permutation_comms[14].x
mstore(0x10c0, 0x09146416257ff32a922ca968d508414648767ab459b39317900806fa6cc89802) // permutation_comms[14].y
mstore(0x10e0, 0x0f90c1f8834639080818fb3a4fb2da7a3ff8b5168f2b8abeafba24b49e253fea) // permutation_comms[15].x
mstore(0x1100, 0x2a4273eb9314075bc19da07581bca118ff5384d9cc91cb10641202c305f24abe) // permutation_comms[15].y
mstore(0x1120, 0x2455133013160f8d40673e100efcb5cefc10276ffbf6f8f4967c5307f92ba0d3) // permutation_comms[16].x
mstore(0x1140, 0x01ef3199288f9b9a19cd9abe718f2b98c0c9211f984c2628a0ed889f8ef9f4ba) // permutation_comms[16].y
mstore(0x1160, 0x26fb5c39410696c6d88bb17fd34e80c7a5b536241527870f57372fdf83ae4ffd) // permutation_comms[17].x
mstore(0x1180, 0x23f84e6efef8614e26192cbc34d651fafca98f8752bae25069010a08538c832a) // permutation_comms[17].y
mstore(0x11a0, 0x0bcb511fbfa979bd34915a8a169fd81f6fdecf76ccba46bcf705b0ba25fe6991) // permutation_comms[18].x
mstore(0x11c0, 0x147b1fb3b6b7f79a7d0eaaa4c9df4396965faf3219aab85e129bae3e5713885a) // permutation_comms[18].y
mstore(0x11e0, 0x23b564d83a77be986bb8d6514f80e2a73586e5b62e6c093f22d6f1550b85c233) // permutation_comms[19].x
mstore(0x1200, 0x0514a126e170a8e0d625e1dae64fb8eea5580f5d7e86797e5187931ed225d2f2) // permutation_comms[19].y
// Read accumulator from instances
if mload(HAS_ACCUMULATOR_MPTR) {
let num_limbs := mload(NUM_ACC_LIMBS_MPTR)
let num_limb_bits := mload(NUM_ACC_LIMB_BITS_MPTR)
let cptr := add(INSTANCE_CPTR, mul(mload(ACC_OFFSET_MPTR), 0x20))
let lhs_y_off := mul(num_limbs, 0x20)
let rhs_x_off := mul(lhs_y_off, 2)
let rhs_y_off := mul(lhs_y_off, 3)
let lhs_x := calldataload(cptr)
let lhs_y := calldataload(add(cptr, lhs_y_off))
let rhs_x := calldataload(add(cptr, rhs_x_off))
let rhs_y := calldataload(add(cptr, rhs_y_off))
for
{
let cptr_end := add(cptr, mul(0x20, num_limbs))
let shift := num_limb_bits
}
lt(cptr, cptr_end)
{}
{
cptr := add(cptr, 0x20)
lhs_x := add(lhs_x, shl(shift, calldataload(cptr)))
lhs_y := add(lhs_y, shl(shift, calldataload(add(cptr, lhs_y_off))))
rhs_x := add(rhs_x, shl(shift, calldataload(add(cptr, rhs_x_off))))
rhs_y := add(rhs_y, shl(shift, calldataload(add(cptr, rhs_y_off))))
shift := add(shift, num_limb_bits)
}
success := and(success, and(lt(lhs_x, q), lt(lhs_y, q)))
success := and(success, eq(mulmod(lhs_y, lhs_y, q), addmod(mulmod(lhs_x, mulmod(lhs_x, lhs_x, q), q), 3, q)))
success := and(success, and(lt(rhs_x, q), lt(rhs_y, q)))
success := and(success, eq(mulmod(rhs_y, rhs_y, q), addmod(mulmod(rhs_x, mulmod(rhs_x, rhs_x, q), q), 3, q)))
mstore(ACC_LHS_X_MPTR, lhs_x)
mstore(ACC_LHS_Y_MPTR, lhs_y)
mstore(ACC_RHS_X_MPTR, rhs_x)
mstore(ACC_RHS_Y_MPTR, rhs_y)
}
pop(q)
}
// Revert earlier if anything from calldata is invalid
if iszero(success) {
revert(0, 0)
}
// Compute lagrange evaluations and instance evaluation
{
let k := mload(K_MPTR)
let x := mload(X_MPTR)
let x_n := x
for
{ let idx := 0 }
lt(idx, k)
{ idx := add(idx, 1) }
{
x_n := mulmod(x_n, x_n, r)
}
let omega := mload(OMEGA_MPTR)
let mptr := X_N_MPTR
let mptr_end := add(mptr, mul(0x20, add(mload(NUM_INSTANCES_MPTR), 6)))
if iszero(mload(NUM_INSTANCES_MPTR)) {
mptr_end := add(mptr_end, 0x20)
}
for
{ let pow_of_omega := mload(OMEGA_INV_TO_L_MPTR) }
lt(mptr, mptr_end)
{ mptr := add(mptr, 0x20) }
{
mstore(mptr, addmod(x, sub(r, pow_of_omega), r))
pow_of_omega := mulmod(pow_of_omega, omega, r)
}
let x_n_minus_1 := addmod(x_n, sub(r, 1), r)
mstore(mptr_end, x_n_minus_1)
success := batch_invert(success, X_N_MPTR, add(mptr_end, 0x20), r)
mptr := X_N_MPTR
let l_i_common := mulmod(x_n_minus_1, mload(N_INV_MPTR), r)
for
{ let pow_of_omega := mload(OMEGA_INV_TO_L_MPTR) }
lt(mptr, mptr_end)
{ mptr := add(mptr, 0x20) }
{
mstore(mptr, mulmod(l_i_common, mulmod(mload(mptr), pow_of_omega, r), r))
pow_of_omega := mulmod(pow_of_omega, omega, r)
}
let l_blind := mload(add(X_N_MPTR, 0x20))
let l_i_cptr := add(X_N_MPTR, 0x40)
for
{ let l_i_cptr_end := add(X_N_MPTR, 0xc0) }
lt(l_i_cptr, l_i_cptr_end)
{ l_i_cptr := add(l_i_cptr, 0x20) }
{
l_blind := addmod(l_blind, mload(l_i_cptr), r)
}
let instance_eval := 0
for
{
let instance_cptr := INSTANCE_CPTR
let instance_cptr_end := add(instance_cptr, mul(0x20, mload(NUM_INSTANCES_MPTR)))
}
lt(instance_cptr, instance_cptr_end)
{
instance_cptr := add(instance_cptr, 0x20)
l_i_cptr := add(l_i_cptr, 0x20)
}
{
instance_eval := addmod(instance_eval, mulmod(mload(l_i_cptr), calldataload(instance_cptr), r), r)
}
let x_n_minus_1_inv := mload(mptr_end)
let l_last := mload(X_N_MPTR)
let l_0 := mload(add(X_N_MPTR, 0xc0))
mstore(X_N_MPTR, x_n)
mstore(X_N_MINUS_1_INV_MPTR, x_n_minus_1_inv)
mstore(L_LAST_MPTR, l_last)
mstore(L_BLIND_MPTR, l_blind)
mstore(L_0_MPTR, l_0)
mstore(INSTANCE_EVAL_MPTR, instance_eval)
}
// Compute quotient evavluation
{
let quotient_eval_numer
let delta := 4131629893567559867359510883348571134090853742863529169391034518566172092834
let y := mload(Y_MPTR)
{
let var0 := 0x1
let f_0 := calldataload(0x0b64)
let var1 := sub(r, f_0)
let var2 := addmod(var0, var1, r)
let a_13 := calldataload(0x0a64)
let var3 := sub(r, a_13)
let var4 := addmod(var0, var3, r)
let var5 := mulmod(var2, var4, r)
let a_0_next_1 := calldataload(0x0b04)
let a_0 := calldataload(0x0984)
let var6 := sub(r, a_0)
let var7 := addmod(a_0_next_1, var6, r)
let var8 := mulmod(var5, var7, r)
let f_16 := calldataload(0x0b84)
let var9 := mulmod(var8, f_16, r)
quotient_eval_numer := var9
}
{
let a_7 := calldataload(0x0a44)
let a_3 := calldataload(0x0924)
let a_2 := calldataload(0x08c4)
let var0 := 0x1
let var1 := addmod(a_2, var0, r)
let var2 := sub(r, var1)
let var3 := addmod(a_3, var2, r)
let var4 := mulmod(a_7, var3, r)
let f_16 := calldataload(0x0b84)
let var5 := mulmod(var4, f_16, r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), var5, r)
}
{
let a_8 := calldataload(0x0a24)
let a_3 := calldataload(0x0924)
let a_2 := calldataload(0x08c4)
let var0 := 0x1
let var1 := sub(r, var0)
let var2 := addmod(a_2, var1, r)
let var3 := sub(r, var2)
let var4 := addmod(a_3, var3, r)
let var5 := mulmod(a_8, var4, r)
let f_16 := calldataload(0x0b84)
let var6 := mulmod(var5, f_16, r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), var6, r)
}
{
let a_9 := calldataload(0x0a04)
let a_2 := calldataload(0x08c4)
let var0 := mulmod(a_9, a_2, r)
let f_16 := calldataload(0x0b84)
let var1 := mulmod(var0, f_16, r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), var1, r)
}
{
let a_2 := calldataload(0x08c4)
let a_15 := calldataload(0x0aa4)
let a_6 := calldataload(0x08a4)
let var0 := mulmod(a_15, a_6, r)
let a_14 := calldataload(0x0904)
let a_17 := calldataload(0x08e4)
let var1 := mulmod(a_14, a_17, r)
let var2 := addmod(var0, var1, r)
let var3 := sub(r, var2)
let var4 := addmod(a_2, var3, r)
let f_16 := calldataload(0x0b84)
let var5 := mulmod(var4, f_16, r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), var5, r)
}
{
let a_3 := calldataload(0x0924)
let a_16 := calldataload(0x0964)
let a_18 := calldataload(0x0944)
let var0 := mulmod(a_16, a_18, r)
let var1 := sub(r, var0)
let var2 := addmod(a_3, var1, r)
let f_16 := calldataload(0x0b84)
let var3 := mulmod(var2, f_16, r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), var3, r)
}
{
let a_6_next_1 := calldataload(0x0b24)
let a_4 := calldataload(0x0ac4)
let a_2 := calldataload(0x08c4)
let var0 := mulmod(a_4, a_2, r)
let a_5 := calldataload(0x0ae4)
let a_3 := calldataload(0x0924)
let var1 := mulmod(a_5, a_3, r)
let var2 := addmod(var0, var1, r)
let var3 := 0x1
let var4 := addmod(a_4, a_5, r)
let a_11 := calldataload(0x09e4)
let var5 := addmod(var4, a_11, r)
let var6 := sub(r, var5)
let var7 := addmod(var3, var6, r)
let a_6 := calldataload(0x08a4)
let var8 := mulmod(var7, a_6, r)
let var9 := addmod(var2, var8, r)
let var10 := sub(r, var9)
let var11 := addmod(a_6_next_1, var10, r)
let f_16 := calldataload(0x0b84)
let var12 := mulmod(var11, f_16, r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), var12, r)
}
{
let a_1_next_1 := calldataload(0x0b44)
let var0 := 0x1
let f_1_next_1 := calldataload(0x0ba4)
let var1 := sub(r, f_1_next_1)
let var2 := addmod(var0, var1, r)
let a_10 := calldataload(0x09a4)
let a_0 := calldataload(0x0984)
let var3 := mulmod(a_10, a_0, r)
let a_12 := calldataload(0x09c4)
let a_1 := calldataload(0x0a84)
let var4 := mulmod(a_12, a_1, r)
let var5 := addmod(var3, var4, r)
let var6 := addmod(a_10, a_12, r)
let a_13 := calldataload(0x0a64)
let var7 := addmod(var6, a_13, r)
let var8 := sub(r, var7)
let var9 := addmod(var0, var8, r)
let var10 := addmod(a_1, var0, r)
let var11 := mulmod(var9, var10, r)
let var12 := addmod(var5, var11, r)
let var13 := mulmod(var2, var12, r)
let var14 := sub(r, var13)
let var15 := addmod(a_1_next_1, var14, r)
let f_16 := calldataload(0x0b84)
let var16 := mulmod(var15, f_16, r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), var16, r)
}
{
let f_15 := calldataload(0x0bc4)
let a_0 := calldataload(0x0984)
let var0 := 0x2
let var1 := sub(r, var0)
let var2 := addmod(a_0, var1, r)
let var3 := mulmod(f_15, var2, r)
let f_16 := calldataload(0x0b84)
let var4 := mulmod(var3, f_16, r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), var4, r)
}
{
let l_0 := mload(L_0_MPTR)
let eval := addmod(l_0, sub(r, mulmod(l_0, calldataload(0x1024), r)), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let perm_z_last := calldataload(0x11a4)
let eval := mulmod(mload(L_LAST_MPTR), addmod(mulmod(perm_z_last, perm_z_last, r), sub(r, perm_z_last), r), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let eval := mulmod(mload(L_0_MPTR), addmod(calldataload(0x1084), sub(r, calldataload(0x1064)), r), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let eval := mulmod(mload(L_0_MPTR), addmod(calldataload(0x10e4), sub(r, calldataload(0x10c4)), r), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let eval := mulmod(mload(L_0_MPTR), addmod(calldataload(0x1144), sub(r, calldataload(0x1124)), r), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let eval := mulmod(mload(L_0_MPTR), addmod(calldataload(0x11a4), sub(r, calldataload(0x1184)), r), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let gamma := mload(GAMMA_MPTR)
let beta := mload(BETA_MPTR)
let lhs := calldataload(0x1044)
let rhs := calldataload(0x1024)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x08a4), mulmod(beta, calldataload(0x0da4), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x08c4), mulmod(beta, calldataload(0x0dc4), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x08e4), mulmod(beta, calldataload(0x0de4), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x0904), mulmod(beta, calldataload(0x0e04), r), r), gamma, r), r)
mstore(0x00, mulmod(beta, mload(X_MPTR), r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x08a4), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x08c4), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x08e4), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x0904), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
let left_sub_right := addmod(lhs, sub(r, rhs), r)
let eval := addmod(left_sub_right, sub(r, mulmod(left_sub_right, addmod(mload(L_LAST_MPTR), mload(L_BLIND_MPTR), r), r)), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let gamma := mload(GAMMA_MPTR)
let beta := mload(BETA_MPTR)
let lhs := calldataload(0x10a4)
let rhs := calldataload(0x1084)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x0924), mulmod(beta, calldataload(0x0e24), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x0944), mulmod(beta, calldataload(0x0e44), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x0964), mulmod(beta, calldataload(0x0e64), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x0984), mulmod(beta, calldataload(0x0e84), r), r), gamma, r), r)
rhs := mulmod(rhs, addmod(addmod(calldataload(0x0924), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x0944), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x0964), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x0984), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
let left_sub_right := addmod(lhs, sub(r, rhs), r)
let eval := addmod(left_sub_right, sub(r, mulmod(left_sub_right, addmod(mload(L_LAST_MPTR), mload(L_BLIND_MPTR), r), r)), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let gamma := mload(GAMMA_MPTR)
let beta := mload(BETA_MPTR)
let lhs := calldataload(0x1104)
let rhs := calldataload(0x10e4)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x09a4), mulmod(beta, calldataload(0x0ea4), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x09c4), mulmod(beta, calldataload(0x0ec4), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x09e4), mulmod(beta, calldataload(0x0ee4), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x0a04), mulmod(beta, calldataload(0x0f04), r), r), gamma, r), r)
rhs := mulmod(rhs, addmod(addmod(calldataload(0x09a4), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x09c4), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x09e4), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x0a04), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
let left_sub_right := addmod(lhs, sub(r, rhs), r)
let eval := addmod(left_sub_right, sub(r, mulmod(left_sub_right, addmod(mload(L_LAST_MPTR), mload(L_BLIND_MPTR), r), r)), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let gamma := mload(GAMMA_MPTR)
let beta := mload(BETA_MPTR)
let lhs := calldataload(0x1164)
let rhs := calldataload(0x1144)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x0a24), mulmod(beta, calldataload(0x0f24), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x0a44), mulmod(beta, calldataload(0x0f44), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x0a64), mulmod(beta, calldataload(0x0f64), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x0a84), mulmod(beta, calldataload(0x0f84), r), r), gamma, r), r)
rhs := mulmod(rhs, addmod(addmod(calldataload(0x0a24), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x0a44), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x0a64), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x0a84), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
let left_sub_right := addmod(lhs, sub(r, rhs), r)
let eval := addmod(left_sub_right, sub(r, mulmod(left_sub_right, addmod(mload(L_LAST_MPTR), mload(L_BLIND_MPTR), r), r)), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let gamma := mload(GAMMA_MPTR)
let beta := mload(BETA_MPTR)
let lhs := calldataload(0x11c4)
let rhs := calldataload(0x11a4)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x0aa4), mulmod(beta, calldataload(0x0fa4), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x0ac4), mulmod(beta, calldataload(0x0fc4), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(calldataload(0x0ae4), mulmod(beta, calldataload(0x0fe4), r), r), gamma, r), r)
lhs := mulmod(lhs, addmod(addmod(mload(INSTANCE_EVAL_MPTR), mulmod(beta, calldataload(0x1004), r), r), gamma, r), r)
rhs := mulmod(rhs, addmod(addmod(calldataload(0x0aa4), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x0ac4), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(calldataload(0x0ae4), mload(0x00), r), gamma, r), r)
mstore(0x00, mulmod(mload(0x00), delta, r))
rhs := mulmod(rhs, addmod(addmod(mload(INSTANCE_EVAL_MPTR), mload(0x00), r), gamma, r), r)
let left_sub_right := addmod(lhs, sub(r, rhs), r)
let eval := addmod(left_sub_right, sub(r, mulmod(left_sub_right, addmod(mload(L_LAST_MPTR), mload(L_BLIND_MPTR), r), r)), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let l_0 := mload(L_0_MPTR)
let eval := addmod(l_0, mulmod(l_0, sub(r, calldataload(0x11e4)), r), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let l_last := mload(L_LAST_MPTR)
let eval := mulmod(l_last, addmod(mulmod(calldataload(0x11e4), calldataload(0x11e4), r), sub(r, calldataload(0x11e4)), r), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let theta := mload(THETA_MPTR)
let input
{
let var0 := 0x1
let f_16 := calldataload(0x0b84)
let var1 := mulmod(var0, f_16, r)
let a_1 := calldataload(0x0a84)
let c_0 := mload(0x1220)
let var2 := sub(r, c_0)
let var3 := addmod(a_1, var2, r)
let var4 := mulmod(var1, var3, r)
let var5 := addmod(var4, c_0, r)
let a_4 := calldataload(0x0ac4)
let var6 := addmod(a_4, var2, r)
let var7 := mulmod(var1, var6, r)
let var8 := addmod(var7, c_0, r)
let a_5 := calldataload(0x0ae4)
let var9 := addmod(a_5, var2, r)
let var10 := mulmod(var1, var9, r)
let var11 := addmod(var10, c_0, r)
let a_7 := calldataload(0x0a44)
let var12 := addmod(a_7, var2, r)
let var13 := mulmod(var1, var12, r)
let var14 := addmod(var13, c_0, r)
let a_8 := calldataload(0x0a24)
let var15 := addmod(a_8, var2, r)
let var16 := mulmod(var1, var15, r)
let var17 := addmod(var16, c_0, r)
let a_9 := calldataload(0x0a04)
let var18 := addmod(a_9, var2, r)
let var19 := mulmod(var1, var18, r)
let var20 := addmod(var19, c_0, r)
let a_10 := calldataload(0x09a4)
let var21 := addmod(a_10, var2, r)
let var22 := mulmod(var1, var21, r)
let var23 := addmod(var22, c_0, r)
let a_11 := calldataload(0x09e4)
let var24 := addmod(a_11, var2, r)
let var25 := mulmod(var1, var24, r)
let var26 := addmod(var25, c_0, r)
let a_12 := calldataload(0x09c4)
let var27 := addmod(a_12, var2, r)
let var28 := mulmod(var1, var27, r)
let var29 := addmod(var28, c_0, r)
let a_13 := calldataload(0x0a64)
let var30 := addmod(a_13, var2, r)
let var31 := mulmod(var1, var30, r)
let var32 := addmod(var31, c_0, r)
let a_14 := calldataload(0x0904)
let var33 := addmod(a_14, var2, r)
let var34 := mulmod(var1, var33, r)
let var35 := addmod(var34, c_0, r)
let a_15 := calldataload(0x0aa4)
let var36 := addmod(a_15, var2, r)
let var37 := mulmod(var1, var36, r)
let var38 := addmod(var37, c_0, r)
let a_16 := calldataload(0x0964)
let var39 := addmod(a_16, var2, r)
let var40 := mulmod(var1, var39, r)
let var41 := addmod(var40, c_0, r)
input := var5
input := addmod(mulmod(input, theta, r), var8, r)
input := addmod(mulmod(input, theta, r), var11, r)
input := addmod(mulmod(input, theta, r), var14, r)
input := addmod(mulmod(input, theta, r), var17, r)
input := addmod(mulmod(input, theta, r), var20, r)
input := addmod(mulmod(input, theta, r), var23, r)
input := addmod(mulmod(input, theta, r), var26, r)
input := addmod(mulmod(input, theta, r), var29, r)
input := addmod(mulmod(input, theta, r), var32, r)
input := addmod(mulmod(input, theta, r), var35, r)
input := addmod(mulmod(input, theta, r), var38, r)
input := addmod(mulmod(input, theta, r), var41, r)
}
let table
{
let var0 := 0x1
let f_16 := calldataload(0x0b84)
let var1 := mulmod(var0, f_16, r)
let f_2 := calldataload(0x0be4)
let c_0 := mload(0x1220)
let var2 := sub(r, c_0)
let var3 := addmod(f_2, var2, r)
let var4 := mulmod(var1, var3, r)
let var5 := addmod(var4, c_0, r)
let f_13 := calldataload(0x0c04)
let var6 := addmod(f_13, var2, r)
let var7 := mulmod(var1, var6, r)
let var8 := addmod(var7, c_0, r)
let f_14 := calldataload(0x0c24)
let var9 := addmod(f_14, var2, r)
let var10 := mulmod(var1, var9, r)
let var11 := addmod(var10, c_0, r)
let f_10 := calldataload(0x0c44)
let var12 := addmod(f_10, var2, r)
let var13 := mulmod(var1, var12, r)
let var14 := addmod(var13, c_0, r)
let f_9 := calldataload(0x0c64)
let var15 := addmod(f_9, var2, r)
let var16 := mulmod(var1, var15, r)
let var17 := addmod(var16, c_0, r)
let f_8 := calldataload(0x0c84)
let var18 := addmod(f_8, var2, r)
let var19 := mulmod(var1, var18, r)
let var20 := addmod(var19, c_0, r)
let f_5 := calldataload(0x0ca4)
let var21 := addmod(f_5, var2, r)
let var22 := mulmod(var1, var21, r)
let var23 := addmod(var22, c_0, r)
let f_7 := calldataload(0x0cc4)
let var24 := addmod(f_7, var2, r)
let var25 := mulmod(var1, var24, r)
let var26 := addmod(var25, c_0, r)
let f_6 := calldataload(0x0ce4)
let var27 := addmod(f_6, var2, r)
let var28 := mulmod(var1, var27, r)
let var29 := addmod(var28, c_0, r)
let f_11 := calldataload(0x0d04)
let var30 := addmod(f_11, var2, r)
let var31 := mulmod(var1, var30, r)
let var32 := addmod(var31, c_0, r)
let f_3 := calldataload(0x0d24)
let var33 := addmod(f_3, var2, r)
let var34 := mulmod(var1, var33, r)
let var35 := addmod(var34, c_0, r)
let f_12 := calldataload(0x0d44)
let var36 := addmod(f_12, var2, r)
let var37 := mulmod(var1, var36, r)
let var38 := addmod(var37, c_0, r)
let f_4 := calldataload(0x0d64)
let var39 := addmod(f_4, var2, r)
let var40 := mulmod(var1, var39, r)
let var41 := addmod(var40, c_0, r)
table := var5
table := addmod(mulmod(table, theta, r), var8, r)
table := addmod(mulmod(table, theta, r), var11, r)
table := addmod(mulmod(table, theta, r), var14, r)
table := addmod(mulmod(table, theta, r), var17, r)
table := addmod(mulmod(table, theta, r), var20, r)
table := addmod(mulmod(table, theta, r), var23, r)
table := addmod(mulmod(table, theta, r), var26, r)
table := addmod(mulmod(table, theta, r), var29, r)
table := addmod(mulmod(table, theta, r), var32, r)
table := addmod(mulmod(table, theta, r), var35, r)
table := addmod(mulmod(table, theta, r), var38, r)
table := addmod(mulmod(table, theta, r), var41, r)
}
let beta := mload(BETA_MPTR)
let gamma := mload(GAMMA_MPTR)
let lhs := mulmod(calldataload(0x1204), mulmod(addmod(calldataload(0x1224), beta, r), addmod(calldataload(0x1264), gamma, r), r), r)
let rhs := mulmod(calldataload(0x11e4), mulmod(addmod(input, beta, r), addmod(table, gamma, r), r), r)
let eval := mulmod(addmod(1, sub(r, addmod(mload(L_BLIND_MPTR), mload(L_LAST_MPTR), r)), r), addmod(lhs, sub(r, rhs), r), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let eval := mulmod(mload(L_0_MPTR), addmod(calldataload(0x1224), sub(r, calldataload(0x1264)), r), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
{
let eval := mulmod(addmod(1, sub(r, addmod(mload(L_BLIND_MPTR), mload(L_LAST_MPTR), r)), r), mulmod(addmod(calldataload(0x1224), sub(r, calldataload(0x1264)), r), addmod(calldataload(0x1224), sub(r, calldataload(0x1244)), r), r), r)
quotient_eval_numer := addmod(mulmod(quotient_eval_numer, y, r), eval, r)
}
pop(y)
pop(delta)
let quotient_eval := mulmod(quotient_eval_numer, mload(X_N_MINUS_1_INV_MPTR), r)
mstore(QUOTIENT_EVAL_MPTR, quotient_eval)
}
// Compute quotient commitment
{
mstore(0x00, calldataload(LAST_QUOTIENT_X_CPTR))
mstore(0x20, calldataload(add(LAST_QUOTIENT_X_CPTR, 0x20)))
let x_n := mload(X_N_MPTR)
for
{
let cptr := sub(LAST_QUOTIENT_X_CPTR, 0x40)
let cptr_end := sub(FIRST_QUOTIENT_X_CPTR, 0x40)
}
lt(cptr_end, cptr)
{}
{
success := ec_mul_acc(success, x_n)
success := ec_add_acc(success, calldataload(cptr), calldataload(add(cptr, 0x20)))
cptr := sub(cptr, 0x40)
}
mstore(QUOTIENT_X_MPTR, mload(0x00))
mstore(QUOTIENT_Y_MPTR, mload(0x20))
}
// Compute pairing lhs and rhs
{
{
let x := mload(X_MPTR)
let omega := mload(OMEGA_MPTR)
let omega_inv := mload(OMEGA_INV_MPTR)
let x_pow_of_omega := mulmod(x, omega, r)
mstore(0x03a0, x_pow_of_omega)
mstore(0x0380, x)
x_pow_of_omega := mulmod(x, omega_inv, r)
mstore(0x0360, x_pow_of_omega)
x_pow_of_omega := mulmod(x_pow_of_omega, omega_inv, r)
x_pow_of_omega := mulmod(x_pow_of_omega, omega_inv, r)
x_pow_of_omega := mulmod(x_pow_of_omega, omega_inv, r)
x_pow_of_omega := mulmod(x_pow_of_omega, omega_inv, r)
x_pow_of_omega := mulmod(x_pow_of_omega, omega_inv, r)
mstore(0x0340, x_pow_of_omega)
}
{
let mu := mload(MU_MPTR)
for
{
let mptr := 0x03c0
let mptr_end := 0x0440
let point_mptr := 0x0340
}
lt(mptr, mptr_end)
{
mptr := add(mptr, 0x20)
point_mptr := add(point_mptr, 0x20)
}
{
mstore(mptr, addmod(mu, sub(r, mload(point_mptr)), r))
}
let s
s := mload(0x0400)
s := mulmod(s, mload(0x0420), r)
mstore(0x0440, s)
let diff
diff := mload(0x03c0)
diff := mulmod(diff, mload(0x03e0), r)
mstore(0x0460, diff)
mstore(0x00, diff)
diff := mload(0x03c0)
diff := mulmod(diff, mload(0x03e0), r)
diff := mulmod(diff, mload(0x0420), r)
mstore(0x0480, diff)
diff := mload(0x03e0)
mstore(0x04a0, diff)
diff := mload(0x03c0)
diff := mulmod(diff, mload(0x0420), r)
mstore(0x04c0, diff)
diff := mload(0x03c0)
diff := mulmod(diff, mload(0x03e0), r)
diff := mulmod(diff, mload(0x0400), r)
mstore(0x04e0, diff)
}
{
let point_2 := mload(0x0380)
let point_3 := mload(0x03a0)
let coeff
coeff := addmod(point_2, sub(r, point_3), r)
coeff := mulmod(coeff, mload(0x0400), r)
mstore(0x20, coeff)
coeff := addmod(point_3, sub(r, point_2), r)
coeff := mulmod(coeff, mload(0x0420), r)
mstore(0x40, coeff)
}
{
let point_2 := mload(0x0380)
let coeff
coeff := 1
coeff := mulmod(coeff, mload(0x0400), r)
mstore(0x60, coeff)
}
{
let point_0 := mload(0x0340)
let point_2 := mload(0x0380)
let point_3 := mload(0x03a0)
let coeff
coeff := addmod(point_0, sub(r, point_2), r)
coeff := mulmod(coeff, addmod(point_0, sub(r, point_3), r), r)
coeff := mulmod(coeff, mload(0x03c0), r)
mstore(0x80, coeff)
coeff := addmod(point_2, sub(r, point_0), r)
coeff := mulmod(coeff, addmod(point_2, sub(r, point_3), r), r)
coeff := mulmod(coeff, mload(0x0400), r)
mstore(0xa0, coeff)
coeff := addmod(point_3, sub(r, point_0), r)
coeff := mulmod(coeff, addmod(point_3, sub(r, point_2), r), r)
coeff := mulmod(coeff, mload(0x0420), r)
mstore(0xc0, coeff)
}
{
let point_1 := mload(0x0360)
let point_2 := mload(0x0380)
let coeff
coeff := addmod(point_1, sub(r, point_2), r)
coeff := mulmod(coeff, mload(0x03e0), r)
mstore(0xe0, coeff)
coeff := addmod(point_2, sub(r, point_1), r)
coeff := mulmod(coeff, mload(0x0400), r)
mstore(0x0100, coeff)
}
{
let point_3 := mload(0x03a0)
let coeff
coeff := 1
coeff := mulmod(coeff, mload(0x0420), r)
mstore(0x0120, coeff)
}
{
success := batch_invert(success, 0, 0x0140, r)
let diff_0_inv := mload(0x00)
mstore(0x0460, diff_0_inv)
for
{
let mptr := 0x0480
let mptr_end := 0x0500
}
lt(mptr, mptr_end)
{ mptr := add(mptr, 0x20) }
{
mstore(mptr, mulmod(mload(mptr), diff_0_inv, r))
}
}
{
let zeta := mload(ZETA_MPTR)
let r_eval
r_eval := addmod(r_eval, mulmod(mload(0x20), calldataload(0x11e4), r), r)
r_eval := addmod(r_eval, mulmod(mload(0x40), calldataload(0x1204), r), r)
r_eval := mulmod(r_eval, zeta, r)
r_eval := addmod(r_eval, mulmod(mload(0x20), calldataload(0x11a4), r), r)
r_eval := addmod(r_eval, mulmod(mload(0x40), calldataload(0x11c4), r), r)
r_eval := mulmod(r_eval, zeta, r)
r_eval := addmod(r_eval, mulmod(mload(0x20), calldataload(0x0a84), r), r)
r_eval := addmod(r_eval, mulmod(mload(0x40), calldataload(0x0b44), r), r)
r_eval := mulmod(r_eval, zeta, r)
r_eval := addmod(r_eval, mulmod(mload(0x20), calldataload(0x0984), r), r)
r_eval := addmod(r_eval, mulmod(mload(0x40), calldataload(0x0b04), r), r)
r_eval := mulmod(r_eval, zeta, r)
r_eval := addmod(r_eval, mulmod(mload(0x20), calldataload(0x08a4), r), r)
r_eval := addmod(r_eval, mulmod(mload(0x40), calldataload(0x0b24), r), r)
mstore(0x0500, r_eval)
}
{
let coeff := mload(0x60)
let zeta := mload(ZETA_MPTR)
let r_eval
r_eval := mulmod(coeff, calldataload(0x0d84), r)
r_eval := mulmod(r_eval, zeta, r)
r_eval := addmod(r_eval, mulmod(coeff, mload(QUOTIENT_EVAL_MPTR), r), r)
for
{
let cptr := 0x1004
let cptr_end := 0x0d84
}
lt(cptr_end, cptr)
{ cptr := sub(cptr, 0x20) }
{
r_eval := addmod(mulmod(r_eval, zeta, r), mulmod(coeff, calldataload(cptr), r), r)
}
for
{
let cptr := 0x0d64
let cptr_end := 0x0ba4
}
lt(cptr_end, cptr)
{ cptr := sub(cptr, 0x20) }
{
r_eval := addmod(mulmod(r_eval, zeta, r), mulmod(coeff, calldataload(cptr), r), r)
}
r_eval := mulmod(r_eval, zeta, r)
r_eval := addmod(r_eval, mulmod(coeff, calldataload(0x0b84), r), r)
r_eval := mulmod(r_eval, zeta, r)
r_eval := addmod(r_eval, mulmod(coeff, calldataload(0x0b64), r), r)
r_eval := mulmod(r_eval, zeta, r)
r_eval := addmod(r_eval, mulmod(coeff, calldataload(0x1264), r), r)
for
{
let cptr := 0x0ae4
let cptr_end := 0x0a84
}
lt(cptr_end, cptr)
{ cptr := sub(cptr, 0x20) }
{
r_eval := addmod(mulmod(r_eval, zeta, r), mulmod(coeff, calldataload(cptr), r), r)
}
for
{
let cptr := 0x0a64
let cptr_end := 0x0984
}
lt(cptr_end, cptr)
{ cptr := sub(cptr, 0x20) }
{
r_eval := addmod(mulmod(r_eval, zeta, r), mulmod(coeff, calldataload(cptr), r), r)
}
for
{
let cptr := 0x0964
let cptr_end := 0x08a4
}
lt(cptr_end, cptr)
{ cptr := sub(cptr, 0x20) }
{
r_eval := addmod(mulmod(r_eval, zeta, r), mulmod(coeff, calldataload(cptr), r), r)
}
r_eval := mulmod(r_eval, mload(0x0480), r)
mstore(0x0520, r_eval)
}
{
let zeta := mload(ZETA_MPTR)
let r_eval
r_eval := addmod(r_eval, mulmod(mload(0x80), calldataload(0x1184), r), r)
r_eval := addmod(r_eval, mulmod(mload(0xa0), calldataload(0x1144), r), r)
r_eval := addmod(r_eval, mulmod(mload(0xc0), calldataload(0x1164), r), r)
r_eval := mulmod(r_eval, zeta, r)
r_eval := addmod(r_eval, mulmod(mload(0x80), calldataload(0x1124), r), r)
r_eval := addmod(r_eval, mulmod(mload(0xa0), calldataload(0x10e4), r), r)
r_eval := addmod(r_eval, mulmod(mload(0xc0), calldataload(0x1104), r), r)
r_eval := mulmod(r_eval, zeta, r)
r_eval := addmod(r_eval, mulmod(mload(0x80), calldataload(0x10c4), r), r)
r_eval := addmod(r_eval, mulmod(mload(0xa0), calldataload(0x1084), r), r)
r_eval := addmod(r_eval, mulmod(mload(0xc0), calldataload(0x10a4), r), r)
r_eval := mulmod(r_eval, zeta, r)
r_eval := addmod(r_eval, mulmod(mload(0x80), calldataload(0x1064), r), r)
r_eval := addmod(r_eval, mulmod(mload(0xa0), calldataload(0x1024), r), r)
r_eval := addmod(r_eval, mulmod(mload(0xc0), calldataload(0x1044), r), r)
r_eval := mulmod(r_eval, mload(0x04a0), r)
mstore(0x0540, r_eval)
}
{
let zeta := mload(ZETA_MPTR)
let r_eval
r_eval := addmod(r_eval, mulmod(mload(0xe0), calldataload(0x1244), r), r)
r_eval := addmod(r_eval, mulmod(mload(0x0100), calldataload(0x1224), r), r)
r_eval := mulmod(r_eval, mload(0x04c0), r)
mstore(0x0560, r_eval)
}
{
let coeff := mload(0x0120)
let zeta := mload(ZETA_MPTR)
let r_eval
r_eval := mulmod(coeff, calldataload(0x0ba4), r)
r_eval := mulmod(r_eval, mload(0x04e0), r)
mstore(0x0580, r_eval)
}
{
let sum := mload(0x20)
sum := addmod(sum, mload(0x40), r)
mstore(0x05a0, sum)
}
{
let sum := mload(0x60)
mstore(0x05c0, sum)
}
{
let sum := mload(0x80)
sum := addmod(sum, mload(0xa0), r)
sum := addmod(sum, mload(0xc0), r)
mstore(0x05e0, sum)
}
{
let sum := mload(0xe0)
sum := addmod(sum, mload(0x0100), r)
mstore(0x0600, sum)
}
{
let sum := mload(0x0120)
mstore(0x0620, sum)
}
{
for
{
let mptr := 0x00
let mptr_end := 0xa0
let sum_mptr := 0x05a0
}
lt(mptr, mptr_end)
{
mptr := add(mptr, 0x20)
sum_mptr := add(sum_mptr, 0x20)
}
{
mstore(mptr, mload(sum_mptr))
}
success := batch_invert(success, 0, 0xa0, r)
let r_eval := mulmod(mload(0x80), mload(0x0580), r)
for
{
let sum_inv_mptr := 0x60
let sum_inv_mptr_end := 0xa0
let r_eval_mptr := 0x0560
}
lt(sum_inv_mptr, sum_inv_mptr_end)
{
sum_inv_mptr := sub(sum_inv_mptr, 0x20)
r_eval_mptr := sub(r_eval_mptr, 0x20)
}
{
r_eval := mulmod(r_eval, mload(NU_MPTR), r)
r_eval := addmod(r_eval, mulmod(mload(sum_inv_mptr), mload(r_eval_mptr), r), r)
}
mstore(G1_SCALAR_MPTR, sub(r, r_eval))
}
{
let zeta := mload(ZETA_MPTR)
let nu := mload(NU_MPTR)
mstore(0x00, calldataload(0x06e4))
mstore(0x20, calldataload(0x0704))
success := ec_mul_acc(success, zeta)
success := ec_add_acc(success, calldataload(0x06a4), calldataload(0x06c4))
success := ec_mul_acc(success, zeta)
success := ec_add_acc(success, calldataload(0xa4), calldataload(0xc4))
success := ec_mul_acc(success, zeta)
success := ec_add_acc(success, calldataload(0x64), calldataload(0x84))
success := ec_mul_acc(success, zeta)
success := ec_add_acc(success, calldataload(0x01e4), calldataload(0x0204))
mstore(0x80, calldataload(0x0724))
mstore(0xa0, calldataload(0x0744))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(QUOTIENT_X_MPTR), mload(QUOTIENT_Y_MPTR))
for
{
let ptr := 0x11e0
let ptr_end := 0x0ce0
}
lt(ptr_end, ptr)
{ ptr := sub(ptr, 0x40) }
{
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(ptr), mload(add(ptr, 0x20)))
}
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x09e0), mload(0x0a00))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x0be0), mload(0x0c00))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x09a0), mload(0x09c0))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x0ba0), mload(0x0bc0))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x0a60), mload(0x0a80))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x0aa0), mload(0x0ac0))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x0a20), mload(0x0a40))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x0ae0), mload(0x0b00))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x0b20), mload(0x0b40))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x0b60), mload(0x0b80))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x0c60), mload(0x0c80))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x0c20), mload(0x0c40))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x0960), mload(0x0980))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x0ca0), mload(0x0cc0))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x0ce0), mload(0x0d00))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, mload(0x08e0), mload(0x0900))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x0564), calldataload(0x0584))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x01a4), calldataload(0x01c4))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x0164), calldataload(0x0184))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x0424), calldataload(0x0444))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x03a4), calldataload(0x03c4))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x0224), calldataload(0x0244))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x0264), calldataload(0x0284))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x02a4), calldataload(0x02c4))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x0324), calldataload(0x0344))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x0364), calldataload(0x0384))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x02e4), calldataload(0x0304))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x0464), calldataload(0x0484))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x04e4), calldataload(0x0504))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x0124), calldataload(0x0144))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x03e4), calldataload(0x0404))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0x04a4), calldataload(0x04c4))
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(0xe4), calldataload(0x0104))
success := ec_mul_tmp(success, mulmod(nu, mload(0x0480), r))
success := ec_add_acc(success, mload(0x80), mload(0xa0))
nu := mulmod(nu, mload(NU_MPTR), r)
mstore(0x80, calldataload(0x0664))
mstore(0xa0, calldataload(0x0684))
for
{
let ptr := 0x0624
let ptr_end := 0x0564
}
lt(ptr_end, ptr)
{ ptr := sub(ptr, 0x40) }
{
success := ec_mul_tmp(success, zeta)
success := ec_add_tmp(success, calldataload(ptr), calldataload(add(ptr, 0x20)))
}
success := ec_mul_tmp(success, mulmod(nu, mload(0x04a0), r))
success := ec_add_acc(success, mload(0x80), mload(0xa0))
nu := mulmod(nu, mload(NU_MPTR), r)
mstore(0x80, calldataload(0x0524))
mstore(0xa0, calldataload(0x0544))
success := ec_mul_tmp(success, mulmod(nu, mload(0x04c0), r))
success := ec_add_acc(success, mload(0x80), mload(0xa0))
nu := mulmod(nu, mload(NU_MPTR), r)
mstore(0x80, mload(0x0920))
mstore(0xa0, mload(0x0940))
success := ec_mul_tmp(success, mulmod(nu, mload(0x04e0), r))
success := ec_add_acc(success, mload(0x80), mload(0xa0))
mstore(0x80, mload(G1_X_MPTR))
mstore(0xa0, mload(G1_Y_MPTR))
success := ec_mul_tmp(success, mload(G1_SCALAR_MPTR))
success := ec_add_acc(success, mload(0x80), mload(0xa0))
mstore(0x80, calldataload(0x1284))
mstore(0xa0, calldataload(0x12a4))
success := ec_mul_tmp(success, sub(r, mload(0x0440)))
success := ec_add_acc(success, mload(0x80), mload(0xa0))
mstore(0x80, calldataload(0x12c4))
mstore(0xa0, calldataload(0x12e4))
success := ec_mul_tmp(success, mload(MU_MPTR))
success := ec_add_acc(success, mload(0x80), mload(0xa0))
mstore(PAIRING_LHS_X_MPTR, mload(0x00))
mstore(PAIRING_LHS_Y_MPTR, mload(0x20))
mstore(PAIRING_RHS_X_MPTR, calldataload(0x12c4))
mstore(PAIRING_RHS_Y_MPTR, calldataload(0x12e4))
}
}
// Random linear combine with accumulator
if mload(HAS_ACCUMULATOR_MPTR) {
mstore(0x00, mload(ACC_LHS_X_MPTR))
mstore(0x20, mload(ACC_LHS_Y_MPTR))
mstore(0x40, mload(ACC_RHS_X_MPTR))
mstore(0x60, mload(ACC_RHS_Y_MPTR))
mstore(0x80, mload(PAIRING_LHS_X_MPTR))
mstore(0xa0, mload(PAIRING_LHS_Y_MPTR))
mstore(0xc0, mload(PAIRING_RHS_X_MPTR))
mstore(0xe0, mload(PAIRING_RHS_Y_MPTR))
let challenge := mod(keccak256(0x00, 0x100), r)
// [pairing_lhs] += challenge * [acc_lhs]
success := ec_mul_acc(success, challenge)
success := ec_add_acc(success, mload(PAIRING_LHS_X_MPTR), mload(PAIRING_LHS_Y_MPTR))
mstore(PAIRING_LHS_X_MPTR, mload(0x00))
mstore(PAIRING_LHS_Y_MPTR, mload(0x20))
// [pairing_rhs] += challenge * [acc_rhs]
mstore(0x00, mload(ACC_RHS_X_MPTR))
mstore(0x20, mload(ACC_RHS_Y_MPTR))
success := ec_mul_acc(success, challenge)
success := ec_add_acc(success, mload(PAIRING_RHS_X_MPTR), mload(PAIRING_RHS_Y_MPTR))
mstore(PAIRING_RHS_X_MPTR, mload(0x00))
mstore(PAIRING_RHS_Y_MPTR, mload(0x20))
}
// Perform pairing
success := ec_pairing(
success,
mload(PAIRING_LHS_X_MPTR),
mload(PAIRING_LHS_Y_MPTR),
mload(PAIRING_RHS_X_MPTR),
mload(PAIRING_RHS_Y_MPTR)
)
// Revert if anything fails
if iszero(success) {
revert(0x00, 0x00)
}
// Return 1 as result if everything succeeds
mstore(0x00, 1)
return(0x00, 0x20)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment