Created
April 4, 2024 08:20
-
-
Save leonardoalt/382603dec4da0425d073ffeed9356e7c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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