From 3cf56c7f96b3581a4473c5966a2e5f39e81cd3b1 Mon Sep 17 00:00:00 2001 From: Eric Tu <6364934+ec2@users.noreply.github.com> Date: Tue, 5 Dec 2023 17:13:53 +0800 Subject: [PATCH] Fixing/Adding Prover to make it compatible with Go node (#36) * serialize ssz instead of json * config files for mainnet * update gen verifier justcommands * CLI main testnet -> mainnet * gen verifier for agg cirguit * Debugging the aggregation verifier contract failing to generate * fmt * we need to pass witness in? * un commit some configs * update contracts. NOTE: I think committee_update contract might be borked... look at the number of pubinputs * update deps * add step mainnet config * print path to pk when fails to find * mainnet agg config * update moreconfigs * attempt to get logging working * axum tracing * enable tower log * update other deps * jsonrpc logging * update jsonrpc_v2 * good kids handle errors * serialize as lowercase for consistancy * clean some deps --------- Co-authored-by: Ubuntu --- Cargo.toml | 8 +- .../committee_update_aggregated.sol | 23 +++++ .../config/committee_update_18.json | 2 +- .../config/committee_update_mainnet.json | 31 +++++++ .../config/committee_update_verifier_25.json | 22 ++--- .../committee_update_verifier_mainnet.json | 12 +++ .../config/sync_step_mainnet.json | 25 ++++++ lightclient-circuits/src/util/circuit.rs | 3 +- prover/Cargo.toml | 13 ++- prover/src/args.rs | 1 + prover/src/main.rs | 2 +- prover/src/rpc.rs | 84 ++++++++----------- 12 files changed, 154 insertions(+), 72 deletions(-) create mode 100644 contracts/snark-verifiers/committee_update_aggregated.sol create mode 100644 lightclient-circuits/config/committee_update_mainnet.json create mode 100644 lightclient-circuits/config/committee_update_verifier_mainnet.json create mode 100644 lightclient-circuits/config/sync_step_mainnet.json diff --git a/Cargo.toml b/Cargo.toml index e44c3dda..3e728886 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,16 +72,16 @@ beacon-api-client = { git = "https://github.com/ralexstokes/ethereum-consensus.g ssz_rs = "0.9" # crypto -group = "0.12" +group = "0.13" num-bigint = { version = "0.4", features = ["rand"] } -pasta_curves = "0.4.1" -ff = "0.12" +pasta_curves = "0.5.1" +ff = "0.13" sha2 = { version = "0.9", features = ["compress"] } uint = "0.9.1" ark-std = { version = "0.4.0", features = ["print-trace"] } # misc -itertools = "0.11.0" +itertools = "0.12.0" serde = { version = "1.0.130", features = ["derive"] } serde_json = "1.0.78" log = "0.4.14" diff --git a/contracts/snark-verifiers/committee_update_aggregated.sol b/contracts/snark-verifiers/committee_update_aggregated.sol new file mode 100644 index 00000000..29554b61 --- /dev/null +++ b/contracts/snark-verifiers/committee_update_aggregated.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +contract Verifier { + + /** + * @notice Bn256 P value + * @dev In order to prevent the verifier from accepting two version of the same pubInput, n and the quantity (n + P), where n + P <= 2^256, we require that all pubInputs are stricly less than P. + * @dev The reason for this is that the assmebly code of the verifier performs all arithmetic operations modulo P and as a consequence can't distinguish between n and n + P values. + */ + + uint256 constant SIZE_LIMIT = 21888242871839275222246405745257275088696311157297823662689037894645226208583; + + function verify( + uint256[1] calldata pubInputs, + bytes calldata proof + ) public view returns (bool) { + bool success = true; + bytes32[970] memory transcript; + for (uint i = 0; i < pubInputs.length; i++) { + require(pubInputs[i] < SIZE_LIMIT); + } + assembly { } { let y_square := mulmod(y, y, 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47) let x_square := mulmod(x, x, 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47) let x_cube := mulmod(x_square, x, 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47) let x_cube_plus_3 := addmod(x_cube, 3, 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47) let is_affine := eq(x_cube_plus_3, y_square) valid := and(valid, is_affine) } } mstore(0xa0, mod(calldataload(0x4), f_q))mstore(0xc0, mod(calldataload(0x64), f_q))mstore(0xe0, mod(calldataload(0x84), f_q))mstore(0x100, mod(calldataload(0xa4), f_q))mstore(0x120, mod(calldataload(0xc4), f_q))mstore(0x140, mod(calldataload(0xe4), f_q))mstore(0x160, mod(calldataload(0x104), f_q))mstore(0x180, mod(calldataload(0x124), f_q))mstore(0x1a0, mod(calldataload(0x144), f_q))mstore(0x1c0, mod(calldataload(0x164), f_q))mstore(0x1e0, mod(calldataload(0x184), f_q))mstore(0x200, mod(calldataload(0x1a4), f_q))mstore(0x220, mod(calldataload(0x1c4), f_q))mstore(0x240, mod(calldataload(0x1e4), f_q))mstore(0x260, mod(calldataload(0x204), f_q))mstore(0x280, mod(calldataload(0x224), f_q))mstore(0x2a0, mod(calldataload(0x244), f_q))mstore(0x2c0, mod(calldataload(0x264), f_q))mstore(0x2e0, mod(calldataload(0x284), f_q))mstore(0x300, mod(calldataload(0x2a4), f_q))mstore(0x320, mod(calldataload(0x2c4), f_q))mstore(0x340, mod(calldataload(0x2e4), f_q))mstore(0x360, mod(calldataload(0x304), f_q))mstore(0x380, mod(calldataload(0x324), f_q))mstore(0x3a0, mod(calldataload(0x344), f_q))mstore(0x3c0, mod(calldataload(0x364), f_q))mstore(0x3e0, mod(calldataload(0x384), f_q))mstore(0x400, mod(calldataload(0x3a4), f_q))mstore(0x420, mod(calldataload(0x3c4), f_q))mstore(0x440, mod(calldataload(0x3e4), f_q))mstore(0x460, mod(calldataload(0x404), f_q))mstore(0x480, mod(calldataload(0x424), f_q))mstore(0x4a0, mod(calldataload(0x444), f_q))mstore(0x4c0, mod(calldataload(0x464), f_q))mstore(0x4e0, mod(calldataload(0x484), f_q))mstore(0x500, mod(calldataload(0x4a4), f_q))mstore(0x520, mod(calldataload(0x4c4), f_q))mstore(0x540, mod(calldataload(0x4e4), f_q))mstore(0x560, mod(calldataload(0x504), f_q))mstore(0x580, mod(calldataload(0x524), f_q))mstore(0x5a0, mod(calldataload(0x544), f_q))mstore(0x5c0, mod(calldataload(0x564), f_q))mstore(0x5e0, mod(calldataload(0x584), f_q))mstore(0x600, mod(calldataload(0x5a4), f_q))mstore(0x620, mod(calldataload(0x5c4), f_q))mstore(0x640, mod(calldataload(0x5e4), f_q))mstore(0x660, mod(calldataload(0x604), f_q))mstore(0x680, mod(calldataload(0x624), f_q))mstore(0x6a0, mod(calldataload(0x644), f_q))mstore(0x6c0, mod(calldataload(0x664), f_q))mstore(0x6e0, mod(calldataload(0x684), f_q))mstore(0x700, mod(calldataload(0x6a4), f_q))mstore(0x720, mod(calldataload(0x6c4), f_q))mstore(0x740, mod(calldataload(0x6e4), f_q))mstore(0x760, mod(calldataload(0x704), f_q))mstore(0x780, mod(calldataload(0x724), f_q))mstore(0x7a0, mod(calldataload(0x744), f_q))mstore(0x7c0, mod(calldataload(0x764), f_q))mstore(0x7e0, mod(calldataload(0x784), f_q))mstore(0x800, mod(calldataload(0x7a4), f_q))mstore(0x820, mod(calldataload(0x7c4), f_q))mstore(0x840, mod(calldataload(0x7e4), f_q))mstore(0x860, mod(calldataload(0x804), f_q))mstore(0x880, mod(calldataload(0x824), f_q))mstore(0x8a0, mod(calldataload(0x844), f_q))mstore(0x8c0, mod(calldataload(0x864), f_q))mstore(0x8e0, mod(calldataload(0x884), f_q))mstore(0x900, mod(calldataload(0x8a4), f_q))mstore(0x920, mod(calldataload(0x8c4), f_q))mstore(0x940, mod(calldataload(0x8e4), f_q))mstore(0x960, mod(calldataload(0x904), f_q))mstore(0x980, mod(calldataload(0x924), f_q))mstore(0x9a0, mod(calldataload(0x944), f_q))mstore(0x9c0, mod(calldataload(0x964), f_q))mstore(0x9e0, mod(calldataload(0x984), f_q))mstore(0xa00, mod(calldataload(0x9a4), f_q))mstore(0xa20, mod(calldataload(0x9c4), f_q))mstore(0x80, 15186837681902097513544980734177221849855427296742621920266601528186303241061) { let x := calldataload(0x9e4) mstore(0xa40, x) let y := calldataload(0xa04) mstore(0xa60, y) success := and(validate_ec_point(x, y), success) }mstore(0xa80, keccak256(0x80, 2560)){ let hash := mload(0xa80) mstore(0xaa0, mod(hash, f_q)) mstore(0xac0, hash) } { let x := calldataload(0xa24) mstore(0xae0, x) let y := calldataload(0xa44) mstore(0xb00, y) success := and(validate_ec_point(x, y), success) } { let x := calldataload(0xa64) mstore(0xb20, x) let y := calldataload(0xa84) mstore(0xb40, y) success := and(validate_ec_point(x, y), success) }mstore(0xb60, keccak256(0xac0, 160)){ let hash := mload(0xb60) mstore(0xb80, mod(hash, f_q)) mstore(0xba0, hash) }mstore8(0xbc0, 1)mstore(0xbc0, keccak256(0xba0, 33)){ let hash := mload(0xbc0) mstore(0xbe0, mod(hash, f_q)) mstore(0xc00, hash) } { let x := calldataload(0xaa4) mstore(0xc20, x) let y := calldataload(0xac4) mstore(0xc40, y) success := and(validate_ec_point(x, y), success) } { let x := calldataload(0xae4) mstore(0xc60, x) let y := calldataload(0xb04) mstore(0xc80, y) success := and(validate_ec_point(x, y), success) } { let x := calldataload(0xb24) mstore(0xca0, x) let y := calldataload(0xb44) mstore(0xcc0, y) success := and(validate_ec_point(x, y), success) }mstore(0xce0, keccak256(0xc00, 224)){ let hash := mload(0xce0) mstore(0xd00, mod(hash, f_q)) mstore(0xd20, hash) } { let x := calldataload(0xb64) mstore(0xd40, x) let y := calldataload(0xb84) mstore(0xd60, y) success := and(validate_ec_point(x, y), success) } { let x := calldataload(0xba4) mstore(0xd80, x) let y := calldataload(0xbc4) mstore(0xda0, y) success := and(validate_ec_point(x, y), success) } { let x := calldataload(0xbe4) mstore(0xdc0, x) let y := calldataload(0xc04) mstore(0xde0, y) success := and(validate_ec_point(x, y), success) } { let x := calldataload(0xc24) mstore(0xe00, x) let y := calldataload(0xc44) mstore(0xe20, y) success := and(validate_ec_point(x, y), success) }mstore(0xe40, keccak256(0xd20, 288)){ let hash := mload(0xe40) mstore(0xe60, mod(hash, f_q)) mstore(0xe80, hash) }mstore(0xea0, mod(calldataload(0xc64), f_q))mstore(0xec0, mod(calldataload(0xc84), f_q))mstore(0xee0, mod(calldataload(0xca4), f_q))mstore(0xf00, mod(calldataload(0xcc4), f_q))mstore(0xf20, mod(calldataload(0xce4), f_q))mstore(0xf40, mod(calldataload(0xd04), f_q))mstore(0xf60, mod(calldataload(0xd24), f_q))mstore(0xf80, mod(calldataload(0xd44), f_q))mstore(0xfa0, mod(calldataload(0xd64), f_q))mstore(0xfc0, mod(calldataload(0xd84), f_q))mstore(0xfe0, mod(calldataload(0xda4), f_q))mstore(0x1000, mod(calldataload(0xdc4), f_q))mstore(0x1020, mod(calldataload(0xde4), f_q))mstore(0x1040, mod(calldataload(0xe04), f_q))mstore(0x1060, mod(calldataload(0xe24), f_q))mstore(0x1080, mod(calldataload(0xe44), f_q))mstore(0x10a0, mod(calldataload(0xe64), f_q))mstore(0x10c0, mod(calldataload(0xe84), f_q))mstore(0x10e0, mod(calldataload(0xea4), f_q))mstore(0x1100, keccak256(0xe80, 640)){ let hash := mload(0x1100) mstore(0x1120, mod(hash, f_q)) mstore(0x1140, hash) }mstore8(0x1160, 1)mstore(0x1160, keccak256(0x1140, 33)){ let hash := mload(0x1160) mstore(0x1180, mod(hash, f_q)) mstore(0x11a0, hash) } { let x := calldataload(0xec4) mstore(0x11c0, x) let y := calldataload(0xee4) mstore(0x11e0, y) success := and(validate_ec_point(x, y), success) }mstore(0x1200, keccak256(0x11a0, 96)){ let hash := mload(0x1200) mstore(0x1220, mod(hash, f_q)) mstore(0x1240, hash) } { let x := calldataload(0xf04) mstore(0x1260, x) let y := calldataload(0xf24) mstore(0x1280, y) success := and(validate_ec_point(x, y), success) }{ let x := mload(0xa0)x := add(x, shl(88, mload(0xc0)))x := add(x, shl(176, mload(0xe0)))mstore(0x12a0, x)let y := mload(0x100)y := add(y, shl(88, mload(0x120)))y := add(y, shl(176, mload(0x140)))mstore(0x12c0, y) success := and(validate_ec_point(x, y), success) }{ let x := mload(0x160)x := add(x, shl(88, mload(0x180)))x := add(x, shl(176, mload(0x1a0)))mstore(0x12e0, x)let y := mload(0x1c0)y := add(y, shl(88, mload(0x1e0)))y := add(y, shl(176, mload(0x200)))mstore(0x1300, y) success := and(validate_ec_point(x, y), success) }mstore(0x1320, mulmod(mload(0xe60), mload(0xe60), f_q))mstore(0x1340, mulmod(mload(0x1320), mload(0x1320), f_q))mstore(0x1360, mulmod(mload(0x1340), mload(0x1340), f_q))mstore(0x1380, mulmod(mload(0x1360), mload(0x1360), f_q))mstore(0x13a0, mulmod(mload(0x1380), mload(0x1380), f_q))mstore(0x13c0, mulmod(mload(0x13a0), mload(0x13a0), f_q))mstore(0x13e0, mulmod(mload(0x13c0), mload(0x13c0), f_q))mstore(0x1400, mulmod(mload(0x13e0), mload(0x13e0), f_q))mstore(0x1420, mulmod(mload(0x1400), mload(0x1400), f_q))mstore(0x1440, mulmod(mload(0x1420), mload(0x1420), f_q))mstore(0x1460, mulmod(mload(0x1440), mload(0x1440), f_q))mstore(0x1480, mulmod(mload(0x1460), mload(0x1460), f_q))mstore(0x14a0, mulmod(mload(0x1480), mload(0x1480), f_q))mstore(0x14c0, mulmod(mload(0x14a0), mload(0x14a0), f_q))mstore(0x14e0, mulmod(mload(0x14c0), mload(0x14c0), f_q))mstore(0x1500, mulmod(mload(0x14e0), mload(0x14e0), f_q))mstore(0x1520, mulmod(mload(0x1500), mload(0x1500), f_q))mstore(0x1540, mulmod(mload(0x1520), mload(0x1520), f_q))mstore(0x1560, mulmod(mload(0x1540), mload(0x1540), f_q))mstore(0x1580, mulmod(mload(0x1560), mload(0x1560), f_q))mstore(0x15a0, mulmod(mload(0x1580), mload(0x1580), f_q))mstore(0x15c0, mulmod(mload(0x15a0), mload(0x15a0), f_q))mstore(0x15e0, mulmod(mload(0x15c0), mload(0x15c0), f_q))mstore(0x1600, mulmod(mload(0x15e0), mload(0x15e0), f_q))mstore(0x1620, mulmod(mload(0x1600), mload(0x1600), f_q))mstore(0x1640, addmod(mload(0x1620), 21888242871839275222246405745257275088548364400416034343698204186575808495616, f_q))mstore(0x1660, mulmod(mload(0x1640), 21888242219518804655518433051623070663413851959604507555939307129453691614729, f_q))mstore(0x1680, mulmod(mload(0x1660), 2589924162180571669379035227311450128851046490936248479048462765733473671200, f_q))mstore(0x16a0, addmod(mload(0xe60), 19298318709658703552867370517945824959697317909479785864649741420842334824417, f_q))mstore(0x16c0, mulmod(mload(0x1660), 7358966525675286471217089135633860168646304224547606326237275077574224349359, f_q))mstore(0x16e0, addmod(mload(0xe60), 14529276346163988751029316609623414919902060175868428017460929109001584146258, f_q))mstore(0x1700, mulmod(mload(0x1660), 5723528081196465413808013109680264505774289533922470433187916976440924869204, f_q))mstore(0x1720, addmod(mload(0xe60), 16164714790642809808438392635577010582774074866493563910510287210134883626413, f_q))mstore(0x1740, mulmod(mload(0x1660), 9741553891420464328295280489650144566903017206473301385034033384879943874347, f_q))mstore(0x1760, addmod(mload(0xe60), 12146688980418810893951125255607130521645347193942732958664170801695864621270, f_q))mstore(0x1780, mulmod(mload(0x1660), 16569469942529664681363945218228869388192121720036659574609237682362097667612, f_q))mstore(0x17a0, addmod(mload(0xe60), 5318772929309610540882460527028405700356242680379374769088966504213710828005, f_q))mstore(0x17c0, mulmod(mload(0x1660), 17329448237240114492580865744088056414251735686965494637158808787419781175510, f_q))mstore(0x17e0, addmod(mload(0xe60), 4558794634599160729665540001169218674296628713450539706539395399156027320107, f_q))mstore(0x1800, mulmod(mload(0x1660), 11377606117859914088982205826922132024839443553408109299929510653283289974216, f_q))mstore(0x1820, addmod(mload(0xe60), 10510636753979361133264199918335143063708920847007925043768693533292518521401, f_q))mstore(0x1840, mulmod(mload(0x1660), 1, f_q))mstore(0x1860, addmod(mload(0xe60), 21888242871839275222246405745257275088548364400416034343698204186575808495616, f_q))mstore(0x1880, mulmod(mload(0x1660), 6143038923529407703646399695489445107254060255791852207908457597807435305312, f_q))mstore(0x18a0, addmod(mload(0xe60), 15745203948309867518600006049767829981294304144624182135789746588768373190305, f_q))mstore(0x18c0, mulmod(mload(0x1660), 11451405578697956743456240853980216273390554734748796433026540431386972584651, f_q))mstore(0x18e0, addmod(mload(0xe60), 10436837293141318478790164891277058815157809665667237910671663755188835910966, f_q))mstore(0x1900, mulmod(mload(0x1660), 16670521521732547392407716560529197273408943645332907966320731856743274895475, f_q))mstore(0x1920, addmod(mload(0xe60), 5217721350106727829838689184728077815139420755083126377377472329832533600142, f_q))mstore(0x1940, mulmod(mload(0x1660), 8374374965308410102411073611984011876711565317741801500439755773472076597347, f_q))mstore(0x1960, addmod(mload(0xe60), 13513867906530865119835332133273263211836799082674232843258448413103731898270, f_q))mstore(0x1980, mulmod(mload(0x1660), 17041886618628883845743410343041491135676788197442345444346654338941897766515, f_q))mstore(0x19a0, addmod(mload(0xe60), 4846356253210391376502995402215783952871576202973688899351549847633910729102, f_q))mstore(0x19c0, mulmod(mload(0x1660), 21490807004895109926141140246143262403290679459142140821740925192625185504522, f_q))mstore(0x19e0, addmod(mload(0xe60), 397435866944165296105265499114012685257684941273893521957278993950622991095, f_q))mstore(0x1a00, mulmod(mload(0x1660), 4947689244094276630090796471410438387704819356682144196760515917874272844658, f_q))mstore(0x1a20, addmod(mload(0xe60), 16940553627744998592155609273846836700843545043733890146937688268701535650959, f_q))mstore(0x1a40, mulmod(mload(0x1660), 11211301017135681023579411905410872569206244553457844956874280139879520583390, f_q))mstore(0x1a60, addmod(mload(0xe60), 10676941854703594198666993839846402519342119846958189386823924046696287912227, f_q))mstore(0x1a80, mulmod(mload(0x1660), 5264024894212359361117235356180248560912605977787414341366976252256241723081, f_q))mstore(0x1aa0, addmod(mload(0xe60), 16624217977626915861129170389077026527635758422628620002331227934319566772536, f_q))mstore(0x1ac0, mulmod(mload(0x1660), 18846108080730935585192484934247867403156699586319724728525857970312957475341, f_q))mstore(0x1ae0, addmod(mload(0xe60), 3042134791108339637053920811009407685391664814096309615172346216262851020276, f_q))mstore(0x1b00, mulmod(mload(0x1660), 14702679338564370535199761954906750181917994561807919001424434650417511039135, f_q))mstore(0x1b20, addmod(mload(0xe60), 7185563533274904687046643790350524906630369838608115342273769536158297456482, f_q))mstore(0x1b40, mulmod(mload(0x1660), 3615478808282855240548287271348143516886772452944084747768312988864436725401, f_q))mstore(0x1b60, addmod(mload(0xe60), 18272764063556419981698118473909131571661591947471949595929891197711371770216, f_q))mstore(0x1b80, mulmod(mload(0x1660), 20616120149426804763291284446254360562902600427757250597073510835143294097149, f_q))mstore(0x1ba0, addmod(mload(0xe60), 1272122722412470458955121299002914525645763972658783746624693351432514398468, f_q))mstore(0x1bc0, mulmod(mload(0x1660), 21451937155080765789602997556105366785934335730087568134349216848800867145453, f_q))mstore(0x1be0, addmod(mload(0xe60), 436305716758509432643408189151908302614028670328466209348987337774941350164, f_q))mstore(0x1c00, mulmod(mload(0x1660), 19017161409611545481649028523508330517390470146558499215911270929711753577772, f_q))mstore(0x1c20, addmod(mload(0xe60), 2871081462227729740597377221748944571157894253857535127786933256864054917845, f_q))mstore(0x1c40, mulmod(mload(0x1660), 1426404432721484388505361748317961535523355871255605456897797744433766488507, f_q))mstore(0x1c60, addmod(mload(0xe60), 20461838439117790833741043996939313553025008529160428886800406442142042007110, f_q))mstore(0x1c80, mulmod(mload(0x1660), 10856460699172062612938276947444161095149765964986006640875349177781443506948, f_q))mstore(0x1ca0, addmod(mload(0xe60), 11031782172667212609308128797813113993398598435430027702822855008794364988669, f_q))mstore(0x1cc0, mulmod(mload(0x1660), 13982290267294411190096162596630216412723378687553046594730793425118513274800, f_q))mstore(0x1ce0, addmod(mload(0xe60), 7905952604544864032150243148627058675824985712862987748967410761457295220817, f_q))mstore(0x1d00, mulmod(mload(0x1660), 6561173800290098519452899326025724923999000100011249967503610931251216538972, f_q))mstore(0x1d20, addmod(mload(0xe60), 15327069071549176702793506419231550164549364300404784376194593255324591956645, f_q))mstore(0x1d40, mulmod(mload(0x1660), 216092043779272773661818549620449970334216366264741118684015851799902419467, f_q))mstore(0x1d60, addmod(mload(0xe60), 21672150828060002448584587195636825118214148034151293225014188334775906076150, f_q))mstore(0x1d80, mulmod(mload(0x1660), 8339897343549661683735240707424456381152000284494796404206060322637347081841, f_q))mstore(0x1da0, addmod(mload(0xe60), 13548345528289613538511165037832818707396364115921237939492143863938461413776, f_q))mstore(0x1dc0, mulmod(mload(0x1660), 9537783784440837896026284659246718978615447564543116209283382057778110278482, f_q))mstore(0x1de0, addmod(mload(0xe60), 12350459087398437326220121086010556109932916835872918134414822128797698217135, f_q))mstore(0x1e00, mulmod(mload(0x1660), 4918863199804216794313374068541208658413103970649356533216388956233707684201, f_q))mstore(0x1e20, addmod(mload(0xe60), 16969379672035058427933031676716066430135260429766677810481815230342100811416, f_q))mstore(0x1e40, mulmod(mload(0x1660), 12619617507853212586156872920672483948819476989779550311307282715684870266992, f_q))mstore(0x1e60, addmod(mload(0xe60), 9268625363986062636089532824584791139728887410636484032390921470890938228625, f_q))mstore(0x1e80, mulmod(mload(0x1660), 7724834143148934071153960970746466069533317335090538734978957273885451415039, f_q))mstore(0x1ea0, addmod(mload(0xe60), 14163408728690341151092444774510809019015047065325495608719246912690357080578, f_q))mstore(0x1ec0, mulmod(mload(0x1660), 3947443723575973965644279767310964219908423994086470065513888332899718123222, f_q))mstore(0x1ee0, addmod(mload(0xe60), 17940799148263301256602125977946310868639940406329564278184315853676090372395, f_q))mstore(0x1f00, mulmod(mload(0x1660), 4278169934129084685243600944817585393960331423200121614669592058880339851017, f_q))mstore(0x1f20, addmod(mload(0xe60), 17610072937710190537002804800439689694588032977215912729028612127695468644600, f_q))mstore(0x1f40, mulmod(mload(0x1660), 18610195890048912503953886742825279624920778288956610528523679659246523534888, f_q))mstore(0x1f60, addmod(mload(0xe60), 3278046981790362718292519002431995463627586111459423815174524527329284960729, f_q))mstore(0x1f80, mulmod(mload(0x1660), 18650950439243380548803943501264732333660994969150820494757875443931913035538, f_q))mstore(0x1fa0, addmod(mload(0xe60), 3237292432595894673442462243992542754887369431265213848940328742643895460079, f_q))mstore(0x1fc0, mulmod(mload(0x1660), 1539082509056298927655194235755440186888826897239928178265486731666142403222, f_q))mstore(0x1fe0, addmod(mload(0xe60), 20349160362782976294591211509501834901659537503176106165432717454909666092395, f_q))mstore(0x2000, mulmod(mload(0x1660), 7201942790515709282685196242945925103656293029640288298785338889388148385095, f_q))mstore(0x2020, addmod(mload(0xe60), 14686300081323565939561209502311349984892071370775746044912865297187660110522, f_q))mstore(0x2040, mulmod(mload(0x1660), 19032961837237948602743626455740240236231119053033140765040043513661803148152, f_q))mstore(0x2060, addmod(mload(0xe60), 2855281034601326619502779289517034852317245347382893578658160672914005347465, f_q))mstore(0x2080, mulmod(mload(0x1660), 2567282239914283233897093963566444708534370585850632404740959782869832258160, f_q))mstore(0x20a0, addmod(mload(0xe60), 19320960631924991988349311781690830380013993814565401938957244403705976237457, f_q))mstore(0x20c0, mulmod(mload(0x1660), 4317410353320599552056040796202302907960891408523818766419977508859423800635, f_q))mstore(0x20e0, addmod(mload(0xe60), 17570832518518675670190364949054972180587472991892215577278226677716384694982, f_q))mstore(0x2100, mulmod(mload(0x1660), 13278633335035662196775171978256331227098467443289894350288377027124807268610, f_q))mstore(0x2120, addmod(mload(0xe60), 8609609536803613025471233767000943861449896957126139993409827159451001227007, f_q))mstore(0x2140, mulmod(mload(0x1660), 14875928112196239563830800280253496262679717528621719058794366823499719730250, f_q))mstore(0x2160, addmod(mload(0xe60), 7012314759643035658415605465003778825868646871794315284903837363076088765367, f_q))mstore(0x2180, mulmod(mload(0x1660), 19796139880566276863821462929959333991118601370893606152699382550533537294194, f_q))mstore(0x21a0, addmod(mload(0xe60), 2092102991272998358424942815297941097429763029522428190998821636042271201423, f_q))mstore(0x21c0, mulmod(mload(0x1660), 2366023502186770334390939928726871658997402416352868340984630739442624219298, f_q))mstore(0x21e0, addmod(mload(0xe60), 19522219369652504887855465816530403429550961984063166002713573447133184276319, f_q))mstore(0x2200, mulmod(mload(0x1660), 21253353101772772853143434797425538330127740258736196037595754086106342026689, f_q))mstore(0x2220, addmod(mload(0xe60), 634889770066502369102970947831736758420624141679838306102450100469466468928, f_q))mstore(0x2240, mulmod(mload(0x1660), 915149353520972163646494413843788069594022902357002628455555785223409501882, f_q))mstore(0x2260, addmod(mload(0xe60), 20973093518318303058599911331413487018954341498059031715242648401352398993735, f_q))mstore(0x2280, mulmod(mload(0x1660), 10568970125726285804117343896670014233202947662952899210242732241268902924574, f_q))mstore(0x22a0, addmod(mload(0xe60), 11319272746112989418129061848587260855345416737463135133455471945306905571043, f_q))mstore(0x22c0, mulmod(mload(0x1660), 14391499717548074167711220639833994904150450341569029103202493919171555826079, f_q))mstore(0x22e0, addmod(mload(0xe60), 7496743154291201054535185105423280184397914058847005240495710267404252669538, f_q))mstore(0x2300, mulmod(mload(0x1660), 21625474091353515468972056892507670731596366572979277269929807338991438239209, f_q))mstore(0x2320, addmod(mload(0xe60), 262768780485759753274348852749604356951997827436757073768396847584370256408, f_q))mstore(0x2340, mulmod(mload(0x1660), 5522161504810533295870699551020523636289972223872138525048055197429246400245, f_q))mstore(0x2360, addmod(mload(0xe60), 16366081367028741926375706194236751452258392176543895818650148989146562095372, f_q))mstore(0x2380, mulmod(mload(0x1660), 13460340987090708339895471217907463146299492238292355609500595215222015441425, f_q))mstore(0x23a0, addmod(mload(0xe60), 8427901884748566882350934527349811942248872162123678734197608971353793054192, f_q))mstore(0x23c0, mulmod(mload(0x1660), 10119780362642123194334092174270235809557798114544683654677907882314807212354, f_q))mstore(0x23e0, addmod(mload(0xe60), 11768462509197152027912313570987039278990566285871350689020296304261001283263, f_q))mstore(0x2400, mulmod(mload(0x1660), 17071166023700100601206475197987781457317255275364269378966936420361158573060, f_q))mstore(0x2420, addmod(mload(0xe60), 4817076848139174621039930547269493631231109125051764964731267766214649922557, f_q))mstore(0x2440, mulmod(mload(0x1660), 3766081621734395783232337525162072736827576297943013392955872170138036189193, f_q))mstore(0x2460, addmod(mload(0xe60), 18122161250104879439014068220095202351720788102473020950742332016437772306424, f_q))mstore(0x2480, mulmod(mload(0x1660), 12527559239011619672642164628594151794373299855825077281897476265823405013867, f_q))mstore(0x24a0, addmod(mload(0xe60), 9360683632827655549604241116663123294175064544590957061800727920752403481750, f_q))mstore(0x24c0, mulmod(mload(0x1660), 2080322550956715654503104356805349981348621877591103674778333538652571537127, f_q))mstore(0x24e0, addmod(mload(0xe60), 19807920320882559567743301388451925107199742522824930668919870647923236958490, f_q))mstore(0x2500, mulmod(mload(0x1660), 2628756703476154169061943895067339616982893965722790735027992440678275638809, f_q))mstore(0x2520, addmod(mload(0xe60), 19259486168363121053184461850189935471565470434693243608670211745897532856808, f_q))mstore(0x2540, mulmod(mload(0x1660), 9100833993744738801214480881117348002768153232283708533639316963648253510584, f_q))mstore(0x2560, addmod(mload(0xe60), 12787408878094536421031924864139927085780211168132325810058887222927554985033, f_q))mstore(0x2580, mulmod(mload(0x1660), 2716126075209315604595593532492318169063881707251443034813230722931138506730, f_q))mstore(0x25a0, addmod(mload(0xe60), 19172116796629959617650812212764956919484482693164591308884973463644669988887, f_q))mstore(0x25c0, mulmod(mload(0x1660), 11145214675344139457514777444556774698911688619991656085001542609383151586084, f_q))mstore(0x25e0, addmod(mload(0xe60), 10743028196495135764731628300700500389636675780424378258696661577192656909533, f_q))mstore(0x2600, mulmod(mload(0x1660), 9455661879513343744992217403146497004398519586311920696418911397370647067417, f_q))mstore(0x2620, addmod(mload(0xe60), 12432580992325931477254188342110778084149844814104113647279292789205161428200, f_q))mstore(0x2640, mulmod(mload(0x1660), 4245441013247250116003069945606352967193023389718465410501109428393342802981, f_q))mstore(0x2660, addmod(mload(0xe60), 17642801858592025106243335799650922121355341010697568933197094758182465692636, f_q))mstore(0x2680, mulmod(mload(0x1660), 8121682530053504880310722217952646955671803028092472717631336758359411770524, f_q))mstore(0x26a0, addmod(mload(0xe60), 13766560341785770341935683527304628132876561372323561626066867428216396725093, f_q))mstore(0x26c0, mulmod(mload(0x1660), 19228510170961893342195489288913594506775385223367826565223897736323409650249, f_q))mstore(0x26e0, addmod(mload(0xe60), 2659732700877381880050916456343680581772979177048207778474306450252398845368, f_q))mstore(0x2700, mulmod(mload(0x1660), 21028615043508430391966460973087822914495768542988934643007264425341826464745, f_q))mstore(0x2720, addmod(mload(0xe60), 859627828330844830279944772169452174052595857427099700690939761233982030872, f_q))mstore(0x2740, mulmod(mload(0x1660), 6132660129994545119218258312491950835441607143741804980633129304664017206141, f_q))mstore(0x2760, addmod(mload(0xe60), 15755582741844730103028147432765324253106757256674229363065074881911791289476, f_q))mstore(0x2780, mulmod(mload(0x1660), 20568413767908000563248462071403279763059526791006943936879709840333098380384, f_q))mstore(0x27a0, addmod(mload(0xe60), 1319829103931274658997943673853995325488837609409090406818494346242710115233, f_q))mstore(0x27c0, mulmod(mload(0x1660), 10094752117139066216691253588991632982053223883646966177987813353508871280747, f_q))mstore(0x27e0, addmod(mload(0xe60), 11793490754700209005555152156265642106495140516769068165710390833066937214870, f_q))mstore(0x2800, mulmod(mload(0x1660), 1412722828635353260820440480395979990287424749622479812473617828668210087992, f_q))mstore(0x2820, addmod(mload(0xe60), 20475520043203921961425965264861295098260939650793554531224586357907598407625, f_q))mstore(0x2840, mulmod(mload(0x1660), 5854133144571823792863860130267644613802765696134002830362054821530146160770, f_q))mstore(0x2860, addmod(mload(0xe60), 16034109727267451429382545614989630474745598704282031513336149365045662334847, f_q))mstore(0x2880, mulmod(mload(0x1660), 4011166062409277037846946896120088236083831265462590090132047642583670217875, f_q))mstore(0x28a0, addmod(mload(0xe60), 17877076809429998184399458849137186852464533134953444253566156543992138277742, f_q))mstore(0x28c0, mulmod(mload(0x1660), 21346203717540287263608402129024479709126363130664317843105498655869866203005, f_q))mstore(0x28e0, addmod(mload(0xe60), 542039154298987958638003616232795379422001269751716500592705530705942292612, f_q))mstore(0x2900, mulmod(mload(0x1660), 2596759765691555579319057187001626676797139380458426414819107034267851199894, f_q))mstore(0x2920, addmod(mload(0xe60), 19291483106147719642927348558255648411751225019957607928879097152307957295723, f_q))mstore(0x2940, mulmod(mload(0x1660), 515148244606945972463850631189471072103916690263705052318085725998468254533, f_q))mstore(0x2960, addmod(mload(0xe60), 21373094627232329249782555114067804016444447710152329291380118460577340241084, f_q))mstore(0x2980, mulmod(mload(0x1660), 16193474294403570471913209081172098662039194833035886085838226141251611760575, f_q))mstore(0x29a0, addmod(mload(0xe60), 5694768577435704750333196664085176426509169567380148257859978045324196735042, f_q))mstore(0x29c0, mulmod(mload(0x1660), 13788243025932779125104144225768424453664118806559109014238064020826883170336, f_q))mstore(0x29e0, addmod(mload(0xe60), 8099999845906496097142261519488850634884245593856925329460140165748925325281, f_q))mstore(0x2a00, mulmod(mload(0x1660), 12396386169390721083998741284742024397478287569179289945429941103360590919681, f_q))mstore(0x2a20, addmod(mload(0xe60), 9491856702448554138247664460515250691070076831236744398268263083215217575936, f_q))mstore(0x2a40, mulmod(mload(0x1660), 5980488956150442207659150513163747165544364597008566989111579977672498964212, f_q))mstore(0x2a60, addmod(mload(0xe60), 15907753915688833014587255232093527923003999803407467354586624208903309531405, f_q))mstore(0x2a80, mulmod(mload(0x1660), 6354421102357179089872998275128818476713799693323012459783788405734328942427, f_q))mstore(0x2aa0, addmod(mload(0xe60), 15533821769482096132373407470128456611834564707093021883914415780841479553190, f_q))mstore(0x2ac0, mulmod(mload(0x1660), 8561696234966975469289029207282849740510759316794581475824569334969644143582, f_q))mstore(0x2ae0, addmod(mload(0xe60), 13326546636872299752957376537974425348037605083621452867873634851606164352035, f_q))mstore(0x2b00, mulmod(mload(0x1660), 5397263786135457391507049168732549761126132269670746248720049083068923385507, f_q))mstore(0x2b20, addmod(mload(0xe60), 16490979085703817830739356576524725327422232130745288094978155103506885110110, f_q))mstore(0x2b40, mulmod(mload(0x1660), 5223738580615264174925218065001555728265216895679471490312087802465486318994, f_q))mstore(0x2b60, addmod(mload(0xe60), 16664504291224011047321187680255719360283147504736562853386116384110322176623, f_q)){ let prod := mload(0x16a0) prod := mulmod(mload(0x16e0), prod, f_q) mstore(0x2b80, prod) prod := mulmod(mload(0x1720), prod, f_q) mstore(0x2ba0, prod) prod := mulmod(mload(0x1760), prod, f_q) mstore(0x2bc0, prod) prod := mulmod(mload(0x17a0), prod, f_q) mstore(0x2be0, prod) prod := mulmod(mload(0x17e0), prod, f_q) mstore(0x2c00, prod) prod := mulmod(mload(0x1820), prod, f_q) mstore(0x2c20, prod) prod := mulmod(mload(0x1860), prod, f_q) mstore(0x2c40, prod) prod := mulmod(mload(0x18a0), prod, f_q) mstore(0x2c60, prod) prod := mulmod(mload(0x18e0), prod, f_q) mstore(0x2c80, prod) prod := mulmod(mload(0x1920), prod, f_q) mstore(0x2ca0, prod) prod := mulmod(mload(0x1960), prod, f_q) mstore(0x2cc0, prod) prod := mulmod(mload(0x19a0), prod, f_q) mstore(0x2ce0, prod) prod := mulmod(mload(0x19e0), prod, f_q) mstore(0x2d00, prod) prod := mulmod(mload(0x1a20), prod, f_q) mstore(0x2d20, prod) prod := mulmod(mload(0x1a60), prod, f_q) mstore(0x2d40, prod) prod := mulmod(mload(0x1aa0), prod, f_q) mstore(0x2d60, prod) prod := mulmod(mload(0x1ae0), prod, f_q) mstore(0x2d80, prod) prod := mulmod(mload(0x1b20), prod, f_q) mstore(0x2da0, prod) prod := mulmod(mload(0x1b60), prod, f_q) mstore(0x2dc0, prod) prod := mulmod(mload(0x1ba0), prod, f_q) mstore(0x2de0, prod) prod := mulmod(mload(0x1be0), prod, f_q) mstore(0x2e00, prod) prod := mulmod(mload(0x1c20), prod, f_q) mstore(0x2e20, prod) prod := mulmod(mload(0x1c60), prod, f_q) mstore(0x2e40, prod) prod := mulmod(mload(0x1ca0), prod, f_q) mstore(0x2e60, prod) prod := mulmod(mload(0x1ce0), prod, f_q) mstore(0x2e80, prod) prod := mulmod(mload(0x1d20), prod, f_q) mstore(0x2ea0, prod) prod := mulmod(mload(0x1d60), prod, f_q) mstore(0x2ec0, prod) prod := mulmod(mload(0x1da0), prod, f_q) mstore(0x2ee0, prod) prod := mulmod(mload(0x1de0), prod, f_q) mstore(0x2f00, prod) prod := mulmod(mload(0x1e20), prod, f_q) mstore(0x2f20, prod) prod := mulmod(mload(0x1e60), prod, f_q) mstore(0x2f40, prod) prod := mulmod(mload(0x1ea0), prod, f_q) mstore(0x2f60, prod) prod := mulmod(mload(0x1ee0), prod, f_q) mstore(0x2f80, prod) prod := mulmod(mload(0x1f20), prod, f_q) mstore(0x2fa0, prod) prod := mulmod(mload(0x1f60), prod, f_q) mstore(0x2fc0, prod) prod := mulmod(mload(0x1fa0), prod, f_q) mstore(0x2fe0, prod) prod := mulmod(mload(0x1fe0), prod, f_q) mstore(0x3000, prod) prod := mulmod(mload(0x2020), prod, f_q) mstore(0x3020, prod) prod := mulmod(mload(0x2060), prod, f_q) mstore(0x3040, prod) prod := mulmod(mload(0x20a0), prod, f_q) mstore(0x3060, prod) prod := mulmod(mload(0x20e0), prod, f_q) mstore(0x3080, prod) prod := mulmod(mload(0x2120), prod, f_q) mstore(0x30a0, prod) prod := mulmod(mload(0x2160), prod, f_q) mstore(0x30c0, prod) prod := mulmod(mload(0x21a0), prod, f_q) mstore(0x30e0, prod) prod := mulmod(mload(0x21e0), prod, f_q) mstore(0x3100, prod) prod := mulmod(mload(0x2220), prod, f_q) mstore(0x3120, prod) prod := mulmod(mload(0x2260), prod, f_q) mstore(0x3140, prod) prod := mulmod(mload(0x22a0), prod, f_q) mstore(0x3160, prod) prod := mulmod(mload(0x22e0), prod, f_q) mstore(0x3180, prod) prod := mulmod(mload(0x2320), prod, f_q) mstore(0x31a0, prod) prod := mulmod(mload(0x2360), prod, f_q) mstore(0x31c0, prod) prod := mulmod(mload(0x23a0), prod, f_q) mstore(0x31e0, prod) prod := mulmod(mload(0x23e0), prod, f_q) mstore(0x3200, prod) prod := mulmod(mload(0x2420), prod, f_q) mstore(0x3220, prod) prod := mulmod(mload(0x2460), prod, f_q) mstore(0x3240, prod) prod := mulmod(mload(0x24a0), prod, f_q) mstore(0x3260, prod) prod := mulmod(mload(0x24e0), prod, f_q) mstore(0x3280, prod) prod := mulmod(mload(0x2520), prod, f_q) mstore(0x32a0, prod) prod := mulmod(mload(0x2560), prod, f_q) mstore(0x32c0, prod) prod := mulmod(mload(0x25a0), prod, f_q) mstore(0x32e0, prod) prod := mulmod(mload(0x25e0), prod, f_q) mstore(0x3300, prod) prod := mulmod(mload(0x2620), prod, f_q) mstore(0x3320, prod) prod := mulmod(mload(0x2660), prod, f_q) mstore(0x3340, prod) prod := mulmod(mload(0x26a0), prod, f_q) mstore(0x3360, prod) prod := mulmod(mload(0x26e0), prod, f_q) mstore(0x3380, prod) prod := mulmod(mload(0x2720), prod, f_q) mstore(0x33a0, prod) prod := mulmod(mload(0x2760), prod, f_q) mstore(0x33c0, prod) prod := mulmod(mload(0x27a0), prod, f_q) mstore(0x33e0, prod) prod := mulmod(mload(0x27e0), prod, f_q) mstore(0x3400, prod) prod := mulmod(mload(0x2820), prod, f_q) mstore(0x3420, prod) prod := mulmod(mload(0x2860), prod, f_q) mstore(0x3440, prod) prod := mulmod(mload(0x28a0), prod, f_q) mstore(0x3460, prod) prod := mulmod(mload(0x28e0), prod, f_q) mstore(0x3480, prod) prod := mulmod(mload(0x2920), prod, f_q) mstore(0x34a0, prod) prod := mulmod(mload(0x2960), prod, f_q) mstore(0x34c0, prod) prod := mulmod(mload(0x29a0), prod, f_q) mstore(0x34e0, prod) prod := mulmod(mload(0x29e0), prod, f_q) mstore(0x3500, prod) prod := mulmod(mload(0x2a20), prod, f_q) mstore(0x3520, prod) prod := mulmod(mload(0x2a60), prod, f_q) mstore(0x3540, prod) prod := mulmod(mload(0x2aa0), prod, f_q) mstore(0x3560, prod) prod := mulmod(mload(0x2ae0), prod, f_q) mstore(0x3580, prod) prod := mulmod(mload(0x2b20), prod, f_q) mstore(0x35a0, prod) prod := mulmod(mload(0x2b60), prod, f_q) mstore(0x35c0, prod) prod := mulmod(mload(0x1640), prod, f_q) mstore(0x35e0, prod) }mstore(0x3620, 32)mstore(0x3640, 32)mstore(0x3660, 32)mstore(0x3680, mload(0x35e0))mstore(0x36a0, 21888242871839275222246405745257275088548364400416034343698204186575808495615)mstore(0x36c0, 21888242871839275222246405745257275088548364400416034343698204186575808495617)success := and(eq(staticcall(gas(), 0x5, 0x3620, 0xc0, 0x3600, 0x20), 1), success){ let inv := mload(0x3600) let v v := mload(0x1640) mstore(0x1640, mulmod(mload(0x35c0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2b60) mstore(0x2b60, mulmod(mload(0x35a0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2b20) mstore(0x2b20, mulmod(mload(0x3580), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2ae0) mstore(0x2ae0, mulmod(mload(0x3560), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2aa0) mstore(0x2aa0, mulmod(mload(0x3540), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2a60) mstore(0x2a60, mulmod(mload(0x3520), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2a20) mstore(0x2a20, mulmod(mload(0x3500), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x29e0) mstore(0x29e0, mulmod(mload(0x34e0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x29a0) mstore(0x29a0, mulmod(mload(0x34c0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2960) mstore(0x2960, mulmod(mload(0x34a0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2920) mstore(0x2920, mulmod(mload(0x3480), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x28e0) mstore(0x28e0, mulmod(mload(0x3460), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x28a0) mstore(0x28a0, mulmod(mload(0x3440), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2860) mstore(0x2860, mulmod(mload(0x3420), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2820) mstore(0x2820, mulmod(mload(0x3400), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x27e0) mstore(0x27e0, mulmod(mload(0x33e0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x27a0) mstore(0x27a0, mulmod(mload(0x33c0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2760) mstore(0x2760, mulmod(mload(0x33a0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2720) mstore(0x2720, mulmod(mload(0x3380), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x26e0) mstore(0x26e0, mulmod(mload(0x3360), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x26a0) mstore(0x26a0, mulmod(mload(0x3340), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2660) mstore(0x2660, mulmod(mload(0x3320), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2620) mstore(0x2620, mulmod(mload(0x3300), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x25e0) mstore(0x25e0, mulmod(mload(0x32e0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x25a0) mstore(0x25a0, mulmod(mload(0x32c0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2560) mstore(0x2560, mulmod(mload(0x32a0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2520) mstore(0x2520, mulmod(mload(0x3280), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x24e0) mstore(0x24e0, mulmod(mload(0x3260), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x24a0) mstore(0x24a0, mulmod(mload(0x3240), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2460) mstore(0x2460, mulmod(mload(0x3220), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2420) mstore(0x2420, mulmod(mload(0x3200), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x23e0) mstore(0x23e0, mulmod(mload(0x31e0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x23a0) mstore(0x23a0, mulmod(mload(0x31c0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2360) mstore(0x2360, mulmod(mload(0x31a0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2320) mstore(0x2320, mulmod(mload(0x3180), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x22e0) mstore(0x22e0, mulmod(mload(0x3160), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x22a0) mstore(0x22a0, mulmod(mload(0x3140), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2260) mstore(0x2260, mulmod(mload(0x3120), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2220) mstore(0x2220, mulmod(mload(0x3100), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x21e0) mstore(0x21e0, mulmod(mload(0x30e0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x21a0) mstore(0x21a0, mulmod(mload(0x30c0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2160) mstore(0x2160, mulmod(mload(0x30a0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2120) mstore(0x2120, mulmod(mload(0x3080), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x20e0) mstore(0x20e0, mulmod(mload(0x3060), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x20a0) mstore(0x20a0, mulmod(mload(0x3040), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2060) mstore(0x2060, mulmod(mload(0x3020), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x2020) mstore(0x2020, mulmod(mload(0x3000), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1fe0) mstore(0x1fe0, mulmod(mload(0x2fe0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1fa0) mstore(0x1fa0, mulmod(mload(0x2fc0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1f60) mstore(0x1f60, mulmod(mload(0x2fa0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1f20) mstore(0x1f20, mulmod(mload(0x2f80), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1ee0) mstore(0x1ee0, mulmod(mload(0x2f60), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1ea0) mstore(0x1ea0, mulmod(mload(0x2f40), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1e60) mstore(0x1e60, mulmod(mload(0x2f20), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1e20) mstore(0x1e20, mulmod(mload(0x2f00), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1de0) mstore(0x1de0, mulmod(mload(0x2ee0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1da0) mstore(0x1da0, mulmod(mload(0x2ec0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1d60) mstore(0x1d60, mulmod(mload(0x2ea0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1d20) mstore(0x1d20, mulmod(mload(0x2e80), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1ce0) mstore(0x1ce0, mulmod(mload(0x2e60), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1ca0) mstore(0x1ca0, mulmod(mload(0x2e40), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1c60) mstore(0x1c60, mulmod(mload(0x2e20), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1c20) mstore(0x1c20, mulmod(mload(0x2e00), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1be0) mstore(0x1be0, mulmod(mload(0x2de0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1ba0) mstore(0x1ba0, mulmod(mload(0x2dc0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1b60) mstore(0x1b60, mulmod(mload(0x2da0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1b20) mstore(0x1b20, mulmod(mload(0x2d80), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1ae0) mstore(0x1ae0, mulmod(mload(0x2d60), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1aa0) mstore(0x1aa0, mulmod(mload(0x2d40), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1a60) mstore(0x1a60, mulmod(mload(0x2d20), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1a20) mstore(0x1a20, mulmod(mload(0x2d00), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x19e0) mstore(0x19e0, mulmod(mload(0x2ce0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x19a0) mstore(0x19a0, mulmod(mload(0x2cc0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1960) mstore(0x1960, mulmod(mload(0x2ca0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1920) mstore(0x1920, mulmod(mload(0x2c80), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x18e0) mstore(0x18e0, mulmod(mload(0x2c60), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x18a0) mstore(0x18a0, mulmod(mload(0x2c40), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1860) mstore(0x1860, mulmod(mload(0x2c20), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1820) mstore(0x1820, mulmod(mload(0x2c00), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x17e0) mstore(0x17e0, mulmod(mload(0x2be0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x17a0) mstore(0x17a0, mulmod(mload(0x2bc0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1760) mstore(0x1760, mulmod(mload(0x2ba0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x1720) mstore(0x1720, mulmod(mload(0x2b80), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x16e0) mstore(0x16e0, mulmod(mload(0x16a0), inv, f_q)) inv := mulmod(v, inv, f_q) mstore(0x16a0, inv) }mstore(0x36e0, mulmod(mload(0x1680), mload(0x16a0), f_q))mstore(0x3700, mulmod(mload(0x16c0), mload(0x16e0), f_q))mstore(0x3720, mulmod(mload(0x1700), mload(0x1720), f_q))mstore(0x3740, mulmod(mload(0x1740), mload(0x1760), f_q))mstore(0x3760, mulmod(mload(0x1780), mload(0x17a0), f_q))mstore(0x3780, mulmod(mload(0x17c0), mload(0x17e0), f_q))mstore(0x37a0, mulmod(mload(0x1800), mload(0x1820), f_q))mstore(0x37c0, mulmod(mload(0x1840), mload(0x1860), f_q))mstore(0x37e0, mulmod(mload(0x1880), mload(0x18a0), f_q))mstore(0x3800, mulmod(mload(0x18c0), mload(0x18e0), f_q))mstore(0x3820, mulmod(mload(0x1900), mload(0x1920), f_q))mstore(0x3840, mulmod(mload(0x1940), mload(0x1960), f_q))mstore(0x3860, mulmod(mload(0x1980), mload(0x19a0), f_q))mstore(0x3880, mulmod(mload(0x19c0), mload(0x19e0), f_q))mstore(0x38a0, mulmod(mload(0x1a00), mload(0x1a20), f_q))mstore(0x38c0, mulmod(mload(0x1a40), mload(0x1a60), f_q))mstore(0x38e0, mulmod(mload(0x1a80), mload(0x1aa0), f_q))mstore(0x3900, mulmod(mload(0x1ac0), mload(0x1ae0), f_q))mstore(0x3920, mulmod(mload(0x1b00), mload(0x1b20), f_q))mstore(0x3940, mulmod(mload(0x1b40), mload(0x1b60), f_q))mstore(0x3960, mulmod(mload(0x1b80), mload(0x1ba0), f_q))mstore(0x3980, mulmod(mload(0x1bc0), mload(0x1be0), f_q))mstore(0x39a0, mulmod(mload(0x1c00), mload(0x1c20), f_q))mstore(0x39c0, mulmod(mload(0x1c40), mload(0x1c60), f_q))mstore(0x39e0, mulmod(mload(0x1c80), mload(0x1ca0), f_q))mstore(0x3a00, mulmod(mload(0x1cc0), mload(0x1ce0), f_q))mstore(0x3a20, mulmod(mload(0x1d00), mload(0x1d20), f_q))mstore(0x3a40, mulmod(mload(0x1d40), mload(0x1d60), f_q))mstore(0x3a60, mulmod(mload(0x1d80), mload(0x1da0), f_q))mstore(0x3a80, mulmod(mload(0x1dc0), mload(0x1de0), f_q))mstore(0x3aa0, mulmod(mload(0x1e00), mload(0x1e20), f_q))mstore(0x3ac0, mulmod(mload(0x1e40), mload(0x1e60), f_q))mstore(0x3ae0, mulmod(mload(0x1e80), mload(0x1ea0), f_q))mstore(0x3b00, mulmod(mload(0x1ec0), mload(0x1ee0), f_q))mstore(0x3b20, mulmod(mload(0x1f00), mload(0x1f20), f_q))mstore(0x3b40, mulmod(mload(0x1f40), mload(0x1f60), f_q))mstore(0x3b60, mulmod(mload(0x1f80), mload(0x1fa0), f_q))mstore(0x3b80, mulmod(mload(0x1fc0), mload(0x1fe0), f_q))mstore(0x3ba0, mulmod(mload(0x2000), mload(0x2020), f_q))mstore(0x3bc0, mulmod(mload(0x2040), mload(0x2060), f_q))mstore(0x3be0, mulmod(mload(0x2080), mload(0x20a0), f_q))mstore(0x3c00, mulmod(mload(0x20c0), mload(0x20e0), f_q))mstore(0x3c20, mulmod(mload(0x2100), mload(0x2120), f_q))mstore(0x3c40, mulmod(mload(0x2140), mload(0x2160), f_q))mstore(0x3c60, mulmod(mload(0x2180), mload(0x21a0), f_q))mstore(0x3c80, mulmod(mload(0x21c0), mload(0x21e0), f_q))mstore(0x3ca0, mulmod(mload(0x2200), mload(0x2220), f_q))mstore(0x3cc0, mulmod(mload(0x2240), mload(0x2260), f_q))mstore(0x3ce0, mulmod(mload(0x2280), mload(0x22a0), f_q))mstore(0x3d00, mulmod(mload(0x22c0), mload(0x22e0), f_q))mstore(0x3d20, mulmod(mload(0x2300), mload(0x2320), f_q))mstore(0x3d40, mulmod(mload(0x2340), mload(0x2360), f_q))mstore(0x3d60, mulmod(mload(0x2380), mload(0x23a0), f_q))mstore(0x3d80, mulmod(mload(0x23c0), mload(0x23e0), f_q))mstore(0x3da0, mulmod(mload(0x2400), mload(0x2420), f_q))mstore(0x3dc0, mulmod(mload(0x2440), mload(0x2460), f_q))mstore(0x3de0, mulmod(mload(0x2480), mload(0x24a0), f_q))mstore(0x3e00, mulmod(mload(0x24c0), mload(0x24e0), f_q))mstore(0x3e20, mulmod(mload(0x2500), mload(0x2520), f_q))mstore(0x3e40, mulmod(mload(0x2540), mload(0x2560), f_q))mstore(0x3e60, mulmod(mload(0x2580), mload(0x25a0), f_q))mstore(0x3e80, mulmod(mload(0x25c0), mload(0x25e0), f_q))mstore(0x3ea0, mulmod(mload(0x2600), mload(0x2620), f_q))mstore(0x3ec0, mulmod(mload(0x2640), mload(0x2660), f_q))mstore(0x3ee0, mulmod(mload(0x2680), mload(0x26a0), f_q))mstore(0x3f00, mulmod(mload(0x26c0), mload(0x26e0), f_q))mstore(0x3f20, mulmod(mload(0x2700), mload(0x2720), f_q))mstore(0x3f40, mulmod(mload(0x2740), mload(0x2760), f_q))mstore(0x3f60, mulmod(mload(0x2780), mload(0x27a0), f_q))mstore(0x3f80, mulmod(mload(0x27c0), mload(0x27e0), f_q))mstore(0x3fa0, mulmod(mload(0x2800), mload(0x2820), f_q))mstore(0x3fc0, mulmod(mload(0x2840), mload(0x2860), f_q))mstore(0x3fe0, mulmod(mload(0x2880), mload(0x28a0), f_q))mstore(0x4000, mulmod(mload(0x28c0), mload(0x28e0), f_q))mstore(0x4020, mulmod(mload(0x2900), mload(0x2920), f_q))mstore(0x4040, mulmod(mload(0x2940), mload(0x2960), f_q))mstore(0x4060, mulmod(mload(0x2980), mload(0x29a0), f_q))mstore(0x4080, mulmod(mload(0x29c0), mload(0x29e0), f_q))mstore(0x40a0, mulmod(mload(0x2a00), mload(0x2a20), f_q))mstore(0x40c0, mulmod(mload(0x2a40), mload(0x2a60), f_q))mstore(0x40e0, mulmod(mload(0x2a80), mload(0x2aa0), f_q))mstore(0x4100, mulmod(mload(0x2ac0), mload(0x2ae0), f_q))mstore(0x4120, mulmod(mload(0x2b00), mload(0x2b20), f_q))mstore(0x4140, mulmod(mload(0x2b40), mload(0x2b60), f_q)){ let result := mulmod(mload(0x37c0), mload(0xa0), f_q)result := addmod(mulmod(mload(0x37e0), mload(0xc0), f_q), result, f_q)result := addmod(mulmod(mload(0x3800), mload(0xe0), f_q), result, f_q)result := addmod(mulmod(mload(0x3820), mload(0x100), f_q), result, f_q)result := addmod(mulmod(mload(0x3840), mload(0x120), f_q), result, f_q)result := addmod(mulmod(mload(0x3860), mload(0x140), f_q), result, f_q)result := addmod(mulmod(mload(0x3880), mload(0x160), f_q), result, f_q)result := addmod(mulmod(mload(0x38a0), mload(0x180), f_q), result, f_q)result := addmod(mulmod(mload(0x38c0), mload(0x1a0), f_q), result, f_q)result := addmod(mulmod(mload(0x38e0), mload(0x1c0), f_q), result, f_q)result := addmod(mulmod(mload(0x3900), mload(0x1e0), f_q), result, f_q)result := addmod(mulmod(mload(0x3920), mload(0x200), f_q), result, f_q)result := addmod(mulmod(mload(0x3940), mload(0x220), f_q), result, f_q)result := addmod(mulmod(mload(0x3960), mload(0x240), f_q), result, f_q)result := addmod(mulmod(mload(0x3980), mload(0x260), f_q), result, f_q)result := addmod(mulmod(mload(0x39a0), mload(0x280), f_q), result, f_q)result := addmod(mulmod(mload(0x39c0), mload(0x2a0), f_q), result, f_q)result := addmod(mulmod(mload(0x39e0), mload(0x2c0), f_q), result, f_q)result := addmod(mulmod(mload(0x3a00), mload(0x2e0), f_q), result, f_q)result := addmod(mulmod(mload(0x3a20), mload(0x300), f_q), result, f_q)result := addmod(mulmod(mload(0x3a40), mload(0x320), f_q), result, f_q)result := addmod(mulmod(mload(0x3a60), mload(0x340), f_q), result, f_q)result := addmod(mulmod(mload(0x3a80), mload(0x360), f_q), result, f_q)result := addmod(mulmod(mload(0x3aa0), mload(0x380), f_q), result, f_q)result := addmod(mulmod(mload(0x3ac0), mload(0x3a0), f_q), result, f_q)result := addmod(mulmod(mload(0x3ae0), mload(0x3c0), f_q), result, f_q)result := addmod(mulmod(mload(0x3b00), mload(0x3e0), f_q), result, f_q)result := addmod(mulmod(mload(0x3b20), mload(0x400), f_q), result, f_q)result := addmod(mulmod(mload(0x3b40), mload(0x420), f_q), result, f_q)result := addmod(mulmod(mload(0x3b60), mload(0x440), f_q), result, f_q)result := addmod(mulmod(mload(0x3b80), mload(0x460), f_q), result, f_q)result := addmod(mulmod(mload(0x3ba0), mload(0x480), f_q), result, f_q)result := addmod(mulmod(mload(0x3bc0), mload(0x4a0), f_q), result, f_q)result := addmod(mulmod(mload(0x3be0), mload(0x4c0), f_q), result, f_q)result := addmod(mulmod(mload(0x3c00), mload(0x4e0), f_q), result, f_q)result := addmod(mulmod(mload(0x3c20), mload(0x500), f_q), result, f_q)result := addmod(mulmod(mload(0x3c40), mload(0x520), f_q), result, f_q)result := addmod(mulmod(mload(0x3c60), mload(0x540), f_q), result, f_q)result := addmod(mulmod(mload(0x3c80), mload(0x560), f_q), result, f_q)result := addmod(mulmod(mload(0x3ca0), mload(0x580), f_q), result, f_q)result := addmod(mulmod(mload(0x3cc0), mload(0x5a0), f_q), result, f_q)result := addmod(mulmod(mload(0x3ce0), mload(0x5c0), f_q), result, f_q)result := addmod(mulmod(mload(0x3d00), mload(0x5e0), f_q), result, f_q)result := addmod(mulmod(mload(0x3d20), mload(0x600), f_q), result, f_q)result := addmod(mulmod(mload(0x3d40), mload(0x620), f_q), result, f_q)result := addmod(mulmod(mload(0x3d60), mload(0x640), f_q), result, f_q)result := addmod(mulmod(mload(0x3d80), mload(0x660), f_q), result, f_q)result := addmod(mulmod(mload(0x3da0), mload(0x680), f_q), result, f_q)result := addmod(mulmod(mload(0x3dc0), mload(0x6a0), f_q), result, f_q)result := addmod(mulmod(mload(0x3de0), mload(0x6c0), f_q), result, f_q)result := addmod(mulmod(mload(0x3e00), mload(0x6e0), f_q), result, f_q)result := addmod(mulmod(mload(0x3e20), mload(0x700), f_q), result, f_q)result := addmod(mulmod(mload(0x3e40), mload(0x720), f_q), result, f_q)result := addmod(mulmod(mload(0x3e60), mload(0x740), f_q), result, f_q)result := addmod(mulmod(mload(0x3e80), mload(0x760), f_q), result, f_q)result := addmod(mulmod(mload(0x3ea0), mload(0x780), f_q), result, f_q)result := addmod(mulmod(mload(0x3ec0), mload(0x7a0), f_q), result, f_q)result := addmod(mulmod(mload(0x3ee0), mload(0x7c0), f_q), result, f_q)result := addmod(mulmod(mload(0x3f00), mload(0x7e0), f_q), result, f_q)result := addmod(mulmod(mload(0x3f20), mload(0x800), f_q), result, f_q)result := addmod(mulmod(mload(0x3f40), mload(0x820), f_q), result, f_q)result := addmod(mulmod(mload(0x3f60), mload(0x840), f_q), result, f_q)result := addmod(mulmod(mload(0x3f80), mload(0x860), f_q), result, f_q)result := addmod(mulmod(mload(0x3fa0), mload(0x880), f_q), result, f_q)result := addmod(mulmod(mload(0x3fc0), mload(0x8a0), f_q), result, f_q)result := addmod(mulmod(mload(0x3fe0), mload(0x8c0), f_q), result, f_q)result := addmod(mulmod(mload(0x4000), mload(0x8e0), f_q), result, f_q)result := addmod(mulmod(mload(0x4020), mload(0x900), f_q), result, f_q)result := addmod(mulmod(mload(0x4040), mload(0x920), f_q), result, f_q)result := addmod(mulmod(mload(0x4060), mload(0x940), f_q), result, f_q)result := addmod(mulmod(mload(0x4080), mload(0x960), f_q), result, f_q)result := addmod(mulmod(mload(0x40a0), mload(0x980), f_q), result, f_q)result := addmod(mulmod(mload(0x40c0), mload(0x9a0), f_q), result, f_q)result := addmod(mulmod(mload(0x40e0), mload(0x9c0), f_q), result, f_q)result := addmod(mulmod(mload(0x4100), mload(0x9e0), f_q), result, f_q)result := addmod(mulmod(mload(0x4120), mload(0xa00), f_q), result, f_q)result := addmod(mulmod(mload(0x4140), mload(0xa20), f_q), result, f_q)mstore(0x4160, result) }mstore(0x4180, mulmod(mload(0xee0), mload(0xec0), f_q))mstore(0x41a0, addmod(mload(0xea0), mload(0x4180), f_q))mstore(0x41c0, addmod(mload(0x41a0), sub(f_q, mload(0xf00)), f_q))mstore(0x41e0, mulmod(mload(0x41c0), mload(0xf80), f_q))mstore(0x4200, mulmod(mload(0xd00), mload(0x41e0), f_q))mstore(0x4220, addmod(1, sub(f_q, mload(0x1020)), f_q))mstore(0x4240, mulmod(mload(0x4220), mload(0x37c0), f_q))mstore(0x4260, addmod(mload(0x4200), mload(0x4240), f_q))mstore(0x4280, mulmod(mload(0xd00), mload(0x4260), f_q))mstore(0x42a0, mulmod(mload(0x1020), mload(0x1020), f_q))mstore(0x42c0, addmod(mload(0x42a0), sub(f_q, mload(0x1020)), f_q))mstore(0x42e0, mulmod(mload(0x42c0), mload(0x36e0), f_q))mstore(0x4300, addmod(mload(0x4280), mload(0x42e0), f_q))mstore(0x4320, mulmod(mload(0xd00), mload(0x4300), f_q))mstore(0x4340, addmod(1, sub(f_q, mload(0x36e0)), f_q))mstore(0x4360, addmod(mload(0x3700), mload(0x3720), f_q))mstore(0x4380, addmod(mload(0x4360), mload(0x3740), f_q))mstore(0x43a0, addmod(mload(0x4380), mload(0x3760), f_q))mstore(0x43c0, addmod(mload(0x43a0), mload(0x3780), f_q))mstore(0x43e0, addmod(mload(0x43c0), mload(0x37a0), f_q))mstore(0x4400, addmod(mload(0x4340), sub(f_q, mload(0x43e0)), f_q))mstore(0x4420, mulmod(mload(0xfc0), mload(0xb80), f_q))mstore(0x4440, addmod(mload(0xf20), mload(0x4420), f_q))mstore(0x4460, addmod(mload(0x4440), mload(0xbe0), f_q))mstore(0x4480, mulmod(mload(0xfe0), mload(0xb80), f_q))mstore(0x44a0, addmod(mload(0xea0), mload(0x4480), f_q))mstore(0x44c0, addmod(mload(0x44a0), mload(0xbe0), f_q))mstore(0x44e0, mulmod(mload(0x44c0), mload(0x4460), f_q))mstore(0x4500, mulmod(mload(0x1000), mload(0xb80), f_q))mstore(0x4520, addmod(mload(0x4160), mload(0x4500), f_q))mstore(0x4540, addmod(mload(0x4520), mload(0xbe0), f_q))mstore(0x4560, mulmod(mload(0x4540), mload(0x44e0), f_q))mstore(0x4580, mulmod(mload(0x4560), mload(0x1040), f_q))mstore(0x45a0, mulmod(1, mload(0xb80), f_q))mstore(0x45c0, mulmod(mload(0xe60), mload(0x45a0), f_q))mstore(0x45e0, addmod(mload(0xf20), mload(0x45c0), f_q))mstore(0x4600, addmod(mload(0x45e0), mload(0xbe0), f_q))mstore(0x4620, mulmod(4131629893567559867359510883348571134090853742863529169391034518566172092834, mload(0xb80), f_q))mstore(0x4640, mulmod(mload(0xe60), mload(0x4620), f_q))mstore(0x4660, addmod(mload(0xea0), mload(0x4640), f_q))mstore(0x4680, addmod(mload(0x4660), mload(0xbe0), f_q))mstore(0x46a0, mulmod(mload(0x4680), mload(0x4600), f_q))mstore(0x46c0, mulmod(8910878055287538404433155982483128285667088683464058436815641868457422632747, mload(0xb80), f_q))mstore(0x46e0, mulmod(mload(0xe60), mload(0x46c0), f_q))mstore(0x4700, addmod(mload(0x4160), mload(0x46e0), f_q))mstore(0x4720, addmod(mload(0x4700), mload(0xbe0), f_q))mstore(0x4740, mulmod(mload(0x4720), mload(0x46a0), f_q))mstore(0x4760, mulmod(mload(0x4740), mload(0x1020), f_q))mstore(0x4780, addmod(mload(0x4580), sub(f_q, mload(0x4760)), f_q))mstore(0x47a0, mulmod(mload(0x4780), mload(0x4400), f_q))mstore(0x47c0, addmod(mload(0x4320), mload(0x47a0), f_q))mstore(0x47e0, mulmod(mload(0xd00), mload(0x47c0), f_q))mstore(0x4800, addmod(1, sub(f_q, mload(0x1060)), f_q))mstore(0x4820, mulmod(mload(0x4800), mload(0x37c0), f_q))mstore(0x4840, addmod(mload(0x47e0), mload(0x4820), f_q))mstore(0x4860, mulmod(mload(0xd00), mload(0x4840), f_q))mstore(0x4880, mulmod(mload(0x1060), mload(0x1060), f_q))mstore(0x48a0, addmod(mload(0x4880), sub(f_q, mload(0x1060)), f_q))mstore(0x48c0, mulmod(mload(0x48a0), mload(0x36e0), f_q))mstore(0x48e0, addmod(mload(0x4860), mload(0x48c0), f_q))mstore(0x4900, mulmod(mload(0xd00), mload(0x48e0), f_q))mstore(0x4920, addmod(mload(0x10a0), mload(0xb80), f_q))mstore(0x4940, mulmod(mload(0x4920), mload(0x1080), f_q))mstore(0x4960, addmod(mload(0x10e0), mload(0xbe0), f_q))mstore(0x4980, mulmod(mload(0x4960), mload(0x4940), f_q))mstore(0x49a0, mulmod(mload(0xea0), mload(0xf60), f_q))mstore(0x49c0, addmod(mload(0x49a0), mload(0xb80), f_q))mstore(0x49e0, mulmod(mload(0x49c0), mload(0x1060), f_q))mstore(0x4a00, addmod(mload(0xf40), mload(0xbe0), f_q))mstore(0x4a20, mulmod(mload(0x4a00), mload(0x49e0), f_q))mstore(0x4a40, addmod(mload(0x4980), sub(f_q, mload(0x4a20)), f_q))mstore(0x4a60, mulmod(mload(0x4a40), mload(0x4400), f_q))mstore(0x4a80, addmod(mload(0x4900), mload(0x4a60), f_q))mstore(0x4aa0, mulmod(mload(0xd00), mload(0x4a80), f_q))mstore(0x4ac0, addmod(mload(0x10a0), sub(f_q, mload(0x10e0)), f_q))mstore(0x4ae0, mulmod(mload(0x4ac0), mload(0x37c0), f_q))mstore(0x4b00, addmod(mload(0x4aa0), mload(0x4ae0), f_q))mstore(0x4b20, mulmod(mload(0xd00), mload(0x4b00), f_q))mstore(0x4b40, mulmod(mload(0x4ac0), mload(0x4400), f_q))mstore(0x4b60, addmod(mload(0x10a0), sub(f_q, mload(0x10c0)), f_q))mstore(0x4b80, mulmod(mload(0x4b60), mload(0x4b40), f_q))mstore(0x4ba0, addmod(mload(0x4b20), mload(0x4b80), f_q))mstore(0x4bc0, mulmod(mload(0x1620), mload(0x1620), f_q))mstore(0x4be0, mulmod(mload(0x4bc0), mload(0x1620), f_q))mstore(0x4c00, mulmod(mload(0x4be0), mload(0x1620), f_q))mstore(0x4c20, mulmod(1, mload(0x1620), f_q))mstore(0x4c40, mulmod(1, mload(0x4bc0), f_q))mstore(0x4c60, mulmod(1, mload(0x4be0), f_q))mstore(0x4c80, mulmod(mload(0x4ba0), mload(0x1640), f_q))mstore(0x4ca0, mulmod(mload(0x1320), mload(0xe60), f_q))mstore(0x4cc0, mulmod(mload(0x4ca0), mload(0xe60), f_q))mstore(0x4ce0, mulmod(mload(0xe60), 11377606117859914088982205826922132024839443553408109299929510653283289974216, f_q))mstore(0x4d00, addmod(mload(0x1220), sub(f_q, mload(0x4ce0)), f_q))mstore(0x4d20, mulmod(mload(0xe60), 1, f_q))mstore(0x4d40, addmod(mload(0x1220), sub(f_q, mload(0x4d20)), f_q))mstore(0x4d60, mulmod(mload(0xe60), 6143038923529407703646399695489445107254060255791852207908457597807435305312, f_q))mstore(0x4d80, addmod(mload(0x1220), sub(f_q, mload(0x4d60)), f_q))mstore(0x4da0, mulmod(mload(0xe60), 11451405578697956743456240853980216273390554734748796433026540431386972584651, f_q))mstore(0x4dc0, addmod(mload(0x1220), sub(f_q, mload(0x4da0)), f_q))mstore(0x4de0, mulmod(mload(0xe60), 16670521521732547392407716560529197273408943645332907966320731856743274895475, f_q))mstore(0x4e00, addmod(mload(0x1220), sub(f_q, mload(0x4de0)), f_q))mstore(0x4e20, mulmod(8219252948654094797157108904669854317001423465917391825808691077170189464995, mload(0x4ca0), f_q))mstore(0x4e40, mulmod(mload(0x4e20), 1, f_q)){ let result := mulmod(mload(0x1220), mload(0x4e20), f_q)result := addmod(mulmod(mload(0xe60), sub(f_q, mload(0x4e40)), f_q), result, f_q)mstore(0x4e60, result) }mstore(0x4e80, mulmod(9296671232404480276013511827138458405364435620174469432662539796840967177791, mload(0x4ca0), f_q))mstore(0x4ea0, mulmod(mload(0x4e80), 6143038923529407703646399695489445107254060255791852207908457597807435305312, f_q)){ let result := mulmod(mload(0x1220), mload(0x4e80), f_q)result := addmod(mulmod(mload(0xe60), sub(f_q, mload(0x4ea0)), f_q), result, f_q)mstore(0x4ec0, result) }mstore(0x4ee0, mulmod(16067453484972395187530647612179984850313988171035408068464350590599411369550, mload(0x4ca0), f_q))mstore(0x4f00, mulmod(mload(0x4ee0), 11451405578697956743456240853980216273390554734748796433026540431386972584651, f_q)){ let result := mulmod(mload(0x1220), mload(0x4ee0), f_q)result := addmod(mulmod(mload(0xe60), sub(f_q, mload(0x4f00)), f_q), result, f_q)mstore(0x4f20, result) }mstore(0x4f40, mulmod(19739017567026423485440200119112518431529316337914698509896062636748956259037, mload(0x4ca0), f_q))mstore(0x4f60, mulmod(mload(0x4f40), 16670521521732547392407716560529197273408943645332907966320731856743274895475, f_q)){ let result := mulmod(mload(0x1220), mload(0x4f40), f_q)result := addmod(mulmod(mload(0xe60), sub(f_q, mload(0x4f60)), f_q), result, f_q)mstore(0x4f80, result) }mstore(0x4fa0, mulmod(1, mload(0x4d40), f_q))mstore(0x4fc0, mulmod(mload(0x4fa0), mload(0x4d80), f_q))mstore(0x4fe0, mulmod(mload(0x4fc0), mload(0x4dc0), f_q))mstore(0x5000, mulmod(mload(0x4fe0), mload(0x4e00), f_q))mstore(0x5020, mulmod(15745203948309867518600006049767829981294304144624182135789746588768373190306, mload(0xe60), f_q))mstore(0x5040, mulmod(mload(0x5020), 1, f_q)){ let result := mulmod(mload(0x1220), mload(0x5020), f_q)result := addmod(mulmod(mload(0xe60), sub(f_q, mload(0x5040)), f_q), result, f_q)mstore(0x5060, result) }mstore(0x5080, mulmod(6143038923529407703646399695489445107254060255791852207908457597807435305311, mload(0xe60), f_q))mstore(0x50a0, mulmod(mload(0x5080), 6143038923529407703646399695489445107254060255791852207908457597807435305312, f_q)){ let result := mulmod(mload(0x1220), mload(0x5080), f_q)result := addmod(mulmod(mload(0xe60), sub(f_q, mload(0x50a0)), f_q), result, f_q)mstore(0x50c0, result) }mstore(0x50e0, mulmod(10510636753979361133264199918335143063708920847007925043768693533292518521402, mload(0xe60), f_q))mstore(0x5100, mulmod(mload(0x50e0), 1, f_q)){ let result := mulmod(mload(0x1220), mload(0x50e0), f_q)result := addmod(mulmod(mload(0xe60), sub(f_q, mload(0x5100)), f_q), result, f_q)mstore(0x5120, result) }mstore(0x5140, mulmod(11377606117859914088982205826922132024839443553408109299929510653283289974215, mload(0xe60), f_q))mstore(0x5160, mulmod(mload(0x5140), 11377606117859914088982205826922132024839443553408109299929510653283289974216, f_q)){ let result := mulmod(mload(0x1220), mload(0x5140), f_q)result := addmod(mulmod(mload(0xe60), sub(f_q, mload(0x5160)), f_q), result, f_q)mstore(0x5180, result) }mstore(0x51a0, mulmod(mload(0x4fa0), mload(0x4d00), f_q)){ let result := mulmod(mload(0x1220), 1, f_q)result := addmod(mulmod(mload(0xe60), 21888242871839275222246405745257275088548364400416034343698204186575808495616, f_q), result, f_q)mstore(0x51c0, result) }{ let prod := mload(0x4e60) prod := mulmod(mload(0x4ec0), prod, f_q) mstore(0x51e0, prod) prod := mulmod(mload(0x4f20), prod, f_q) mstore(0x5200, prod) prod := mulmod(mload(0x4f80), prod, f_q) mstore(0x5220, prod) prod := mulmod(mload(0x5060), prod, f_q) mstore(0x5240, prod) prod := mulmod(mload(0x50c0), prod, f_q) mstore(0x5260, prod) prod := mulmod(mload(0x4fc0), prod, f_q) mstore(0x5280, prod) prod := mulmod(mload(0x5120), prod, f_q) mstore(0x52a0, prod) prod := mulmod(mload(0x5180), prod, f_q) mstore(0x52c0, prod) prod := mulmod(mload(0x51a0), prod, f_q) mstore(0x52e0, prod) prod := mulmod(mload(0x51c0), prod, f_q) mstore(0x5300, prod) prod := mulmod(mload(0x4fa0), prod, f_q) mstore(0x5320, prod) }mstore(0x5360, 32)mstore(0x5380, 32)mstore(0x53a0, 32)mstore(0x53c0, mload(0x5320))mstore(0x53e0, 21888242871839275222246405745257275088548364400416034343698204186575808495615)mstore(0x5400, 21888242871839275222246405745257275088548364400416034343698204186575808495617)success := and(eq(staticcall(gas(), 0x5, 0x5360, 0xc0, 0x5340, 0x20), 1), success){ let inv := mload(0x5340) let v v := mload(0x4fa0) mstore(0x4fa0, mulmod(mload(0x5300), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x51c0) mstore(0x51c0, mulmod(mload(0x52e0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x51a0) mstore(0x51a0, mulmod(mload(0x52c0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x5180) mstore(0x5180, mulmod(mload(0x52a0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x5120) mstore(0x5120, mulmod(mload(0x5280), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x4fc0) mstore(0x4fc0, mulmod(mload(0x5260), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x50c0) mstore(0x50c0, mulmod(mload(0x5240), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x5060) mstore(0x5060, mulmod(mload(0x5220), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x4f80) mstore(0x4f80, mulmod(mload(0x5200), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x4f20) mstore(0x4f20, mulmod(mload(0x51e0), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x4ec0) mstore(0x4ec0, mulmod(mload(0x4e60), inv, f_q)) inv := mulmod(v, inv, f_q) mstore(0x4e60, inv) }{ let result := mload(0x4e60)result := addmod(mload(0x4ec0), result, f_q)result := addmod(mload(0x4f20), result, f_q)result := addmod(mload(0x4f80), result, f_q)mstore(0x5420, result) }mstore(0x5440, mulmod(mload(0x5000), mload(0x4fc0), f_q)){ let result := mload(0x5060)result := addmod(mload(0x50c0), result, f_q)mstore(0x5460, result) }mstore(0x5480, mulmod(mload(0x5000), mload(0x51a0), f_q)){ let result := mload(0x5120)result := addmod(mload(0x5180), result, f_q)mstore(0x54a0, result) }mstore(0x54c0, mulmod(mload(0x5000), mload(0x4fa0), f_q)){ let result := mload(0x51c0)mstore(0x54e0, result) }{ let prod := mload(0x5420) prod := mulmod(mload(0x5460), prod, f_q) mstore(0x5500, prod) prod := mulmod(mload(0x54a0), prod, f_q) mstore(0x5520, prod) prod := mulmod(mload(0x54e0), prod, f_q) mstore(0x5540, prod) }mstore(0x5580, 32)mstore(0x55a0, 32)mstore(0x55c0, 32)mstore(0x55e0, mload(0x5540))mstore(0x5600, 21888242871839275222246405745257275088548364400416034343698204186575808495615)mstore(0x5620, 21888242871839275222246405745257275088548364400416034343698204186575808495617)success := and(eq(staticcall(gas(), 0x5, 0x5580, 0xc0, 0x5560, 0x20), 1), success){ let inv := mload(0x5560) let v v := mload(0x54e0) mstore(0x54e0, mulmod(mload(0x5520), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x54a0) mstore(0x54a0, mulmod(mload(0x5500), inv, f_q)) inv := mulmod(v, inv, f_q) v := mload(0x5460) mstore(0x5460, mulmod(mload(0x5420), inv, f_q)) inv := mulmod(v, inv, f_q) mstore(0x5420, inv) }mstore(0x5640, mulmod(mload(0x5440), mload(0x5460), f_q))mstore(0x5660, mulmod(mload(0x5480), mload(0x54a0), f_q))mstore(0x5680, mulmod(mload(0x54c0), mload(0x54e0), f_q))mstore(0x56a0, mulmod(mload(0x1120), mload(0x1120), f_q))mstore(0x56c0, mulmod(mload(0x56a0), mload(0x1120), f_q))mstore(0x56e0, mulmod(mload(0x56c0), mload(0x1120), f_q))mstore(0x5700, mulmod(mload(0x56e0), mload(0x1120), f_q))mstore(0x5720, mulmod(mload(0x5700), mload(0x1120), f_q))mstore(0x5740, mulmod(mload(0x5720), mload(0x1120), f_q))mstore(0x5760, mulmod(mload(0x5740), mload(0x1120), f_q))mstore(0x5780, mulmod(mload(0x5760), mload(0x1120), f_q))mstore(0x57a0, mulmod(mload(0x5780), mload(0x1120), f_q))mstore(0x57c0, mulmod(mload(0x1180), mload(0x1180), f_q))mstore(0x57e0, mulmod(mload(0x57c0), mload(0x1180), f_q))mstore(0x5800, mulmod(mload(0x57e0), mload(0x1180), f_q)){ let result := mulmod(mload(0xea0), mload(0x4e60), f_q)result := addmod(mulmod(mload(0xec0), mload(0x4ec0), f_q), result, f_q)result := addmod(mulmod(mload(0xee0), mload(0x4f20), f_q), result, f_q)result := addmod(mulmod(mload(0xf00), mload(0x4f80), f_q), result, f_q)mstore(0x5820, result) }mstore(0x5840, mulmod(mload(0x5820), mload(0x5420), f_q))mstore(0x5860, mulmod(sub(f_q, mload(0x5840)), 1, f_q))mstore(0x5880, mulmod(mload(0x5860), 1, f_q))mstore(0x58a0, mulmod(1, mload(0x5440), f_q)){ let result := mulmod(mload(0x1020), mload(0x5060), f_q)result := addmod(mulmod(mload(0x1040), mload(0x50c0), f_q), result, f_q)mstore(0x58c0, result) }mstore(0x58e0, mulmod(mload(0x58c0), mload(0x5640), f_q))mstore(0x5900, mulmod(sub(f_q, mload(0x58e0)), 1, f_q))mstore(0x5920, mulmod(mload(0x58a0), 1, f_q)){ let result := mulmod(mload(0x1060), mload(0x5060), f_q)result := addmod(mulmod(mload(0x1080), mload(0x50c0), f_q), result, f_q)mstore(0x5940, result) }mstore(0x5960, mulmod(mload(0x5940), mload(0x5640), f_q))mstore(0x5980, mulmod(sub(f_q, mload(0x5960)), mload(0x1120), f_q))mstore(0x59a0, mulmod(mload(0x58a0), mload(0x1120), f_q))mstore(0x59c0, addmod(mload(0x5900), mload(0x5980), f_q))mstore(0x59e0, mulmod(mload(0x59c0), mload(0x1180), f_q))mstore(0x5a00, mulmod(mload(0x5920), mload(0x1180), f_q))mstore(0x5a20, mulmod(mload(0x59a0), mload(0x1180), f_q))mstore(0x5a40, addmod(mload(0x5880), mload(0x59e0), f_q))mstore(0x5a60, mulmod(1, mload(0x5480), f_q)){ let result := mulmod(mload(0x10a0), mload(0x5120), f_q)result := addmod(mulmod(mload(0x10c0), mload(0x5180), f_q), result, f_q)mstore(0x5a80, result) }mstore(0x5aa0, mulmod(mload(0x5a80), mload(0x5660), f_q))mstore(0x5ac0, mulmod(sub(f_q, mload(0x5aa0)), 1, f_q))mstore(0x5ae0, mulmod(mload(0x5a60), 1, f_q))mstore(0x5b00, mulmod(mload(0x5ac0), mload(0x57c0), f_q))mstore(0x5b20, mulmod(mload(0x5ae0), mload(0x57c0), f_q))mstore(0x5b40, addmod(mload(0x5a40), mload(0x5b00), f_q))mstore(0x5b60, mulmod(1, mload(0x54c0), f_q)){ let result := mulmod(mload(0x10e0), mload(0x51c0), f_q)mstore(0x5b80, result) }mstore(0x5ba0, mulmod(mload(0x5b80), mload(0x5680), f_q))mstore(0x5bc0, mulmod(sub(f_q, mload(0x5ba0)), 1, f_q))mstore(0x5be0, mulmod(mload(0x5b60), 1, f_q)){ let result := mulmod(mload(0xf20), mload(0x51c0), f_q)mstore(0x5c00, result) }mstore(0x5c20, mulmod(mload(0x5c00), mload(0x5680), f_q))mstore(0x5c40, mulmod(sub(f_q, mload(0x5c20)), mload(0x1120), f_q))mstore(0x5c60, mulmod(mload(0x5b60), mload(0x1120), f_q))mstore(0x5c80, addmod(mload(0x5bc0), mload(0x5c40), f_q)){ let result := mulmod(mload(0xf40), mload(0x51c0), f_q)mstore(0x5ca0, result) }mstore(0x5cc0, mulmod(mload(0x5ca0), mload(0x5680), f_q))mstore(0x5ce0, mulmod(sub(f_q, mload(0x5cc0)), mload(0x56a0), f_q))mstore(0x5d00, mulmod(mload(0x5b60), mload(0x56a0), f_q))mstore(0x5d20, addmod(mload(0x5c80), mload(0x5ce0), f_q)){ let result := mulmod(mload(0xf60), mload(0x51c0), f_q)mstore(0x5d40, result) }mstore(0x5d60, mulmod(mload(0x5d40), mload(0x5680), f_q))mstore(0x5d80, mulmod(sub(f_q, mload(0x5d60)), mload(0x56c0), f_q))mstore(0x5da0, mulmod(mload(0x5b60), mload(0x56c0), f_q))mstore(0x5dc0, addmod(mload(0x5d20), mload(0x5d80), f_q)){ let result := mulmod(mload(0xf80), mload(0x51c0), f_q)mstore(0x5de0, result) }mstore(0x5e00, mulmod(mload(0x5de0), mload(0x5680), f_q))mstore(0x5e20, mulmod(sub(f_q, mload(0x5e00)), mload(0x56e0), f_q))mstore(0x5e40, mulmod(mload(0x5b60), mload(0x56e0), f_q))mstore(0x5e60, addmod(mload(0x5dc0), mload(0x5e20), f_q)){ let result := mulmod(mload(0xfc0), mload(0x51c0), f_q)mstore(0x5e80, result) }mstore(0x5ea0, mulmod(mload(0x5e80), mload(0x5680), f_q))mstore(0x5ec0, mulmod(sub(f_q, mload(0x5ea0)), mload(0x5700), f_q))mstore(0x5ee0, mulmod(mload(0x5b60), mload(0x5700), f_q))mstore(0x5f00, addmod(mload(0x5e60), mload(0x5ec0), f_q)){ let result := mulmod(mload(0xfe0), mload(0x51c0), f_q)mstore(0x5f20, result) }mstore(0x5f40, mulmod(mload(0x5f20), mload(0x5680), f_q))mstore(0x5f60, mulmod(sub(f_q, mload(0x5f40)), mload(0x5720), f_q))mstore(0x5f80, mulmod(mload(0x5b60), mload(0x5720), f_q))mstore(0x5fa0, addmod(mload(0x5f00), mload(0x5f60), f_q)){ let result := mulmod(mload(0x1000), mload(0x51c0), f_q)mstore(0x5fc0, result) }mstore(0x5fe0, mulmod(mload(0x5fc0), mload(0x5680), f_q))mstore(0x6000, mulmod(sub(f_q, mload(0x5fe0)), mload(0x5740), f_q))mstore(0x6020, mulmod(mload(0x5b60), mload(0x5740), f_q))mstore(0x6040, addmod(mload(0x5fa0), mload(0x6000), f_q))mstore(0x6060, mulmod(mload(0x4c20), mload(0x54c0), f_q))mstore(0x6080, mulmod(mload(0x4c40), mload(0x54c0), f_q))mstore(0x60a0, mulmod(mload(0x4c60), mload(0x54c0), f_q)){ let result := mulmod(mload(0x4c80), mload(0x51c0), f_q)mstore(0x60c0, result) }mstore(0x60e0, mulmod(mload(0x60c0), mload(0x5680), f_q))mstore(0x6100, mulmod(sub(f_q, mload(0x60e0)), mload(0x5760), f_q))mstore(0x6120, mulmod(mload(0x5b60), mload(0x5760), f_q))mstore(0x6140, mulmod(mload(0x6060), mload(0x5760), f_q))mstore(0x6160, mulmod(mload(0x6080), mload(0x5760), f_q))mstore(0x6180, mulmod(mload(0x60a0), mload(0x5760), f_q))mstore(0x61a0, addmod(mload(0x6040), mload(0x6100), f_q)){ let result := mulmod(mload(0xfa0), mload(0x51c0), f_q)mstore(0x61c0, result) }mstore(0x61e0, mulmod(mload(0x61c0), mload(0x5680), f_q))mstore(0x6200, mulmod(sub(f_q, mload(0x61e0)), mload(0x5780), f_q))mstore(0x6220, mulmod(mload(0x5b60), mload(0x5780), f_q))mstore(0x6240, addmod(mload(0x61a0), mload(0x6200), f_q))mstore(0x6260, mulmod(mload(0x6240), mload(0x57e0), f_q))mstore(0x6280, mulmod(mload(0x5be0), mload(0x57e0), f_q))mstore(0x62a0, mulmod(mload(0x5c60), mload(0x57e0), f_q))mstore(0x62c0, mulmod(mload(0x5d00), mload(0x57e0), f_q))mstore(0x62e0, mulmod(mload(0x5da0), mload(0x57e0), f_q))mstore(0x6300, mulmod(mload(0x5e40), mload(0x57e0), f_q))mstore(0x6320, mulmod(mload(0x5ee0), mload(0x57e0), f_q))mstore(0x6340, mulmod(mload(0x5f80), mload(0x57e0), f_q))mstore(0x6360, mulmod(mload(0x6020), mload(0x57e0), f_q))mstore(0x6380, mulmod(mload(0x6120), mload(0x57e0), f_q))mstore(0x63a0, mulmod(mload(0x6140), mload(0x57e0), f_q))mstore(0x63c0, mulmod(mload(0x6160), mload(0x57e0), f_q))mstore(0x63e0, mulmod(mload(0x6180), mload(0x57e0), f_q))mstore(0x6400, mulmod(mload(0x6220), mload(0x57e0), f_q))mstore(0x6420, addmod(mload(0x5b40), mload(0x6260), f_q))mstore(0x6440, mulmod(1, mload(0x5000), f_q))mstore(0x6460, mulmod(1, mload(0x1220), f_q))mstore(0x6480, 0x0000000000000000000000000000000000000000000000000000000000000001) mstore(0x64a0, 0x0000000000000000000000000000000000000000000000000000000000000002)mstore(0x64c0, mload(0x6420))success := and(eq(staticcall(gas(), 0x7, 0x6480, 0x60, 0x6480, 0x40), 1), success)mstore(0x64e0, mload(0x6480)) mstore(0x6500, mload(0x64a0))mstore(0x6520, mload(0xa40)) mstore(0x6540, mload(0xa60))success := and(eq(staticcall(gas(), 0x6, 0x64e0, 0x80, 0x64e0, 0x40), 1), success)mstore(0x6560, mload(0xc20)) mstore(0x6580, mload(0xc40))mstore(0x65a0, mload(0x5a00))success := and(eq(staticcall(gas(), 0x7, 0x6560, 0x60, 0x6560, 0x40), 1), success)mstore(0x65c0, mload(0x64e0)) mstore(0x65e0, mload(0x6500))mstore(0x6600, mload(0x6560)) mstore(0x6620, mload(0x6580))success := and(eq(staticcall(gas(), 0x6, 0x65c0, 0x80, 0x65c0, 0x40), 1), success)mstore(0x6640, mload(0xc60)) mstore(0x6660, mload(0xc80))mstore(0x6680, mload(0x5a20))success := and(eq(staticcall(gas(), 0x7, 0x6640, 0x60, 0x6640, 0x40), 1), success)mstore(0x66a0, mload(0x65c0)) mstore(0x66c0, mload(0x65e0))mstore(0x66e0, mload(0x6640)) mstore(0x6700, mload(0x6660))success := and(eq(staticcall(gas(), 0x6, 0x66a0, 0x80, 0x66a0, 0x40), 1), success)mstore(0x6720, mload(0xae0)) mstore(0x6740, mload(0xb00))mstore(0x6760, mload(0x5b20))success := and(eq(staticcall(gas(), 0x7, 0x6720, 0x60, 0x6720, 0x40), 1), success)mstore(0x6780, mload(0x66a0)) mstore(0x67a0, mload(0x66c0))mstore(0x67c0, mload(0x6720)) mstore(0x67e0, mload(0x6740))success := and(eq(staticcall(gas(), 0x6, 0x6780, 0x80, 0x6780, 0x40), 1), success)mstore(0x6800, mload(0xb20)) mstore(0x6820, mload(0xb40))mstore(0x6840, mload(0x6280))success := and(eq(staticcall(gas(), 0x7, 0x6800, 0x60, 0x6800, 0x40), 1), success)mstore(0x6860, mload(0x6780)) mstore(0x6880, mload(0x67a0))mstore(0x68a0, mload(0x6800)) mstore(0x68c0, mload(0x6820))success := and(eq(staticcall(gas(), 0x6, 0x6860, 0x80, 0x6860, 0x40), 1), success)mstore(0x68e0, 0x22ab1845dfd98393b63341fa885737f42cc927dbe414a0d1b849868573042e27) mstore(0x6900, 0x0031e66fb2b432a281a411a5f818165d6f398df73046fade2d3e0372af1c77a3)mstore(0x6920, mload(0x62a0))success := and(eq(staticcall(gas(), 0x7, 0x68e0, 0x60, 0x68e0, 0x40), 1), success)mstore(0x6940, mload(0x6860)) mstore(0x6960, mload(0x6880))mstore(0x6980, mload(0x68e0)) mstore(0x69a0, mload(0x6900))success := and(eq(staticcall(gas(), 0x6, 0x6940, 0x80, 0x6940, 0x40), 1), success)mstore(0x69c0, 0x2b49991085edc0ad59347332eef079c69d246382b6050f559f6dfa3e267d4db7) mstore(0x69e0, 0x2f9011bf0177a5787cb6f4f2c628c3f220f334b24ce536720185a88518724f74)mstore(0x6a00, mload(0x62c0))success := and(eq(staticcall(gas(), 0x7, 0x69c0, 0x60, 0x69c0, 0x40), 1), success)mstore(0x6a20, mload(0x6940)) mstore(0x6a40, mload(0x6960))mstore(0x6a60, mload(0x69c0)) mstore(0x6a80, mload(0x69e0))success := and(eq(staticcall(gas(), 0x6, 0x6a20, 0x80, 0x6a20, 0x40), 1), success)mstore(0x6aa0, 0x1c3cf8fbb3bac48d327f768564acc4210893358a29706b6b845c4efb2d597a4c) mstore(0x6ac0, 0x0daadee16f46162c954229b2ec489f604ef3ced4a0d92bd1d578162adc4438c3)mstore(0x6ae0, mload(0x62e0))success := and(eq(staticcall(gas(), 0x7, 0x6aa0, 0x60, 0x6aa0, 0x40), 1), success)mstore(0x6b00, mload(0x6a20)) mstore(0x6b20, mload(0x6a40))mstore(0x6b40, mload(0x6aa0)) mstore(0x6b60, mload(0x6ac0))success := and(eq(staticcall(gas(), 0x6, 0x6b00, 0x80, 0x6b00, 0x40), 1), success)mstore(0x6b80, 0x068d9562cfccc9548fc64e6e30fe3efa4f8eadfdf01d837e300f444d714c8584) mstore(0x6ba0, 0x11b6f25ff1a6e228b4831558c5baf470c3dda44f5b81db253dde98b5a51b568a)mstore(0x6bc0, mload(0x6300))success := and(eq(staticcall(gas(), 0x7, 0x6b80, 0x60, 0x6b80, 0x40), 1), success)mstore(0x6be0, mload(0x6b00)) mstore(0x6c00, mload(0x6b20))mstore(0x6c20, mload(0x6b80)) mstore(0x6c40, mload(0x6ba0))success := and(eq(staticcall(gas(), 0x6, 0x6be0, 0x80, 0x6be0, 0x40), 1), success)mstore(0x6c60, 0x16b30314d1b578c95c5f8d19e826cdc833da127a84075ba0e413264b4abae674) mstore(0x6c80, 0x2f2ded715442bfb76754e49657f387933ea76fd7f4d0833fd4eace95cf46869d)mstore(0x6ca0, mload(0x6320))success := and(eq(staticcall(gas(), 0x7, 0x6c60, 0x60, 0x6c60, 0x40), 1), success)mstore(0x6cc0, mload(0x6be0)) mstore(0x6ce0, mload(0x6c00))mstore(0x6d00, mload(0x6c60)) mstore(0x6d20, mload(0x6c80))success := and(eq(staticcall(gas(), 0x6, 0x6cc0, 0x80, 0x6cc0, 0x40), 1), success)mstore(0x6d40, 0x02da89950a834d06bad25f820ca837babb09cf64bc5939b4fd8ff068de3d3744) mstore(0x6d60, 0x2b43b393ddd80e8788efdfd6d1162410b5d4bbcbe975844b58b229b4c424e4db)mstore(0x6d80, mload(0x6340))success := and(eq(staticcall(gas(), 0x7, 0x6d40, 0x60, 0x6d40, 0x40), 1), success)mstore(0x6da0, mload(0x6cc0)) mstore(0x6dc0, mload(0x6ce0))mstore(0x6de0, mload(0x6d40)) mstore(0x6e00, mload(0x6d60))success := and(eq(staticcall(gas(), 0x6, 0x6da0, 0x80, 0x6da0, 0x40), 1), success)mstore(0x6e20, 0x0099d310db67fd1b6fb03211c729e3a39a3bdcfd5a8820e8e606069c95297d0f) mstore(0x6e40, 0x1aa4cbeb3b34d4c18e165262b1d47135c936234dae97fd0727cc025c2b53d218)mstore(0x6e60, mload(0x6360))success := and(eq(staticcall(gas(), 0x7, 0x6e20, 0x60, 0x6e20, 0x40), 1), success)mstore(0x6e80, mload(0x6da0)) mstore(0x6ea0, mload(0x6dc0))mstore(0x6ec0, mload(0x6e20)) mstore(0x6ee0, mload(0x6e40))success := and(eq(staticcall(gas(), 0x6, 0x6e80, 0x80, 0x6e80, 0x40), 1), success)mstore(0x6f00, mload(0xd40)) mstore(0x6f20, mload(0xd60))mstore(0x6f40, mload(0x6380))success := and(eq(staticcall(gas(), 0x7, 0x6f00, 0x60, 0x6f00, 0x40), 1), success)mstore(0x6f60, mload(0x6e80)) mstore(0x6f80, mload(0x6ea0))mstore(0x6fa0, mload(0x6f00)) mstore(0x6fc0, mload(0x6f20))success := and(eq(staticcall(gas(), 0x6, 0x6f60, 0x80, 0x6f60, 0x40), 1), success)mstore(0x6fe0, mload(0xd80)) mstore(0x7000, mload(0xda0))mstore(0x7020, mload(0x63a0))success := and(eq(staticcall(gas(), 0x7, 0x6fe0, 0x60, 0x6fe0, 0x40), 1), success)mstore(0x7040, mload(0x6f60)) mstore(0x7060, mload(0x6f80))mstore(0x7080, mload(0x6fe0)) mstore(0x70a0, mload(0x7000))success := and(eq(staticcall(gas(), 0x6, 0x7040, 0x80, 0x7040, 0x40), 1), success)mstore(0x70c0, mload(0xdc0)) mstore(0x70e0, mload(0xde0))mstore(0x7100, mload(0x63c0))success := and(eq(staticcall(gas(), 0x7, 0x70c0, 0x60, 0x70c0, 0x40), 1), success)mstore(0x7120, mload(0x7040)) mstore(0x7140, mload(0x7060))mstore(0x7160, mload(0x70c0)) mstore(0x7180, mload(0x70e0))success := and(eq(staticcall(gas(), 0x6, 0x7120, 0x80, 0x7120, 0x40), 1), success)mstore(0x71a0, mload(0xe00)) mstore(0x71c0, mload(0xe20))mstore(0x71e0, mload(0x63e0))success := and(eq(staticcall(gas(), 0x7, 0x71a0, 0x60, 0x71a0, 0x40), 1), success)mstore(0x7200, mload(0x7120)) mstore(0x7220, mload(0x7140))mstore(0x7240, mload(0x71a0)) mstore(0x7260, mload(0x71c0))success := and(eq(staticcall(gas(), 0x6, 0x7200, 0x80, 0x7200, 0x40), 1), success)mstore(0x7280, mload(0xca0)) mstore(0x72a0, mload(0xcc0))mstore(0x72c0, mload(0x6400))success := and(eq(staticcall(gas(), 0x7, 0x7280, 0x60, 0x7280, 0x40), 1), success)mstore(0x72e0, mload(0x7200)) mstore(0x7300, mload(0x7220))mstore(0x7320, mload(0x7280)) mstore(0x7340, mload(0x72a0))success := and(eq(staticcall(gas(), 0x6, 0x72e0, 0x80, 0x72e0, 0x40), 1), success)mstore(0x7360, mload(0x11c0)) mstore(0x7380, mload(0x11e0))mstore(0x73a0, sub(f_q, mload(0x6440)))success := and(eq(staticcall(gas(), 0x7, 0x7360, 0x60, 0x7360, 0x40), 1), success)mstore(0x73c0, mload(0x72e0)) mstore(0x73e0, mload(0x7300))mstore(0x7400, mload(0x7360)) mstore(0x7420, mload(0x7380))success := and(eq(staticcall(gas(), 0x6, 0x73c0, 0x80, 0x73c0, 0x40), 1), success)mstore(0x7440, mload(0x1260)) mstore(0x7460, mload(0x1280))mstore(0x7480, mload(0x6460))success := and(eq(staticcall(gas(), 0x7, 0x7440, 0x60, 0x7440, 0x40), 1), success)mstore(0x74a0, mload(0x73c0)) mstore(0x74c0, mload(0x73e0))mstore(0x74e0, mload(0x7440)) mstore(0x7500, mload(0x7460))success := and(eq(staticcall(gas(), 0x6, 0x74a0, 0x80, 0x74a0, 0x40), 1), success)mstore(0x7520, mload(0x74a0)) mstore(0x7540, mload(0x74c0))mstore(0x7560, mload(0x1260)) mstore(0x7580, mload(0x1280))mstore(0x75a0, mload(0x12a0)) mstore(0x75c0, mload(0x12c0))mstore(0x75e0, mload(0x12e0)) mstore(0x7600, mload(0x1300))mstore(0x7620, keccak256(0x7520, 256))mstore(0x7640, mod(mload(30112), f_q))mstore(0x7660, mulmod(mload(0x7640), mload(0x7640), f_q))mstore(0x7680, mulmod(1, mload(0x7640), f_q))mstore(0x76a0, mload(0x75a0)) mstore(0x76c0, mload(0x75c0))mstore(0x76e0, mload(0x7680))success := and(eq(staticcall(gas(), 0x7, 0x76a0, 0x60, 0x76a0, 0x40), 1), success)mstore(0x7700, mload(0x7520)) mstore(0x7720, mload(0x7540))mstore(0x7740, mload(0x76a0)) mstore(0x7760, mload(0x76c0))success := and(eq(staticcall(gas(), 0x6, 0x7700, 0x80, 0x7700, 0x40), 1), success)mstore(0x7780, mload(0x75e0)) mstore(0x77a0, mload(0x7600))mstore(0x77c0, mload(0x7680))success := and(eq(staticcall(gas(), 0x7, 0x7780, 0x60, 0x7780, 0x40), 1), success)mstore(0x77e0, mload(0x7560)) mstore(0x7800, mload(0x7580))mstore(0x7820, mload(0x7780)) mstore(0x7840, mload(0x77a0))success := and(eq(staticcall(gas(), 0x6, 0x77e0, 0x80, 0x77e0, 0x40), 1), success)mstore(0x7860, mload(0x7700)) mstore(0x7880, mload(0x7720))mstore(0x78a0, 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2) mstore(0x78c0, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed) mstore(0x78e0, 0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b) mstore(0x7900, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa)mstore(0x7920, mload(0x77e0)) mstore(0x7940, mload(0x7800))mstore(0x7960, 0x0181624e80f3d6ae28df7e01eaeab1c0e919877a3b8a6b7fbc69a6817d596ea2) mstore(0x7980, 0x1783d30dcb12d259bb89098addf6280fa4b653be7a152542a28f7b926e27e648) mstore(0x79a0, 0x00ae44489d41a0d179e2dfdc03bddd883b7109f8b6ae316a59e815c1a6b35304) mstore(0x79c0, 0x0b2147ab62a386bd63e6de1522109b8c9588ab466f5aadfde8c41ca3749423ee)success := and(eq(staticcall(gas(), 0x8, 0x7860, 0x180, 0x7860, 0x20), 1), success)success := and(eq(mload(0x7860), 1), success) // Revert if anything fails if iszero(success) { revert(0, 0) }} return success; } } diff --git a/lightclient-circuits/config/committee_update_18.json b/lightclient-circuits/config/committee_update_18.json index 0bfba944..f4f64d68 100644 --- a/lightclient-circuits/config/committee_update_18.json +++ b/lightclient-circuits/config/committee_update_18.json @@ -28,4 +28,4 @@ 262133 ] ] -} +} \ No newline at end of file diff --git a/lightclient-circuits/config/committee_update_mainnet.json b/lightclient-circuits/config/committee_update_mainnet.json new file mode 100644 index 00000000..f4f64d68 --- /dev/null +++ b/lightclient-circuits/config/committee_update_mainnet.json @@ -0,0 +1,31 @@ +{ + "params": { + "k": 18, + "num_advice_per_phase": [ + 12 + ], + "num_fixed": 1, + "num_lookup_advice_per_phase": [ + 1, + 0, + 0 + ], + "lookup_bits": 8, + "num_instance_columns": 1 + }, + "break_points": [ + [ + 262134, + 262132, + 262134, + 262132, + 262133, + 262132, + 262132, + 262133, + 262132, + 262134, + 262133 + ] + ] +} \ No newline at end of file diff --git a/lightclient-circuits/config/committee_update_verifier_25.json b/lightclient-circuits/config/committee_update_verifier_25.json index 9d724c53..88107546 100644 --- a/lightclient-circuits/config/committee_update_verifier_25.json +++ b/lightclient-circuits/config/committee_update_verifier_25.json @@ -1,12 +1,12 @@ { - "params": { - "degree": 25, - "num_advice": 1, - "num_lookup_advice": 1, - "num_fixed": 1, - "lookup_bits": 8 - }, - "break_points": [ - [] - ] - } + "params": { + "degree": 25, + "num_advice": 1, + "num_lookup_advice": 1, + "num_fixed": 1, + "lookup_bits": 8 + }, + "break_points": [ + [] + ] +} \ No newline at end of file diff --git a/lightclient-circuits/config/committee_update_verifier_mainnet.json b/lightclient-circuits/config/committee_update_verifier_mainnet.json new file mode 100644 index 00000000..88107546 --- /dev/null +++ b/lightclient-circuits/config/committee_update_verifier_mainnet.json @@ -0,0 +1,12 @@ +{ + "params": { + "degree": 25, + "num_advice": 1, + "num_lookup_advice": 1, + "num_fixed": 1, + "lookup_bits": 8 + }, + "break_points": [ + [] + ] +} \ No newline at end of file diff --git a/lightclient-circuits/config/sync_step_mainnet.json b/lightclient-circuits/config/sync_step_mainnet.json new file mode 100644 index 00000000..c430ae66 --- /dev/null +++ b/lightclient-circuits/config/sync_step_mainnet.json @@ -0,0 +1,25 @@ +{ + "params": { + "k": 22, + "num_advice_per_phase": [ + 6 + ], + "num_fixed": 1, + "num_lookup_advice_per_phase": [ + 1, + 0, + 0 + ], + "lookup_bits": 8, + "num_instance_columns": 1 + }, + "break_points": [ + [ + 4194292, + 4194294, + 4194292, + 4194293, + 4194293 + ] + ] +} \ No newline at end of file diff --git a/lightclient-circuits/src/util/circuit.rs b/lightclient-circuits/src/util/circuit.rs index 126dcb4f..6fb2ff4b 100644 --- a/lightclient-circuits/src/util/circuit.rs +++ b/lightclient-circuits/src/util/circuit.rs @@ -294,5 +294,6 @@ where C: Circuit, P: AsRef, { - read_pk::(fname.as_ref(), c.params()).expect("proving key should exist") + read_pk::(fname.as_ref(), c.params()) + .expect(format!("proving key: {:?} should exist", fname.as_ref().to_str()).as_str()) } diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 89db6b26..214452da 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -11,15 +11,13 @@ path = "src/main.rs" # cli clap = { version = "4.2", features = ["derive"] } strum = { version = "=0.25", features = ["derive"] } -cli-batteries = "=0.4" +cli-batteries = "0.5" eyre = "0.6" -anstyle = "=1.0.0" -axum = "0.6" +anstyle = "1.0.0" +axum = { version = "0.7", features = ["tracing", "tower-log"] } tokio = { version = "1.32", features = ["macros"] } -jsonrpc-v2 = { version = "0.12", default-features = false, features = ["easy-errors", "macros", "bytes-v10"] } - -http = "0.2" +jsonrpc-v2 = { version = "0.13", default-features = false, features = ["easy-errors", "macros", "bytes-v10", "hyper-integration"] } # halo2 halo2curves.workspace = true @@ -53,9 +51,10 @@ reqwest = "0.11.22" beacon-api-client.workspace = true ethereum-consensus-types.workspace = true futures = "0.3.29" +ssz_rs.workspace = true [build-dependencies] -cli-batteries = "=0.4" +cli-batteries = "=0.5" [features] default = ["halo2_solidity_verifier"] diff --git a/prover/src/args.rs b/prover/src/args.rs index 29c40326..79f65a33 100644 --- a/prover/src/args.rs +++ b/prover/src/args.rs @@ -84,6 +84,7 @@ pub enum OperationCmd { } #[derive(Clone, Debug, PartialEq, EnumString, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] pub enum Spec { #[strum(serialize = "minimal")] Minimal, diff --git a/prover/src/main.rs b/prover/src/main.rs index 350fbb1a..69b2b0e6 100644 --- a/prover/src/main.rs +++ b/prover/src/main.rs @@ -29,7 +29,7 @@ async fn app(options: Cli) -> eyre::Result<()> { args::Spec::Testnet => spec_app::(op.proof, &options.args) .await .unwrap(), - args::Spec::Mainnet => spec_app::(op.proof, &options.args) + args::Spec::Mainnet => spec_app::(op.proof, &options.args) .await .unwrap(), }, diff --git a/prover/src/rpc.rs b/prover/src/rpc.rs index f9ba2357..d5d92548 100644 --- a/prover/src/rpc.rs +++ b/prover/src/rpc.rs @@ -1,9 +1,6 @@ use super::args::Spec; -use axum::response::IntoResponse; -use axum::routing::post; -use axum::Router; +use axum::{http::StatusCode, response::IntoResponse, routing::post, Router}; use ethers::prelude::*; -use http::StatusCode; use itertools::Itertools; use jsonrpc_v2::RequestObject as JsonRpcRequestObject; use jsonrpc_v2::{Error as JsonRpcError, Params}; @@ -18,10 +15,10 @@ use preprocessor::{ fetch_rotation_args, fetch_step_args, rotation_args_from_update, step_args_from_finality_update, }; use snark_verifier_sdk::{evm::evm_verify, halo2::aggregation::AggregationCircuit, Snark}; -use std::net::TcpListener; use std::path::{Path, PathBuf}; use std::sync::Arc; use url::Url; + pub type JsonRpcServerState = Arc>; use crate::rpc_api::{ @@ -59,25 +56,23 @@ fn gen_evm_proof( config_path: PathBuf, witness: C::Witness, yul_path_if_verify: Option>, -) -> (Vec, Vec>) { +) -> eyre::Result<(Vec, Vec>)> { let k = C::get_degree(&config_path); let params = gen_srs(k); let pk = C::read_pk(¶ms, pk_path, &witness); let (proof, instances) = C::gen_evm_proof_shplonk(¶ms, &pk, &config_path, None, &witness) - .map_err(|e| eyre::eyre!("Failed to generate calldata: {}", e)) - .unwrap(); + .map_err(|e| eyre::eyre!("Failed to generate calldata: {}", e))?; println!("Proof size: {}", proof.len()); if let Some(deployment_code_path) = yul_path_if_verify { let deployment_code = - C::gen_evm_verifier_shplonk(¶ms, &pk, Some(deployment_code_path), &witness) - .unwrap(); + C::gen_evm_verifier_shplonk(¶ms, &pk, Some(deployment_code_path), &witness)?; println!("Deployment code size: {}", deployment_code.len()); evm_verify(deployment_code, instances.clone(), proof.clone()); } - (proof, instances) + Ok((proof, instances)) } pub(crate) async fn gen_evm_proof_rotation_circuit_handler( @@ -167,8 +162,8 @@ pub(crate) async fn gen_evm_proof_rotation_circuit_with_witness_handler( let (snark, verifier_filename) = match spec { Spec::Minimal => { - let mut update = serde_json::from_slice(&light_client_update).unwrap(); - let witness = rotation_args_from_update(&mut update).await.unwrap(); + let mut update = ssz_rs::deserialize(&light_client_update)?; + let witness = rotation_args_from_update(&mut update).await?; let snark = gen_committee_update_snark::( PathBuf::from("./lightclient-circuits/config/committee_update_minimal.json"), PathBuf::from("./build/committee_update_minimal.pkey"), @@ -178,8 +173,8 @@ pub(crate) async fn gen_evm_proof_rotation_circuit_with_witness_handler( (snark, "committee_update_verifier_minimal") } Spec::Testnet => { - let mut update = serde_json::from_slice(&light_client_update).unwrap(); - let witness = rotation_args_from_update(&mut update).await.unwrap(); + let mut update = ssz_rs::deserialize(&light_client_update)?; + let witness = rotation_args_from_update(&mut update).await?; let snark = gen_committee_update_snark::( PathBuf::from("./lightclient-circuits/config/committee_update_testnet.json"), PathBuf::from("./build/committee_update_testnet.pkey"), @@ -189,8 +184,8 @@ pub(crate) async fn gen_evm_proof_rotation_circuit_with_witness_handler( (snark, "committee_update_verifier_testnet") } Spec::Mainnet => { - let mut update = serde_json::from_slice(&light_client_update).unwrap(); - let witness = rotation_args_from_update(&mut update).await.unwrap(); + let mut update = ssz_rs::deserialize(&light_client_update)?; + let witness = rotation_args_from_update(&mut update).await?; let snark = gen_committee_update_snark::( PathBuf::from("./lightclient-circuits/config/committee_update_mainnet.json"), PathBuf::from("./build/committee_update_mainnet.pkey"), @@ -241,36 +236,36 @@ pub(crate) async fn gen_evm_proof_step_circuit_handler( let (proof, instances) = match spec { Spec::Minimal => { let client = beacon_api_client::minimal::Client::new(Url::parse(&beacon_api)?); - let witness = fetch_step_args(&client).await.unwrap(); + let witness = fetch_step_args(&client).await?; gen_evm_proof::>( PathBuf::from("./build/sync_step_minimal.pkey"), PathBuf::from("./lightclient-circuits/config/sync_step_minimal.json"), witness, None::, - ) + )? } Spec::Testnet => { let client = beacon_api_client::mainnet::Client::new(Url::parse(&beacon_api)?); - let witness = fetch_step_args(&client).await.unwrap(); + let witness = fetch_step_args(&client).await?; gen_evm_proof::>( PathBuf::from("./build/sync_step_testnet.pkey"), PathBuf::from("./lightclient-circuits/config/sync_step_testnet.json"), witness, None::, - ) + )? } Spec::Mainnet => { let client = beacon_api_client::mainnet::Client::new(Url::parse(&beacon_api)?); - let witness = fetch_step_args(&client).await.unwrap(); + let witness = fetch_step_args(&client).await?; gen_evm_proof::>( PathBuf::from("./build/sync_step_mainnet.pkey"), PathBuf::from("./lightclient-circuits/config/sync_step_mainnet.json"), witness, None::, - ) + )? } }; @@ -297,46 +292,40 @@ pub(crate) async fn gen_evm_proof_step_circuit_with_witness_handler( let (proof, instances) = match spec { Spec::Minimal => { - let update = serde_json::from_slice(&light_client_finality_update).unwrap(); - let pubkeys = serde_json::from_slice(&pubkeys).unwrap(); - let witness = step_args_from_finality_update(update, pubkeys, domain) - .await - .unwrap(); + let update = ssz_rs::deserialize(&light_client_finality_update)?; + let pubkeys = ssz_rs::deserialize(&pubkeys)?; + let witness = step_args_from_finality_update(update, pubkeys, domain).await?; gen_evm_proof::>( PathBuf::from("./build/sync_step_minimal.pkey"), PathBuf::from("./lightclient-circuits/config/sync_step_minimal.json"), witness, None::, - ) + )? } Spec::Testnet => { - let update = serde_json::from_slice(&light_client_finality_update).unwrap(); - let pubkeys = serde_json::from_slice(&pubkeys).unwrap(); - let witness = step_args_from_finality_update(update, pubkeys, domain) - .await - .unwrap(); + let update = ssz_rs::deserialize(&light_client_finality_update)?; + let pubkeys = ssz_rs::deserialize(&pubkeys)?; + let witness = step_args_from_finality_update(update, pubkeys, domain).await?; gen_evm_proof::>( PathBuf::from("./build/sync_step_testnet.pkey"), PathBuf::from("./lightclient-circuits/config/sync_step_testnet.json"), witness, None::, - ) + )? } Spec::Mainnet => { - let update = serde_json::from_slice(&light_client_finality_update).unwrap(); - let pubkeys = serde_json::from_slice(&pubkeys).unwrap(); - let witness = step_args_from_finality_update(update, pubkeys, domain) - .await - .unwrap(); + let update = ssz_rs::deserialize(&light_client_finality_update)?; + let pubkeys = ssz_rs::deserialize(&pubkeys)?; + let witness = step_args_from_finality_update(update, pubkeys, domain).await?; gen_evm_proof::>( PathBuf::from("./build/sync_step_mainnet.pkey"), PathBuf::from("./lightclient-circuits/config/sync_step_mainnet.json"), witness, None::, - ) + )? } }; @@ -406,17 +395,16 @@ pub(crate) fn jsonrpc_server() -> JsonRpcServer { } pub async fn run_rpc(port: usize) -> Result<(), eyre::Error> { - let tcp_listener = TcpListener::bind(format!("0.0.0.0:{}", port)).unwrap(); + let tcp_listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", port)).await?; let rpc_server = Arc::new(jsonrpc_server()); + let router = Router::new() .route("/rpc", post(handler)) .with_state(rpc_server); log::info!("Ready for RPC connections"); - let server = axum::Server::from_tcp(tcp_listener) - .unwrap() - .serve(router.into_make_service()); - server + + axum::serve(tcp_listener, router.into_make_service()) .await .map_err(|e| eyre::eyre!("RPC server error: {}", e)) } @@ -426,9 +414,11 @@ async fn handler( axum::Json(rpc_call): axum::Json, ) -> impl IntoResponse { let response_headers = [("content-type", "application/json-rpc;charset=utf-8")]; - let response = rpc_server.handle(rpc_call).await; + log::debug!("RPC request with method: {}", rpc_call.method_ref()); + let response = rpc_server.handle(rpc_call).await; let response_str = serde_json::to_string(&response); + log::debug!("RPC response: {:?}", response_str); match response_str { Ok(result) => (StatusCode::OK, response_headers, result), Err(err) => (