From 9c9943df9bccf2a2445ba924c8b0d4f86ff6df47 Mon Sep 17 00:00:00 2001 From: rymnc <43716372+rymnc@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:02:00 +0530 Subject: [PATCH] feat: fix deployments --- contracts/PoseidonHasher.sol | 1168 +---------------- contracts/Rln.sol | 2 +- contracts/RlnBase.sol | 2 - deploy/001_deploy_poseidon_hasher.ts | 8 + deploy/003_deploy_rln.ts | 16 +- deployments/allDeployments.json | 707 +++++++++- deployments/sepolia/BinaryIMT.json | 555 ++++++++ deployments/sepolia/PoseidonHasher.json | 60 +- deployments/sepolia/PoseidonT3.json | 60 + deployments/sepolia/RLN.json | 274 +++- deployments/sepolia/Verifier.json | 24 +- .../0e0cac683e804dc76f2f24c8a5b4012c.json | 43 - .../3d22925ef26b2c95bb2dc86b2f9e06ed.json | 40 - .../3f87313134e2217cb187bd594084789f.json | 52 + ... => 8725b13328c7d7e2e008ae1d327b8955.json} | 2 +- .../b1509b5db56df56b3944fa20992a2034.json | 40 - .../d5475cf869d23da2a838dd607679cc44.json | 40 - docs/index.md | 852 +----------- test/poseidon.test.ts | 11 +- test/rln.test.ts | 6 +- 20 files changed, 1690 insertions(+), 2272 deletions(-) create mode 100644 deployments/sepolia/BinaryIMT.json create mode 100644 deployments/sepolia/PoseidonT3.json delete mode 100644 deployments/sepolia/solcInputs/0e0cac683e804dc76f2f24c8a5b4012c.json delete mode 100644 deployments/sepolia/solcInputs/3d22925ef26b2c95bb2dc86b2f9e06ed.json create mode 100644 deployments/sepolia/solcInputs/3f87313134e2217cb187bd594084789f.json rename deployments/sepolia/solcInputs/{96dd1aa02e55dc27e236e777882a31a7.json => 8725b13328c7d7e2e008ae1d327b8955.json} (99%) delete mode 100644 deployments/sepolia/solcInputs/b1509b5db56df56b3944fa20992a2034.json delete mode 100644 deployments/sepolia/solcInputs/d5475cf869d23da2a838dd607679cc44.json diff --git a/contracts/PoseidonHasher.sol b/contracts/PoseidonHasher.sol index c36cf4c..23c3a38 100644 --- a/contracts/PoseidonHasher.sol +++ b/contracts/PoseidonHasher.sol @@ -1,1174 +1,8 @@ // SPDX-License-Identifier: MIT -// Forked from poseidon-solidity - pragma solidity 0.8.15; -library PoseidonT3 { - uint256 constant M00 = 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b; - uint256 constant M01 = 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771; - uint256 constant M02 = 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7; - uint256 constant M10 = 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0; - uint256 constant M11 = 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23; - uint256 constant M12 = 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911; - - // See here for a simplified implementation: https://github.com/vimwitch/poseidon-solidity/blob/e57becdabb65d99fdc586fe1e1e09e7108202d53/contracts/Poseidon.sol#L40 - // Inspired by: https://github.com/iden3/circomlibjs/blob/v0.0.8/src/poseidon_slow.js - function hash(uint256[2] memory) public pure returns (uint256) { - assembly { - let F := 21888242871839275222246405745257275088548364400416034343698204186575808495617 - let M20 := 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d - let M21 := 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa - let M22 := 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0 - - // load the inputs from memory - let state1 := add(mod(mload(0x80), F), 0x00f1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864) - let state2 := add(mod(mload(0xa0), F), 0x08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5) - let scratch0 := mulmod(state1, state1, F) - state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F) - scratch0 := mulmod(state2, state2, F) - state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F) - scratch0 := - add( - 0x2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d0, - add( - add( - 15452833169820924772166449970675545095234312153403844297388521437673434406763, - mulmod(state1, M10, F) - ), - mulmod(state2, M20, F) - ) - ) - let scratch1 := - add( - 0x2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf2, - add( - add( - 18674271267752038776579386132900109523609358935013267566297499497165104279117, - mulmod(state1, M11, F) - ), - mulmod(state2, M21, F) - ) - ) - let scratch2 := - add( - 0x0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa, - add( - add( - 14817777843080276494683266178512808687156649753153012854386334860566696099579, - mulmod(state1, M12, F) - ), - mulmod(state2, M22, F) - ) - ) - let state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := mulmod(scratch1, scratch1, F) - scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F) - state0 := mulmod(scratch2, scratch2, F) - scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F) - state0 := - add( - 0x28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc632, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := mulmod(state1, state1, F) - state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F) - scratch0 := mulmod(state2, state2, F) - state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F) - scratch0 := - add( - 0x15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := mulmod(scratch1, scratch1, F) - scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F) - state0 := mulmod(scratch2, scratch2, F) - scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F) - state0 := - add( - 0x10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c8705, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b9, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd1, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x005032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f9, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc0, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c887, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da53, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x0081c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb38, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a0, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c502, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x00ef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba89, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c5, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e4, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e13, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e9, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a90035, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db69, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b8, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c77, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x002e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x00b9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c3512, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x00248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a808, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f09, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e8284, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd800, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f178, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e504233, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc0, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d59, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f88948, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d142, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c0, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a58, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d01, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc792, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea6111, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa336, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d6, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f451, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf77, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc630, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := - add( - 0x2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := - add( - 0x054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := mulmod(scratch1, scratch1, F) - scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F) - state0 := mulmod(scratch2, scratch2, F) - scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F) - state0 := - add( - 0x1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c2320, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := mulmod(state1, state1, F) - state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F) - scratch0 := mulmod(state2, state2, F) - state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F) - scratch0 := - add( - 0x0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870, - add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)) - ) - scratch1 := - add( - 0x193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba, - add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)) - ) - scratch2 := - add( - 0x102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f8, - add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)) - ) - state0 := mulmod(scratch0, scratch0, F) - scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F) - state0 := mulmod(scratch1, scratch1, F) - scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F) - state0 := mulmod(scratch2, scratch2, F) - scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F) - state0 := - add( - 0x0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1, - add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)) - ) - state1 := - add( - 0x216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22, - add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)) - ) - state2 := - add( - 0x1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e4228325161, - add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)) - ) - scratch0 := mulmod(state0, state0, F) - state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F) - scratch0 := mulmod(state1, state1, F) - state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F) - scratch0 := mulmod(state2, state2, F) - state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F) - - mstore(0x0, mod(add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)), F)) - - return(0, 0x20) - } - } -} +import {PoseidonT3} from "poseidon-solidity/PoseidonT3.sol"; interface IPoseidonHasher { /// @notice Hashes the input using the Poseidon hash function, n = 2 diff --git a/contracts/Rln.sol b/contracts/Rln.sol index 1ad5053..b96bfaa 100644 --- a/contracts/Rln.sol +++ b/contracts/Rln.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; import "./RlnBase.sol"; -contract Rln is RlnBase { +contract RLN is RlnBase { constructor(uint256 membershipDeposit, uint256 depth, address _poseidonHasher, address _verifier) RlnBase(membershipDeposit, depth, _poseidonHasher, _verifier) {} diff --git a/contracts/RlnBase.sol b/contracts/RlnBase.sol index 25c767c..2dc3fb7 100644 --- a/contracts/RlnBase.sol +++ b/contracts/RlnBase.sol @@ -6,8 +6,6 @@ import {PoseidonHasher} from "./PoseidonHasher.sol"; import {IVerifier} from "./IVerifier.sol"; import {BinaryIMT, BinaryIMTData} from "@zk-kit/imt.sol/BinaryIMT.sol"; -import "forge-std/console.sol"; - /// The tree is full error FullTree(); diff --git a/deploy/001_deploy_poseidon_hasher.ts b/deploy/001_deploy_poseidon_hasher.ts index e7e4773..20e0600 100644 --- a/deploy/001_deploy_poseidon_hasher.ts +++ b/deploy/001_deploy_poseidon_hasher.ts @@ -7,9 +7,17 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const [deployer] = await getUnnamedAccounts(); + const deployRes = await deploy("PoseidonT3", { + from: deployer, + log: true, + }); + await deploy("PoseidonHasher", { from: deployer, log: true, + libraries: { + PoseidonT3: deployRes.address, + }, }); }; export default func; diff --git a/deploy/003_deploy_rln.ts b/deploy/003_deploy_rln.ts index cd6ad04..58dae06 100644 --- a/deploy/003_deploy_rln.ts +++ b/deploy/003_deploy_rln.ts @@ -11,12 +11,24 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { .address; const rlnVerifierAddress = (await deployments.get("Verifier")).address; - await deploy("Rln", { + const deployRes = await deploy("BinaryIMT", { + from: deployer, + log: true, + libraries: { + PoseidonT3: (await deployments.get("PoseidonT3")).address, + }, + }); + + await deploy("RLN", { from: deployer, log: true, args: [1000000000000000, 20, poseidonHasherAddress, rlnVerifierAddress], + libraries: { + BinaryIMT: deployRes.address, + }, }); }; + export default func; func.tags = ["Rln"]; -func.dependencies = ["PoseidonHasher", "RlnVerifier"]; +func.dependencies = ["PoseidonHasher", "RlnVerifier", "BinaryIMT"]; diff --git a/deployments/allDeployments.json b/deployments/allDeployments.json index fe35ba1..d9fe0bf 100644 --- a/deployments/allDeployments.json +++ b/deployments/allDeployments.json @@ -4,17 +4,54 @@ "name": "sepolia", "chainId": "11155111", "contracts": { - "PoseidonHasher": { - "address": "0xa1554EAF0DF18C05956249aac375e212edeD2CcF", + "PoseidonT3": { + "address": "0xbeeeAcde37Bce9011326137a49Bd5CA8153E9FCD", "abi": [ { "inputs": [ + { + "internalType": "uint256[2]", + "name": "", + "type": "uint256[2]" + } + ], + "name": "hash", + "outputs": [ { "internalType": "uint256", - "name": "input", + "name": "", "type": "uint256" } ], + "stateMutability": "pure", + "type": "function" + } + ] + }, + "PoseidonHasher": { + "address": "0x2092b99411d480b8Dd04BfD68EF1F0d545b0eB1D", + "abi": [ + { + "inputs": [], + "name": "Q", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[2]", + "name": "inputs", + "type": "uint256[2]" + } + ], "name": "hash", "outputs": [ { @@ -28,8 +65,526 @@ } ] }, + "Verifier": { + "address": "0xe36940B40aDe98F02a4829414F7e8d636CCf3663", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256[2]", + "name": "a", + "type": "uint256[2]" + }, + { + "internalType": "uint256[2][2]", + "name": "b", + "type": "uint256[2][2]" + }, + { + "internalType": "uint256[2]", + "name": "c", + "type": "uint256[2]" + }, + { + "internalType": "uint256[2]", + "name": "input", + "type": "uint256[2]" + } + ], + "name": "verifyProof", + "outputs": [ + { + "internalType": "bool", + "name": "r", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "BinaryIMT": { + "address": "0x9Eae140A17Fd002B2ffA3B5df76C13100CDF909d", + "abi": [ + { + "inputs": [], + "name": "MAX_DEPTH", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SNARK_SCALAR_FIELD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_10", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_11", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_12", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_13", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_14", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_15", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_16", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_17", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_18", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_19", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_2", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_20", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_21", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_22", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_23", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_24", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_25", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_26", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_27", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_28", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_29", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_3", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_30", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_31", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_32", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_4", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_5", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_6", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_7", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_8", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_9", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "defaultZero", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ] + }, "RLN": { - "address": "0xB8144E3214080f179D037bbb4dcaaa6B87f224E4", + "address": "0x3d2dcfF8Ee904C3F5Bf3043642C605DFcA7BEBA9", "abi": [ { "inputs": [ @@ -93,6 +648,17 @@ "name": "InsufficientWithdrawalBalance", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "idCommitment", + "type": "uint256" + } + ], + "name": "InvalidIdCommitment", + "type": "error" + }, { "inputs": [], "name": "InvalidProof", @@ -208,6 +774,32 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "computeRoot", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deployedBlockNumber", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "idCommitmentIndex", @@ -221,6 +813,72 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "imtData", + "outputs": [ + { + "internalType": "uint256", + "name": "depth", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "root", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "numberOfLeaves", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "useDefaultZeroes", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "idCommitment", + "type": "uint256" + } + ], + "name": "isValidCommitment", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "memberExists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -245,7 +903,7 @@ "name": "poseidonHasher", "outputs": [ { - "internalType": "contract IPoseidonHasher", + "internalType": "contract PoseidonHasher", "name": "", "type": "address" } @@ -348,45 +1006,6 @@ "type": "function" } ] - }, - "Verifier": { - "address": "0xb81Faa6F0126dedB55A45eb63E8430B270A00303", - "abi": [ - { - "inputs": [ - { - "internalType": "uint256[2]", - "name": "a", - "type": "uint256[2]" - }, - { - "internalType": "uint256[2][2]", - "name": "b", - "type": "uint256[2][2]" - }, - { - "internalType": "uint256[2]", - "name": "c", - "type": "uint256[2]" - }, - { - "internalType": "uint256[2]", - "name": "input", - "type": "uint256[2]" - } - ], - "name": "verifyProof", - "outputs": [ - { - "internalType": "bool", - "name": "r", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ] } } } diff --git a/deployments/sepolia/BinaryIMT.json b/deployments/sepolia/BinaryIMT.json new file mode 100644 index 0000000..ef3755a --- /dev/null +++ b/deployments/sepolia/BinaryIMT.json @@ -0,0 +1,555 @@ +{ + "address": "0x9Eae140A17Fd002B2ffA3B5df76C13100CDF909d", + "abi": [ + { + "inputs": [], + "name": "MAX_DEPTH", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SNARK_SCALAR_FIELD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_0", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_10", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_11", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_12", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_13", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_14", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_15", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_16", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_17", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_18", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_19", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_2", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_20", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_21", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_22", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_23", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_24", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_25", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_26", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_27", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_28", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_29", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_3", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_30", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_31", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_32", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_4", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_5", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_6", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_7", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_8", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "Z_9", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "defaultZero", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0xd2d8efbdb9b0e3ab4050c94effa32de9d56cb4afe7ef1a36bb5ac3785fed5dce", + "receipt": { + "to": null, + "from": "0x3F47b2a1dF96DE2e198d646b598C37251CCC3b98", + "contractAddress": "0x9Eae140A17Fd002B2ffA3B5df76C13100CDF909d", + "transactionIndex": 15, + "gasUsed": "2603657", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x389d39dc86a2cc38165723dcb8002f4859f4c0b7a62b5c4fb3ef85db417c60a6", + "transactionHash": "0xd2d8efbdb9b0e3ab4050c94effa32de9d56cb4afe7ef1a36bb5ac3785fed5dce", + "logs": [], + "blockNumber": 4794984, + "cumulativeGasUsed": "5266673", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "3f87313134e2217cb187bd594084789f", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"MAX_DEPTH\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SNARK_SCALAR_FIELD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_0\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_1\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_10\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_11\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_12\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_13\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_14\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_15\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_16\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_17\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_18\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_19\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_2\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_20\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_21\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_22\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_23\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_24\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_25\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_26\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_27\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_28\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_29\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_3\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_30\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_31\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_32\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_4\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_5\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_6\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_7\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_8\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Z_9\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"defaultZero\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"The incremental tree allows to calculate the root hash each time a leaf is added, ensuring the integrity of the tree.\",\"kind\":\"dev\",\"methods\":{\"init(BinaryIMTData storage,uint256,uint256)\":{\"details\":\"Initializes a tree.\",\"params\":{\"depth\":\": Depth of the tree.\",\"self\":\": Tree data.\",\"zero\":\": Zero value to be used.\"}},\"insert(BinaryIMTData storage,uint256)\":{\"details\":\"Inserts a leaf in the tree.\",\"params\":{\"leaf\":\": Leaf to be inserted.\",\"self\":\": Tree data.\"}},\"remove(BinaryIMTData storage,uint256,uint256[],uint8[])\":{\"details\":\"Removes a leaf from the tree.\",\"params\":{\"leaf\":\": Leaf to be removed.\",\"proofPathIndices\":\": Path of the proof of membership.\",\"proofSiblings\":\": Array of the sibling nodes of the proof of membership.\",\"self\":\": Tree data.\"}},\"update(BinaryIMTData storage,uint256,uint256,uint256[],uint8[])\":{\"details\":\"Updates a leaf in the tree.\",\"params\":{\"leaf\":\": Leaf to be updated.\",\"newLeaf\":\": New leaf.\",\"proofPathIndices\":\": Path of the proof of membership.\",\"proofSiblings\":\": Array of the sibling nodes of the proof of membership.\",\"self\":\": Tree data.\"}}},\"title\":\"Incremental binary Merkle tree.\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@zk-kit/imt.sol/BinaryIMT.sol\":\"BinaryIMT\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\"]},\"sources\":{\"@zk-kit/imt.sol/BinaryIMT.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport {PoseidonT3} from \\\"poseidon-solidity/PoseidonT3.sol\\\";\\n\\n// Each incremental tree has certain properties and data that will\\n// be used to add new leaves.\\nstruct BinaryIMTData {\\n uint256 depth; // Depth of the tree (levels - 1).\\n uint256 root; // Root hash of the tree.\\n uint256 numberOfLeaves; // Number of leaves of the tree.\\n mapping(uint256 => uint256) zeroes; // Zero hashes used for empty nodes (level -> zero hash).\\n // The nodes of the subtrees used in the last addition of a leaf (level -> [left node, right node]).\\n mapping(uint256 => uint256[2]) lastSubtrees; // Caching these values is essential to efficient appends.\\n bool useDefaultZeroes;\\n}\\n\\n/// @title Incremental binary Merkle tree.\\n/// @dev The incremental tree allows to calculate the root hash each time a leaf is added, ensuring\\n/// the integrity of the tree.\\nlibrary BinaryIMT {\\n uint8 public constant MAX_DEPTH = 32;\\n uint256 public constant SNARK_SCALAR_FIELD =\\n 21888242871839275222246405745257275088548364400416034343698204186575808495617;\\n\\n uint256 public constant Z_0 = 0;\\n uint256 public constant Z_1 = 14744269619966411208579211824598458697587494354926760081771325075741142829156;\\n uint256 public constant Z_2 = 7423237065226347324353380772367382631490014989348495481811164164159255474657;\\n uint256 public constant Z_3 = 11286972368698509976183087595462810875513684078608517520839298933882497716792;\\n uint256 public constant Z_4 = 3607627140608796879659380071776844901612302623152076817094415224584923813162;\\n uint256 public constant Z_5 = 19712377064642672829441595136074946683621277828620209496774504837737984048981;\\n uint256 public constant Z_6 = 20775607673010627194014556968476266066927294572720319469184847051418138353016;\\n uint256 public constant Z_7 = 3396914609616007258851405644437304192397291162432396347162513310381425243293;\\n uint256 public constant Z_8 = 21551820661461729022865262380882070649935529853313286572328683688269863701601;\\n uint256 public constant Z_9 = 6573136701248752079028194407151022595060682063033565181951145966236778420039;\\n uint256 public constant Z_10 = 12413880268183407374852357075976609371175688755676981206018884971008854919922;\\n uint256 public constant Z_11 = 14271763308400718165336499097156975241954733520325982997864342600795471836726;\\n uint256 public constant Z_12 = 20066985985293572387227381049700832219069292839614107140851619262827735677018;\\n uint256 public constant Z_13 = 9394776414966240069580838672673694685292165040808226440647796406499139370960;\\n uint256 public constant Z_14 = 11331146992410411304059858900317123658895005918277453009197229807340014528524;\\n uint256 public constant Z_15 = 15819538789928229930262697811477882737253464456578333862691129291651619515538;\\n uint256 public constant Z_16 = 19217088683336594659449020493828377907203207941212636669271704950158751593251;\\n uint256 public constant Z_17 = 21035245323335827719745544373081896983162834604456827698288649288827293579666;\\n uint256 public constant Z_18 = 6939770416153240137322503476966641397417391950902474480970945462551409848591;\\n uint256 public constant Z_19 = 10941962436777715901943463195175331263348098796018438960955633645115732864202;\\n uint256 public constant Z_20 = 15019797232609675441998260052101280400536945603062888308240081994073687793470;\\n uint256 public constant Z_21 = 11702828337982203149177882813338547876343922920234831094975924378932809409969;\\n uint256 public constant Z_22 = 11217067736778784455593535811108456786943573747466706329920902520905755780395;\\n uint256 public constant Z_23 = 16072238744996205792852194127671441602062027943016727953216607508365787157389;\\n uint256 public constant Z_24 = 17681057402012993898104192736393849603097507831571622013521167331642182653248;\\n uint256 public constant Z_25 = 21694045479371014653083846597424257852691458318143380497809004364947786214945;\\n uint256 public constant Z_26 = 8163447297445169709687354538480474434591144168767135863541048304198280615192;\\n uint256 public constant Z_27 = 14081762237856300239452543304351251708585712948734528663957353575674639038357;\\n uint256 public constant Z_28 = 16619959921569409661790279042024627172199214148318086837362003702249041851090;\\n uint256 public constant Z_29 = 7022159125197495734384997711896547675021391130223237843255817587255104160365;\\n uint256 public constant Z_30 = 4114686047564160449611603615418567457008101555090703535405891656262658644463;\\n uint256 public constant Z_31 = 12549363297364877722388257367377629555213421373705596078299904496781819142130;\\n uint256 public constant Z_32 = 21443572485391568159800782191812935835534334817699172242223315142338162256601;\\n\\n function defaultZero(uint256 index) public pure returns (uint256) {\\n if (index == 0) return Z_0;\\n if (index == 1) return Z_1;\\n if (index == 2) return Z_2;\\n if (index == 3) return Z_3;\\n if (index == 4) return Z_4;\\n if (index == 5) return Z_5;\\n if (index == 6) return Z_6;\\n if (index == 7) return Z_7;\\n if (index == 8) return Z_8;\\n if (index == 9) return Z_9;\\n if (index == 10) return Z_10;\\n if (index == 11) return Z_11;\\n if (index == 12) return Z_12;\\n if (index == 13) return Z_13;\\n if (index == 14) return Z_14;\\n if (index == 15) return Z_15;\\n if (index == 16) return Z_16;\\n if (index == 17) return Z_17;\\n if (index == 18) return Z_18;\\n if (index == 19) return Z_19;\\n if (index == 20) return Z_20;\\n if (index == 21) return Z_21;\\n if (index == 22) return Z_22;\\n if (index == 23) return Z_23;\\n if (index == 24) return Z_24;\\n if (index == 25) return Z_25;\\n if (index == 26) return Z_26;\\n if (index == 27) return Z_27;\\n if (index == 28) return Z_28;\\n if (index == 29) return Z_29;\\n if (index == 30) return Z_30;\\n if (index == 31) return Z_31;\\n if (index == 32) return Z_32;\\n revert(\\\"IncrementalBinaryTree: defaultZero bad index\\\");\\n }\\n\\n /// @dev Initializes a tree.\\n /// @param self: Tree data.\\n /// @param depth: Depth of the tree.\\n /// @param zero: Zero value to be used.\\n function init(BinaryIMTData storage self, uint256 depth, uint256 zero) public {\\n require(zero < SNARK_SCALAR_FIELD, \\\"BinaryIMT: leaf must be < SNARK_SCALAR_FIELD\\\");\\n require(depth > 0 && depth <= MAX_DEPTH, \\\"BinaryIMT: tree depth must be between 1 and 32\\\");\\n\\n self.depth = depth;\\n\\n for (uint8 i = 0; i < depth; ) {\\n self.zeroes[i] = zero;\\n zero = PoseidonT3.hash([zero, zero]);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n self.root = zero;\\n }\\n\\n function initWithDefaultZeroes(BinaryIMTData storage self, uint256 depth) public {\\n require(depth > 0 && depth <= MAX_DEPTH, \\\"BinaryIMT: tree depth must be between 1 and 32\\\");\\n\\n self.depth = depth;\\n self.useDefaultZeroes = true;\\n\\n self.root = defaultZero(depth);\\n }\\n\\n /// @dev Inserts a leaf in the tree.\\n /// @param self: Tree data.\\n /// @param leaf: Leaf to be inserted.\\n function insert(BinaryIMTData storage self, uint256 leaf) public returns (uint256) {\\n uint256 depth = self.depth;\\n\\n require(leaf < SNARK_SCALAR_FIELD, \\\"BinaryIMT: leaf must be < SNARK_SCALAR_FIELD\\\");\\n require(self.numberOfLeaves < 2 ** depth, \\\"BinaryIMT: tree is full\\\");\\n\\n uint256 index = self.numberOfLeaves;\\n uint256 hash = leaf;\\n bool useDefaultZeroes = self.useDefaultZeroes;\\n\\n for (uint8 i = 0; i < depth; ) {\\n if (index & 1 == 0) {\\n self.lastSubtrees[i] = [hash, useDefaultZeroes ? defaultZero(i) : self.zeroes[i]];\\n } else {\\n self.lastSubtrees[i][1] = hash;\\n }\\n\\n hash = PoseidonT3.hash(self.lastSubtrees[i]);\\n index >>= 1;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n self.root = hash;\\n self.numberOfLeaves += 1;\\n return hash;\\n }\\n\\n /// @dev Updates a leaf in the tree.\\n /// @param self: Tree data.\\n /// @param leaf: Leaf to be updated.\\n /// @param newLeaf: New leaf.\\n /// @param proofSiblings: Array of the sibling nodes of the proof of membership.\\n /// @param proofPathIndices: Path of the proof of membership.\\n function update(\\n BinaryIMTData storage self,\\n uint256 leaf,\\n uint256 newLeaf,\\n uint256[] calldata proofSiblings,\\n uint8[] calldata proofPathIndices\\n ) public {\\n require(newLeaf != leaf, \\\"BinaryIMT: new leaf cannot be the same as the old one\\\");\\n require(newLeaf < SNARK_SCALAR_FIELD, \\\"BinaryIMT: new leaf must be < SNARK_SCALAR_FIELD\\\");\\n require(verify(self, leaf, proofSiblings, proofPathIndices), \\\"BinaryIMT: leaf is not part of the tree\\\");\\n\\n uint256 depth = self.depth;\\n uint256 hash = newLeaf;\\n uint256 updateIndex;\\n\\n for (uint8 i = 0; i < depth; ) {\\n updateIndex |= uint256(proofPathIndices[i]) << uint256(i);\\n\\n if (proofPathIndices[i] == 0) {\\n if (proofSiblings[i] == self.lastSubtrees[i][1]) {\\n self.lastSubtrees[i][0] = hash;\\n }\\n\\n hash = PoseidonT3.hash([hash, proofSiblings[i]]);\\n } else {\\n if (proofSiblings[i] == self.lastSubtrees[i][0]) {\\n self.lastSubtrees[i][1] = hash;\\n }\\n\\n hash = PoseidonT3.hash([proofSiblings[i], hash]);\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n require(updateIndex < self.numberOfLeaves, \\\"BinaryIMT: leaf index out of range\\\");\\n\\n self.root = hash;\\n }\\n\\n /// @dev Removes a leaf from the tree.\\n /// @param self: Tree data.\\n /// @param leaf: Leaf to be removed.\\n /// @param proofSiblings: Array of the sibling nodes of the proof of membership.\\n /// @param proofPathIndices: Path of the proof of membership.\\n function remove(\\n BinaryIMTData storage self,\\n uint256 leaf,\\n uint256[] calldata proofSiblings,\\n uint8[] calldata proofPathIndices\\n ) public {\\n update(self, leaf, self.useDefaultZeroes ? Z_0 : self.zeroes[0], proofSiblings, proofPathIndices);\\n }\\n\\n /// @dev Verify if the path is correct and the leaf is part of the tree.\\n /// @param self: Tree data.\\n /// @param leaf: Leaf to be removed.\\n /// @param proofSiblings: Array of the sibling nodes of the proof of membership.\\n /// @param proofPathIndices: Path of the proof of membership.\\n /// @return True or false.\\n function verify(\\n BinaryIMTData storage self,\\n uint256 leaf,\\n uint256[] calldata proofSiblings,\\n uint8[] calldata proofPathIndices\\n ) private view returns (bool) {\\n require(leaf < SNARK_SCALAR_FIELD, \\\"BinaryIMT: leaf must be < SNARK_SCALAR_FIELD\\\");\\n uint256 depth = self.depth;\\n require(\\n proofPathIndices.length == depth && proofSiblings.length == depth,\\n \\\"BinaryIMT: length of path is not correct\\\"\\n );\\n\\n uint256 hash = leaf;\\n\\n for (uint8 i = 0; i < depth; ) {\\n require(proofSiblings[i] < SNARK_SCALAR_FIELD, \\\"BinaryIMT: sibling node must be < SNARK_SCALAR_FIELD\\\");\\n\\n require(proofPathIndices[i] == 1 || proofPathIndices[i] == 0, \\\"BinaryIMT: path index is neither 0 nor 1\\\");\\n\\n if (proofPathIndices[i] == 0) {\\n hash = PoseidonT3.hash([hash, proofSiblings[i]]);\\n } else {\\n hash = PoseidonT3.hash([proofSiblings[i], hash]);\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return hash == self.root;\\n }\\n}\\n\",\"keccak256\":\"0xdc7e7cc2e8176bb76bbd788ae2d50a4e9db13d3256d8b07a695856e073a78586\",\"license\":\"MIT\"},\"poseidon-solidity/PoseidonT3.sol\":{\"content\":\"/// SPDX-License-Identifier: MIT\\npragma solidity >=0.7.0;\\n\\nlibrary PoseidonT3 {\\n uint constant M00 = 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b;\\n uint constant M01 = 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771;\\n uint constant M02 = 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7;\\n uint constant M10 = 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0;\\n uint constant M11 = 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23;\\n uint constant M12 = 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911;\\n\\n // See here for a simplified implementation: https://github.com/vimwitch/poseidon-solidity/blob/e57becdabb65d99fdc586fe1e1e09e7108202d53/contracts/Poseidon.sol#L40\\n // Inspired by: https://github.com/iden3/circomlibjs/blob/v0.0.8/src/poseidon_slow.js\\n function hash(uint[2] memory) public pure returns (uint) {\\n assembly {\\n let F := 21888242871839275222246405745257275088548364400416034343698204186575808495617\\n let M20 := 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d\\n let M21 := 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa\\n let M22 := 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0\\n\\n // load the inputs from memory\\n let state1 := add(mod(mload(0x80), F), 0x00f1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864)\\n let state2 := add(mod(mload(0xa0), F), 0x08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5)\\n let scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n scratch0 := add(\\n 0x2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d0,\\n add(add(15452833169820924772166449970675545095234312153403844297388521437673434406763, mulmod(state1, M10, F)), mulmod(state2, M20, F))\\n )\\n let scratch1 := add(\\n 0x2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf2,\\n add(add(18674271267752038776579386132900109523609358935013267566297499497165104279117, mulmod(state1, M11, F)), mulmod(state2, M21, F))\\n )\\n let scratch2 := add(\\n 0x0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa,\\n add(add(14817777843080276494683266178512808687156649753153012854386334860566696099579, mulmod(state1, M12, F)), mulmod(state2, M22, F))\\n )\\n let state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc632, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n scratch0 := add(0x15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c8705, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd1, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x005032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c887, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da53, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0081c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb38, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c502, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x00ef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba89, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c5, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e4, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e13, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a90035, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db69, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b8, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c77, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x002e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x00b9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c3512, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x00248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a808, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f09, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e8284, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd800, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f178, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e504233, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d59, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f88948, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d142, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c0, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a58, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d01, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc792, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea6111, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa336, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d6, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f451, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf77, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc630, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c2320, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n scratch0 := add(0x0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f8, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e4228325161, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n\\n mstore(0x0, mod(add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)), F))\\n\\n return(0, 0x20)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0102caa303bbc6690508f3615604f7730789ed990058c9513a87ccb30e4835be\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x612e3f610053600b82828239805160001a607314610046577f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361061025d5760003560e01c806365ad985e11610150578063b1849a1a116100cd578063c6675bbf11610091578063c6675bbf146106d9578063c7fadc67146106f7578063ccbad17414610715578063d2aa5c6214610733578063eb095a7d14610751578063f49babe61461076f5761025d565b8063b1849a1a14610638578063b410396a14610656578063b5f35eb914610674578063c0c5bf6714610692578063c2ad38d4146106b05761025d565b80639bf21071116101145780639bf21071146105a25780639cda4774146105c0578063a27154ba146105de578063a3205067146105fc578063af9d047c1461061a5761025d565b806365ad985e1461050c57806365f7bec31461052a5780638836ccf61461054857806389d0e9321461056657806394804215146105845761025d565b806344f9e1ac116101de578063583f8af4116101a2578063583f8af41461046b5780635da707d4146104895780635fcde067146104a757806362cff85e146104c557806364048bf2146104ee5761025d565b806344f9e1ac146103d557806352be1fb8146103f357806354f5a9011461041157806355005f761461042f578063565b427e1461044d5761025d565b806325c2cd121161022557806325c2cd121461033457806330314fc014610352578063309ec3c31461037057806334a84bb41461038e5780633994a957146103b75761025d565b80631150554414610262578063143dc3831461028057806314d8c626146102bd57806318f18fb1146102e65780631ddbea0014610316575b600080fd5b61026a61078d565b6040516102779190611fca565b60405180910390f35b81801561028c57600080fd5b506102a760048036038101906102a29190612051565b6107b1565b6040516102b49190611fca565b60405180910390f35b8180156102c957600080fd5b506102e460048036038101906102df9190612051565b610a24565b005b61030060048036038101906102fb9190612091565b610ab2565b60405161030d9190611fca565b60405180910390f35b61031e611104565b60405161032b9190611fca565b60405180910390f35b61033c611128565b6040516103499190611fca565b60405180910390f35b61035a61114c565b6040516103679190611fca565b60405180910390f35b610378611170565b6040516103859190611fca565b60405180910390f35b81801561039a57600080fd5b506103b560048036038101906103b091906120be565b611194565b005b6103bf611325565b6040516103cc9190611fca565b60405180910390f35b6103dd611349565b6040516103ea9190611fca565b60405180910390f35b6103fb61136d565b6040516104089190611fca565b60405180910390f35b610419611391565b6040516104269190611fca565b60405180910390f35b6104376113b5565b6040516104449190611fca565b60405180910390f35b6104556113d9565b6040516104629190611fca565b60405180910390f35b6104736113fd565b6040516104809190611fca565b60405180910390f35b610491611421565b60405161049e9190611fca565b60405180910390f35b6104af611445565b6040516104bc9190611fca565b60405180910390f35b8180156104d157600080fd5b506104ec60048036038101906104e791906121cc565b611469565b005b6104f66114b3565b6040516105039190611fca565b60405180910390f35b6105146114d7565b6040516105219190611fca565b60405180910390f35b6105326114dc565b60405161053f9190611fca565b60405180910390f35b610550611500565b60405161055d9190611fca565b60405180910390f35b61056e611524565b60405161057b9190611fca565b60405180910390f35b61058c611548565b6040516105999190611fca565b60405180910390f35b6105aa61156c565b6040516105b79190611fca565b60405180910390f35b6105c8611590565b6040516105d59190611fca565b60405180910390f35b6105e66115b4565b6040516105f3919061228f565b60405180910390f35b6106046115b9565b6040516106119190611fca565b60405180910390f35b6106226115dd565b60405161062f9190611fca565b60405180910390f35b610640611601565b60405161064d9190611fca565b60405180910390f35b61065e611625565b60405161066b9190611fca565b60405180910390f35b61067c611649565b6040516106899190611fca565b60405180910390f35b61069a61166d565b6040516106a79190611fca565b60405180910390f35b8180156106bc57600080fd5b506106d760048036038101906106d291906122aa565b611691565b005b6106e1611ad3565b6040516106ee9190611fca565b60405180910390f35b6106ff611af7565b60405161070c9190611fca565b60405180910390f35b61071d611b1b565b60405161072a9190611fca565b60405180910390f35b61073b611b3f565b6040516107489190611fca565b60405180910390f35b610759611b63565b6040516107669190611fca565b60405180910390f35b610777611b87565b6040516107849190611fca565b60405180910390f35b7f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce61151881565b600080836000015490507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001831061081d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610814906123e9565b60405180910390fd5b80600261082a919061256b565b84600201541061086f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161086690612602565b60405180910390fd5b600084600201549050600084905060008660050160009054906101000a900460ff16905060005b848160ff1610156109f1576000600185160361091c576040518060400160405280848152602001836108e0578960030160008460ff168152602001908152602001600020546108ed565b6108ec8360ff16610ab2565b5b8152508860040160008360ff168152602001908152602001600020906002610916929190611f54565b5061094e565b828860040160008360ff16815260200190815260200160002060016002811061094857610947612622565b5b01819055505b73beeeAcde37Bce9011326137a49Bd5CA8153E9FCD63561558fe8960040160008460ff1681526020019081526020016000206040518263ffffffff1660e01b815260040161099c9190612747565b602060405180830381865af41580156109b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109dd9190612777565b9250600184901c9350806001019050610896565b508187600101819055506001876002016000828254610a1091906127a4565b925050819055508194505050505092915050565b600081118015610a385750602060ff168111155b610a77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6e9061286c565b60405180910390fd5b80826000018190555060018260050160006101000a81548160ff021916908315150217905550610aa681610ab2565b82600101819055505050565b6000808203610ac457600090506110ff565b60018203610af4577f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b6486490506110ff565b60028203610b24577f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e190506110ff565b60038203610b54577f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d23890506110ff565b60048203610b84577f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a90506110ff565b60058203610bb4577f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f5590506110ff565b60068203610be4577f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d7890506110ff565b60078203610c14577f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d90506110ff565b60088203610c44577f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc6190506110ff565b60098203610c74577f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd74790506110ff565b600a8203610ca4577f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af290506110ff565b600b8203610cd4577f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d763690506110ff565b600c8203610d04577f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a90506110ff565b600d8203610d34577f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd090506110ff565b600e8203610d64577f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c90506110ff565b600f8203610d94577f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c9290506110ff565b60108203610dc4577f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba732390506110ff565b60118203610df4577f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b99290506110ff565b60128203610e24577f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f90506110ff565b60138203610e54577f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca90506110ff565b60148203610e84577f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e90506110ff565b60158203610eb4577f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b190506110ff565b60168203610ee4577f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b90506110ff565b60178203610f14577f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d90506110ff565b60188203610f44577f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed54090506110ff565b60198203610f74577f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae2190506110ff565b601a8203610fa4577f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce61151890506110ff565b601b8203610fd4577f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d27948379590506110ff565b601c8203611004577f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d290506110ff565b601d8203611034577f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d90506110ff565b601e8203611064577f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef90506110ff565b601f8203611094577f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff290506110ff565b602082036110c4577f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead990506110ff565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f6906128fe565b60405180910390fd5b919050565b7f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d81565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b7f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b81565b7f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b99281565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181106111f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ed906123e9565b60405180910390fd5b60008211801561120a5750602060ff168211155b611249576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112409061286c565b60405180910390fd5b81836000018190555060005b828160ff16101561131657818460030160008360ff1681526020019081526020016000208190555073beeeAcde37Bce9011326137a49Bd5CA8153E9FCD63561558fe6040518060400160405280858152602001858152506040518263ffffffff1660e01b81526004016112c89190612997565b602060405180830381865af41580156112e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113099190612777565b9150806001019050611255565b50808360010181905550505050565b7f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae2181565b7f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d281565b7f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e181565b7f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd081565b7f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f81565b7f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d7881565b7f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc6181565b7f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed54081565b7f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d81565b6114ab86868860050160009054906101000a900460ff1661149f57886003016000808152602001908152602001600020546114a2565b60005b87878787611691565b505050505050565b7f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca81565b600081565b7f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c81565b7f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d23881565b7f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba732381565b7f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd74781565b7f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a81565b7f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d81565b602081565b7f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c9281565b7f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef81565b7f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b181565b7f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d27948379581565b7f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e81565b7f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f5581565b8585036116d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ca90612a24565b60405180910390fd5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018510611735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172c90612ab6565b60405180910390fd5b611743878786868686611bab565b611782576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177990612b48565b60405180910390fd5b6000876000015490506000869050600080600090505b838160ff161015611a77578060ff1686868360ff168181106117bd576117bc612622565b5b90506020020160208101906117d29190612b94565b60ff16901b82179150600086868360ff168181106117f3576117f2612622565b5b90506020020160208101906118089190612b94565b60ff1603611940578a60040160008260ff16815260200190815260200160002060016002811061183b5761183a612622565b5b015488888360ff1681811061185357611852612622565b5b905060200201350361189157828b60040160008360ff16815260200190815260200160002060006002811061188b5761188a612622565b5b01819055505b73beeeAcde37Bce9011326137a49Bd5CA8153E9FCD63561558fe60405180604001604052808681526020018b8b8660ff168181106118d2576118d1612622565b5b905060200201358152506040518263ffffffff1660e01b81526004016118f89190612997565b602060405180830381865af4158015611915573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119399190612777565b9250611a6c565b8a60040160008260ff16815260200190815260200160002060006002811061196b5761196a612622565b5b015488888360ff1681811061198357611982612622565b5b90506020020135036119c157828b60040160008360ff1681526020019081526020016000206001600281106119bb576119ba612622565b5b01819055505b73beeeAcde37Bce9011326137a49Bd5CA8153E9FCD63561558fe60405180604001604052808b8b8660ff168181106119fc576119fb612622565b5b905060200201358152602001868152506040518263ffffffff1660e01b8152600401611a289190612997565b602060405180830381865af4158015611a45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a699190612777565b92505b806001019050611798565b5089600201548110611abe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab590612c33565b60405180910390fd5b818a6001018190555050505050505050505050565b7f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a81565b7f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff281565b7f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b6486481565b7f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d763681565b7f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af281565b7f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead981565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018610611c0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c06906123e9565b60405180910390fd5b6000876000015490508084849050148015611c2c57508086869050145b611c6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c6290612cc5565b60405180910390fd5b600087905060005b828160ff161015611f3e577f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000188888360ff16818110611cb557611cb4612622565b5b9050602002013510611cfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf390612d57565b60405180910390fd5b600186868360ff16818110611d1457611d13612622565b5b9050602002016020810190611d299190612b94565b60ff161480611d655750600086868360ff16818110611d4b57611d4a612622565b5b9050602002016020810190611d609190612b94565b60ff16145b611da4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9b90612de9565b60405180910390fd5b600086868360ff16818110611dbc57611dbb612622565b5b9050602002016020810190611dd19190612b94565b60ff1603611e885773beeeAcde37Bce9011326137a49Bd5CA8153E9FCD63561558fe60405180604001604052808581526020018b8b8660ff16818110611e1a57611e19612622565b5b905060200201358152506040518263ffffffff1660e01b8152600401611e409190612997565b602060405180830381865af4158015611e5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e819190612777565b9150611f33565b73beeeAcde37Bce9011326137a49Bd5CA8153E9FCD63561558fe60405180604001604052808b8b8660ff16818110611ec357611ec2612622565b5b905060200201358152602001858152506040518263ffffffff1660e01b8152600401611eef9190612997565b602060405180830381865af4158015611f0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f309190612777565b91505b806001019050611c73565b5088600101548114925050509695505050505050565b8260028101928215611f83579160200282015b82811115611f82578251825591602001919060010190611f67565b5b509050611f909190611f94565b5090565b5b80821115611fad576000816000905550600101611f95565b5090565b6000819050919050565b611fc481611fb1565b82525050565b6000602082019050611fdf6000830184611fbb565b92915050565b600080fd5b600080fd5b6000819050919050565b61200281611fef565b811461200d57600080fd5b50565b60008135905061201f81611ff9565b92915050565b61202e81611fb1565b811461203957600080fd5b50565b60008135905061204b81612025565b92915050565b6000806040838503121561206857612067611fe5565b5b600061207685828601612010565b92505060206120878582860161203c565b9150509250929050565b6000602082840312156120a7576120a6611fe5565b5b60006120b58482850161203c565b91505092915050565b6000806000606084860312156120d7576120d6611fe5565b5b60006120e586828701612010565b93505060206120f68682870161203c565b92505060406121078682870161203c565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f84011261213657612135612111565b5b8235905067ffffffffffffffff81111561215357612152612116565b5b60208301915083602082028301111561216f5761216e61211b565b5b9250929050565b60008083601f84011261218c5761218b612111565b5b8235905067ffffffffffffffff8111156121a9576121a8612116565b5b6020830191508360208202830111156121c5576121c461211b565b5b9250929050565b600080600080600080608087890312156121e9576121e8611fe5565b5b60006121f789828a01612010565b965050602061220889828a0161203c565b955050604087013567ffffffffffffffff81111561222957612228611fea565b5b61223589828a01612120565b9450945050606087013567ffffffffffffffff81111561225857612257611fea565b5b61226489828a01612176565b92509250509295509295509295565b600060ff82169050919050565b61228981612273565b82525050565b60006020820190506122a46000830184612280565b92915050565b600080600080600080600060a0888a0312156122c9576122c8611fe5565b5b60006122d78a828b01612010565b97505060206122e88a828b0161203c565b96505060406122f98a828b0161203c565b955050606088013567ffffffffffffffff81111561231a57612319611fea565b5b6123268a828b01612120565b9450945050608088013567ffffffffffffffff81111561234957612348611fea565b5b6123558a828b01612176565b925092505092959891949750929550565b600082825260208201905092915050565b7f42696e617279494d543a206c656166206d757374206265203c20534e41524b5f60008201527f5343414c41525f4649454c440000000000000000000000000000000000000000602082015250565b60006123d3602c83612366565b91506123de82612377565b604082019050919050565b60006020820190508181036000830152612402816123c6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008160011c9050919050565b6000808291508390505b600185111561248f5780860481111561246b5761246a612409565b5b600185161561247a5780820291505b808102905061248885612438565b945061244f565b94509492505050565b6000826124a85760019050612564565b816124b65760009050612564565b81600181146124cc57600281146124d657612505565b6001915050612564565b60ff8411156124e8576124e7612409565b5b8360020a9150848211156124ff576124fe612409565b5b50612564565b5060208310610133831016604e8410600b841016171561253a5782820a90508381111561253557612534612409565b5b612564565b6125478484846001612445565b9250905081840481111561255e5761255d612409565b5b81810290505b9392505050565b600061257682611fb1565b915061258183611fb1565b92506125ae7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484612498565b905092915050565b7f42696e617279494d543a20747265652069732066756c6c000000000000000000600082015250565b60006125ec601783612366565b91506125f7826125b6565b602082019050919050565b6000602082019050818103600083015261261b816125df565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060029050919050565b600081905092915050565b6000819050919050565b61267a81611fb1565b82525050565b600061268c8383612671565b60208301905092915050565b60008160001c9050919050565b6000819050919050565b60006126c26126bd83612698565b6126a5565b9050919050565b60006126d582546126af565b9050919050565b6000600182019050919050565b6126f281612651565b6126fc818461265c565b925061270782612667565b8060005b8381101561273f5761271c826126c9565b6127268782612680565b9650612731836126dc565b92505060018101905061270b565b505050505050565b600060408201905061275c60008301846126e9565b92915050565b60008151905061277181612025565b92915050565b60006020828403121561278d5761278c611fe5565b5b600061279b84828501612762565b91505092915050565b60006127af82611fb1565b91506127ba83611fb1565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156127ef576127ee612409565b5b828201905092915050565b7f42696e617279494d543a2074726565206465707468206d75737420626520626560008201527f747765656e203120616e64203332000000000000000000000000000000000000602082015250565b6000612856602e83612366565b9150612861826127fa565b604082019050919050565b6000602082019050818103600083015261288581612849565b9050919050565b7f496e6372656d656e74616c42696e617279547265653a2064656661756c745a6560008201527f726f2062616420696e6465780000000000000000000000000000000000000000602082015250565b60006128e8602c83612366565b91506128f38261288c565b604082019050919050565b60006020820190508181036000830152612917816128db565b9050919050565b600060029050919050565b6000819050919050565b6000602082019050919050565b6129498161291e565b612953818461265c565b925061295e82612929565b8060005b8381101561298f5781516129768782612680565b965061298183612933565b925050600181019050612962565b505050505050565b60006040820190506129ac6000830184612940565b92915050565b7f42696e617279494d543a206e6577206c6561662063616e6e6f7420626520746860008201527f652073616d6520617320746865206f6c64206f6e650000000000000000000000602082015250565b6000612a0e603583612366565b9150612a19826129b2565b604082019050919050565b60006020820190508181036000830152612a3d81612a01565b9050919050565b7f42696e617279494d543a206e6577206c656166206d757374206265203c20534e60008201527f41524b5f5343414c41525f4649454c4400000000000000000000000000000000602082015250565b6000612aa0603083612366565b9150612aab82612a44565b604082019050919050565b60006020820190508181036000830152612acf81612a93565b9050919050565b7f42696e617279494d543a206c656166206973206e6f742070617274206f66207460008201527f6865207472656500000000000000000000000000000000000000000000000000602082015250565b6000612b32602783612366565b9150612b3d82612ad6565b604082019050919050565b60006020820190508181036000830152612b6181612b25565b9050919050565b612b7181612273565b8114612b7c57600080fd5b50565b600081359050612b8e81612b68565b92915050565b600060208284031215612baa57612ba9611fe5565b5b6000612bb884828501612b7f565b91505092915050565b7f42696e617279494d543a206c65616620696e646578206f7574206f662072616e60008201527f6765000000000000000000000000000000000000000000000000000000000000602082015250565b6000612c1d602283612366565b9150612c2882612bc1565b604082019050919050565b60006020820190508181036000830152612c4c81612c10565b9050919050565b7f42696e617279494d543a206c656e677468206f662070617468206973206e6f7460008201527f20636f7272656374000000000000000000000000000000000000000000000000602082015250565b6000612caf602883612366565b9150612cba82612c53565b604082019050919050565b60006020820190508181036000830152612cde81612ca2565b9050919050565b7f42696e617279494d543a207369626c696e67206e6f6465206d7573742062652060008201527f3c20534e41524b5f5343414c41525f4649454c44000000000000000000000000602082015250565b6000612d41603483612366565b9150612d4c82612ce5565b604082019050919050565b60006020820190508181036000830152612d7081612d34565b9050919050565b7f42696e617279494d543a207061746820696e646578206973206e65697468657260008201527f2030206e6f722031000000000000000000000000000000000000000000000000602082015250565b6000612dd3602883612366565b9150612dde82612d77565b604082019050919050565b60006020820190508181036000830152612e0281612dc6565b905091905056fea2646970667358221220589cbf72cc2d84eab9c18913d1987756da4f6f0cf670db3e3b48633df0cb1f5764736f6c634300080f0033", + "deployedBytecode": "0x730000000000000000000000000000000000000000301460806040526004361061025d5760003560e01c806365ad985e11610150578063b1849a1a116100cd578063c6675bbf11610091578063c6675bbf146106d9578063c7fadc67146106f7578063ccbad17414610715578063d2aa5c6214610733578063eb095a7d14610751578063f49babe61461076f5761025d565b8063b1849a1a14610638578063b410396a14610656578063b5f35eb914610674578063c0c5bf6714610692578063c2ad38d4146106b05761025d565b80639bf21071116101145780639bf21071146105a25780639cda4774146105c0578063a27154ba146105de578063a3205067146105fc578063af9d047c1461061a5761025d565b806365ad985e1461050c57806365f7bec31461052a5780638836ccf61461054857806389d0e9321461056657806394804215146105845761025d565b806344f9e1ac116101de578063583f8af4116101a2578063583f8af41461046b5780635da707d4146104895780635fcde067146104a757806362cff85e146104c557806364048bf2146104ee5761025d565b806344f9e1ac146103d557806352be1fb8146103f357806354f5a9011461041157806355005f761461042f578063565b427e1461044d5761025d565b806325c2cd121161022557806325c2cd121461033457806330314fc014610352578063309ec3c31461037057806334a84bb41461038e5780633994a957146103b75761025d565b80631150554414610262578063143dc3831461028057806314d8c626146102bd57806318f18fb1146102e65780631ddbea0014610316575b600080fd5b61026a61078d565b6040516102779190611fca565b60405180910390f35b81801561028c57600080fd5b506102a760048036038101906102a29190612051565b6107b1565b6040516102b49190611fca565b60405180910390f35b8180156102c957600080fd5b506102e460048036038101906102df9190612051565b610a24565b005b61030060048036038101906102fb9190612091565b610ab2565b60405161030d9190611fca565b60405180910390f35b61031e611104565b60405161032b9190611fca565b60405180910390f35b61033c611128565b6040516103499190611fca565b60405180910390f35b61035a61114c565b6040516103679190611fca565b60405180910390f35b610378611170565b6040516103859190611fca565b60405180910390f35b81801561039a57600080fd5b506103b560048036038101906103b091906120be565b611194565b005b6103bf611325565b6040516103cc9190611fca565b60405180910390f35b6103dd611349565b6040516103ea9190611fca565b60405180910390f35b6103fb61136d565b6040516104089190611fca565b60405180910390f35b610419611391565b6040516104269190611fca565b60405180910390f35b6104376113b5565b6040516104449190611fca565b60405180910390f35b6104556113d9565b6040516104629190611fca565b60405180910390f35b6104736113fd565b6040516104809190611fca565b60405180910390f35b610491611421565b60405161049e9190611fca565b60405180910390f35b6104af611445565b6040516104bc9190611fca565b60405180910390f35b8180156104d157600080fd5b506104ec60048036038101906104e791906121cc565b611469565b005b6104f66114b3565b6040516105039190611fca565b60405180910390f35b6105146114d7565b6040516105219190611fca565b60405180910390f35b6105326114dc565b60405161053f9190611fca565b60405180910390f35b610550611500565b60405161055d9190611fca565b60405180910390f35b61056e611524565b60405161057b9190611fca565b60405180910390f35b61058c611548565b6040516105999190611fca565b60405180910390f35b6105aa61156c565b6040516105b79190611fca565b60405180910390f35b6105c8611590565b6040516105d59190611fca565b60405180910390f35b6105e66115b4565b6040516105f3919061228f565b60405180910390f35b6106046115b9565b6040516106119190611fca565b60405180910390f35b6106226115dd565b60405161062f9190611fca565b60405180910390f35b610640611601565b60405161064d9190611fca565b60405180910390f35b61065e611625565b60405161066b9190611fca565b60405180910390f35b61067c611649565b6040516106899190611fca565b60405180910390f35b61069a61166d565b6040516106a79190611fca565b60405180910390f35b8180156106bc57600080fd5b506106d760048036038101906106d291906122aa565b611691565b005b6106e1611ad3565b6040516106ee9190611fca565b60405180910390f35b6106ff611af7565b60405161070c9190611fca565b60405180910390f35b61071d611b1b565b60405161072a9190611fca565b60405180910390f35b61073b611b3f565b6040516107489190611fca565b60405180910390f35b610759611b63565b6040516107669190611fca565b60405180910390f35b610777611b87565b6040516107849190611fca565b60405180910390f35b7f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce61151881565b600080836000015490507f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001831061081d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610814906123e9565b60405180910390fd5b80600261082a919061256b565b84600201541061086f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161086690612602565b60405180910390fd5b600084600201549050600084905060008660050160009054906101000a900460ff16905060005b848160ff1610156109f1576000600185160361091c576040518060400160405280848152602001836108e0578960030160008460ff168152602001908152602001600020546108ed565b6108ec8360ff16610ab2565b5b8152508860040160008360ff168152602001908152602001600020906002610916929190611f54565b5061094e565b828860040160008360ff16815260200190815260200160002060016002811061094857610947612622565b5b01819055505b73__$75f79a42d9bcbdbb69ad79ebd80f556f39$__63561558fe8960040160008460ff1681526020019081526020016000206040518263ffffffff1660e01b815260040161099c9190612747565b602060405180830381865af41580156109b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109dd9190612777565b9250600184901c9350806001019050610896565b508187600101819055506001876002016000828254610a1091906127a4565b925050819055508194505050505092915050565b600081118015610a385750602060ff168111155b610a77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6e9061286c565b60405180910390fd5b80826000018190555060018260050160006101000a81548160ff021916908315150217905550610aa681610ab2565b82600101819055505050565b6000808203610ac457600090506110ff565b60018203610af4577f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b6486490506110ff565b60028203610b24577f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e190506110ff565b60038203610b54577f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d23890506110ff565b60048203610b84577f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a90506110ff565b60058203610bb4577f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f5590506110ff565b60068203610be4577f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d7890506110ff565b60078203610c14577f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d90506110ff565b60088203610c44577f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc6190506110ff565b60098203610c74577f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd74790506110ff565b600a8203610ca4577f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af290506110ff565b600b8203610cd4577f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d763690506110ff565b600c8203610d04577f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a90506110ff565b600d8203610d34577f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd090506110ff565b600e8203610d64577f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c90506110ff565b600f8203610d94577f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c9290506110ff565b60108203610dc4577f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba732390506110ff565b60118203610df4577f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b99290506110ff565b60128203610e24577f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f90506110ff565b60138203610e54577f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca90506110ff565b60148203610e84577f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e90506110ff565b60158203610eb4577f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b190506110ff565b60168203610ee4577f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b90506110ff565b60178203610f14577f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d90506110ff565b60188203610f44577f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed54090506110ff565b60198203610f74577f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae2190506110ff565b601a8203610fa4577f120c58f143d491e95902f7f5277778a2e0ad5168f6add75669932630ce61151890506110ff565b601b8203610fd4577f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d27948379590506110ff565b601c8203611004577f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d290506110ff565b601d8203611034577f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d90506110ff565b601e8203611064577f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef90506110ff565b601f8203611094577f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff290506110ff565b602082036110c4577f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead990506110ff565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f6906128fe565b60405180910390fd5b919050565b7f2388909415230d1b4d1304d2d54f473a628338f2efad83fadf05644549d2538d81565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b7f18cca2a66b5c0787981e69aefd84852d74af0e93ef4912b4648c05f722efe52b81565b7f2e8186e558698ec1c67af9c14d463ffc470043c9c2988b954d75dd643f36b99281565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181106111f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ed906123e9565b60405180910390fd5b60008211801561120a5750602060ff168211155b611249576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112409061286c565b60405180910390fd5b81836000018190555060005b828160ff16101561131657818460030160008360ff1681526020019081526020016000208190555073__$75f79a42d9bcbdbb69ad79ebd80f556f39$__63561558fe6040518060400160405280858152602001858152506040518263ffffffff1660e01b81526004016112c89190612997565b602060405180830381865af41580156112e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113099190612777565b9150806001019050611255565b50808360010181905550505050565b7f2ff6650540f629fd5711a0bc74fc0d28dcb230b9392583e5f8d59696dde6ae2181565b7f24be905fa71335e14c638cc0f66a8623a826e768068a9e968bb1a1dde18a72d281565b7f1069673dcdb12263df301a6ff584a7ec261a44cb9dc68df067a4774460b1f1e181565b7f14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd081565b7f0f57c5571e9a4eab49e2c8cf050dae948aef6ead647392273546249d1c1ff10f81565b7f2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d7881565b7f2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc6181565b7f27171fb4a97b6cc0e9e8f543b5294de866a2af2c9c8d0b1d96e673e4529ed54081565b7f078295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d81565b6114ab86868860050160009054906101000a900460ff1661149f57886003016000808152602001908152602001600020546114a2565b60005b87878787611691565b505050505050565b7f1830ee67b5fb554ad5f63d4388800e1cfe78e310697d46e43c9ce36134f72cca81565b600081565b7f190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c81565b7f18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d23881565b7f2a7c7c9b6ce5880b9f6f228d72bf6a575a526f29c66ecceef8b753d38bba732381565b7f0e884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd74781565b7f2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a81565b7f0f8666b62ed17491c50ceadead57d4cd597ef3821d65c328744c74e553dac26d81565b602081565b7f22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c9281565b7f0918d46bf52d98b034413f4a1a1c41594e7a7a3f6ae08cb43d1a2a230e1959ef81565b7f19df90ec844ebc4ffeebd866f33859b0c051d8c958ee3aa88f8f8df3db91a5b181565b7f1f21feb70d3f21b07bf853d5e5db03071ec495a0a565a21da2d665d27948379581565b7f2134e76ac5d21aab186c2be1dd8f84ee880a1e46eaf712f9d371b6df22191f3e81565b7f2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f5581565b8585036116d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ca90612a24565b60405180910390fd5b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018510611735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172c90612ab6565b60405180910390fd5b611743878786868686611bab565b611782576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177990612b48565b60405180910390fd5b6000876000015490506000869050600080600090505b838160ff161015611a77578060ff1686868360ff168181106117bd576117bc612622565b5b90506020020160208101906117d29190612b94565b60ff16901b82179150600086868360ff168181106117f3576117f2612622565b5b90506020020160208101906118089190612b94565b60ff1603611940578a60040160008260ff16815260200190815260200160002060016002811061183b5761183a612622565b5b015488888360ff1681811061185357611852612622565b5b905060200201350361189157828b60040160008360ff16815260200190815260200160002060006002811061188b5761188a612622565b5b01819055505b73__$75f79a42d9bcbdbb69ad79ebd80f556f39$__63561558fe60405180604001604052808681526020018b8b8660ff168181106118d2576118d1612622565b5b905060200201358152506040518263ffffffff1660e01b81526004016118f89190612997565b602060405180830381865af4158015611915573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119399190612777565b9250611a6c565b8a60040160008260ff16815260200190815260200160002060006002811061196b5761196a612622565b5b015488888360ff1681811061198357611982612622565b5b90506020020135036119c157828b60040160008360ff1681526020019081526020016000206001600281106119bb576119ba612622565b5b01819055505b73__$75f79a42d9bcbdbb69ad79ebd80f556f39$__63561558fe60405180604001604052808b8b8660ff168181106119fc576119fb612622565b5b905060200201358152602001868152506040518263ffffffff1660e01b8152600401611a289190612997565b602060405180830381865af4158015611a45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a699190612777565b92505b806001019050611798565b5089600201548110611abe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab590612c33565b60405180910390fd5b818a6001018190555050505050505050505050565b7f07f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a81565b7f1bbeb01b4c479ecde76917645e404dfa2e26f90d0afc5a65128513ad375c5ff281565b7f2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b6486481565b7f1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d763681565b7f1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af281565b7f2f68a1c58e257e42a17a6c61dff5551ed560b9922ab119d5ac8e184c9734ead981565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018610611c0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c06906123e9565b60405180910390fd5b6000876000015490508084849050148015611c2c57508086869050145b611c6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c6290612cc5565b60405180910390fd5b600087905060005b828160ff161015611f3e577f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000188888360ff16818110611cb557611cb4612622565b5b9050602002013510611cfc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf390612d57565b60405180910390fd5b600186868360ff16818110611d1457611d13612622565b5b9050602002016020810190611d299190612b94565b60ff161480611d655750600086868360ff16818110611d4b57611d4a612622565b5b9050602002016020810190611d609190612b94565b60ff16145b611da4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9b90612de9565b60405180910390fd5b600086868360ff16818110611dbc57611dbb612622565b5b9050602002016020810190611dd19190612b94565b60ff1603611e885773__$75f79a42d9bcbdbb69ad79ebd80f556f39$__63561558fe60405180604001604052808581526020018b8b8660ff16818110611e1a57611e19612622565b5b905060200201358152506040518263ffffffff1660e01b8152600401611e409190612997565b602060405180830381865af4158015611e5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e819190612777565b9150611f33565b73__$75f79a42d9bcbdbb69ad79ebd80f556f39$__63561558fe60405180604001604052808b8b8660ff16818110611ec357611ec2612622565b5b905060200201358152602001858152506040518263ffffffff1660e01b8152600401611eef9190612997565b602060405180830381865af4158015611f0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f309190612777565b91505b806001019050611c73565b5088600101548114925050509695505050505050565b8260028101928215611f83579160200282015b82811115611f82578251825591602001919060010190611f67565b5b509050611f909190611f94565b5090565b5b80821115611fad576000816000905550600101611f95565b5090565b6000819050919050565b611fc481611fb1565b82525050565b6000602082019050611fdf6000830184611fbb565b92915050565b600080fd5b600080fd5b6000819050919050565b61200281611fef565b811461200d57600080fd5b50565b60008135905061201f81611ff9565b92915050565b61202e81611fb1565b811461203957600080fd5b50565b60008135905061204b81612025565b92915050565b6000806040838503121561206857612067611fe5565b5b600061207685828601612010565b92505060206120878582860161203c565b9150509250929050565b6000602082840312156120a7576120a6611fe5565b5b60006120b58482850161203c565b91505092915050565b6000806000606084860312156120d7576120d6611fe5565b5b60006120e586828701612010565b93505060206120f68682870161203c565b92505060406121078682870161203c565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f84011261213657612135612111565b5b8235905067ffffffffffffffff81111561215357612152612116565b5b60208301915083602082028301111561216f5761216e61211b565b5b9250929050565b60008083601f84011261218c5761218b612111565b5b8235905067ffffffffffffffff8111156121a9576121a8612116565b5b6020830191508360208202830111156121c5576121c461211b565b5b9250929050565b600080600080600080608087890312156121e9576121e8611fe5565b5b60006121f789828a01612010565b965050602061220889828a0161203c565b955050604087013567ffffffffffffffff81111561222957612228611fea565b5b61223589828a01612120565b9450945050606087013567ffffffffffffffff81111561225857612257611fea565b5b61226489828a01612176565b92509250509295509295509295565b600060ff82169050919050565b61228981612273565b82525050565b60006020820190506122a46000830184612280565b92915050565b600080600080600080600060a0888a0312156122c9576122c8611fe5565b5b60006122d78a828b01612010565b97505060206122e88a828b0161203c565b96505060406122f98a828b0161203c565b955050606088013567ffffffffffffffff81111561231a57612319611fea565b5b6123268a828b01612120565b9450945050608088013567ffffffffffffffff81111561234957612348611fea565b5b6123558a828b01612176565b925092505092959891949750929550565b600082825260208201905092915050565b7f42696e617279494d543a206c656166206d757374206265203c20534e41524b5f60008201527f5343414c41525f4649454c440000000000000000000000000000000000000000602082015250565b60006123d3602c83612366565b91506123de82612377565b604082019050919050565b60006020820190508181036000830152612402816123c6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008160011c9050919050565b6000808291508390505b600185111561248f5780860481111561246b5761246a612409565b5b600185161561247a5780820291505b808102905061248885612438565b945061244f565b94509492505050565b6000826124a85760019050612564565b816124b65760009050612564565b81600181146124cc57600281146124d657612505565b6001915050612564565b60ff8411156124e8576124e7612409565b5b8360020a9150848211156124ff576124fe612409565b5b50612564565b5060208310610133831016604e8410600b841016171561253a5782820a90508381111561253557612534612409565b5b612564565b6125478484846001612445565b9250905081840481111561255e5761255d612409565b5b81810290505b9392505050565b600061257682611fb1565b915061258183611fb1565b92506125ae7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484612498565b905092915050565b7f42696e617279494d543a20747265652069732066756c6c000000000000000000600082015250565b60006125ec601783612366565b91506125f7826125b6565b602082019050919050565b6000602082019050818103600083015261261b816125df565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060029050919050565b600081905092915050565b6000819050919050565b61267a81611fb1565b82525050565b600061268c8383612671565b60208301905092915050565b60008160001c9050919050565b6000819050919050565b60006126c26126bd83612698565b6126a5565b9050919050565b60006126d582546126af565b9050919050565b6000600182019050919050565b6126f281612651565b6126fc818461265c565b925061270782612667565b8060005b8381101561273f5761271c826126c9565b6127268782612680565b9650612731836126dc565b92505060018101905061270b565b505050505050565b600060408201905061275c60008301846126e9565b92915050565b60008151905061277181612025565b92915050565b60006020828403121561278d5761278c611fe5565b5b600061279b84828501612762565b91505092915050565b60006127af82611fb1565b91506127ba83611fb1565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156127ef576127ee612409565b5b828201905092915050565b7f42696e617279494d543a2074726565206465707468206d75737420626520626560008201527f747765656e203120616e64203332000000000000000000000000000000000000602082015250565b6000612856602e83612366565b9150612861826127fa565b604082019050919050565b6000602082019050818103600083015261288581612849565b9050919050565b7f496e6372656d656e74616c42696e617279547265653a2064656661756c745a6560008201527f726f2062616420696e6465780000000000000000000000000000000000000000602082015250565b60006128e8602c83612366565b91506128f38261288c565b604082019050919050565b60006020820190508181036000830152612917816128db565b9050919050565b600060029050919050565b6000819050919050565b6000602082019050919050565b6129498161291e565b612953818461265c565b925061295e82612929565b8060005b8381101561298f5781516129768782612680565b965061298183612933565b925050600181019050612962565b505050505050565b60006040820190506129ac6000830184612940565b92915050565b7f42696e617279494d543a206e6577206c6561662063616e6e6f7420626520746860008201527f652073616d6520617320746865206f6c64206f6e650000000000000000000000602082015250565b6000612a0e603583612366565b9150612a19826129b2565b604082019050919050565b60006020820190508181036000830152612a3d81612a01565b9050919050565b7f42696e617279494d543a206e6577206c656166206d757374206265203c20534e60008201527f41524b5f5343414c41525f4649454c4400000000000000000000000000000000602082015250565b6000612aa0603083612366565b9150612aab82612a44565b604082019050919050565b60006020820190508181036000830152612acf81612a93565b9050919050565b7f42696e617279494d543a206c656166206973206e6f742070617274206f66207460008201527f6865207472656500000000000000000000000000000000000000000000000000602082015250565b6000612b32602783612366565b9150612b3d82612ad6565b604082019050919050565b60006020820190508181036000830152612b6181612b25565b9050919050565b612b7181612273565b8114612b7c57600080fd5b50565b600081359050612b8e81612b68565b92915050565b600060208284031215612baa57612ba9611fe5565b5b6000612bb884828501612b7f565b91505092915050565b7f42696e617279494d543a206c65616620696e646578206f7574206f662072616e60008201527f6765000000000000000000000000000000000000000000000000000000000000602082015250565b6000612c1d602283612366565b9150612c2882612bc1565b604082019050919050565b60006020820190508181036000830152612c4c81612c10565b9050919050565b7f42696e617279494d543a206c656e677468206f662070617468206973206e6f7460008201527f20636f7272656374000000000000000000000000000000000000000000000000602082015250565b6000612caf602883612366565b9150612cba82612c53565b604082019050919050565b60006020820190508181036000830152612cde81612ca2565b9050919050565b7f42696e617279494d543a207369626c696e67206e6f6465206d7573742062652060008201527f3c20534e41524b5f5343414c41525f4649454c44000000000000000000000000602082015250565b6000612d41603483612366565b9150612d4c82612ce5565b604082019050919050565b60006020820190508181036000830152612d7081612d34565b9050919050565b7f42696e617279494d543a207061746820696e646578206973206e65697468657260008201527f2030206e6f722031000000000000000000000000000000000000000000000000602082015250565b6000612dd3602883612366565b9150612dde82612d77565b604082019050919050565b60006020820190508181036000830152612e0281612dc6565b905091905056fea2646970667358221220589cbf72cc2d84eab9c18913d1987756da4f6f0cf670db3e3b48633df0cb1f5764736f6c634300080f0033", + "libraries": { + "PoseidonT3": "0xbeeeAcde37Bce9011326137a49Bd5CA8153E9FCD" + }, + "devdoc": { + "details": "The incremental tree allows to calculate the root hash each time a leaf is added, ensuring the integrity of the tree.", + "kind": "dev", + "methods": { + "init(BinaryIMTData storage,uint256,uint256)": { + "details": "Initializes a tree.", + "params": { + "depth": ": Depth of the tree.", + "self": ": Tree data.", + "zero": ": Zero value to be used." + } + }, + "insert(BinaryIMTData storage,uint256)": { + "details": "Inserts a leaf in the tree.", + "params": { + "leaf": ": Leaf to be inserted.", + "self": ": Tree data." + } + }, + "remove(BinaryIMTData storage,uint256,uint256[],uint8[])": { + "details": "Removes a leaf from the tree.", + "params": { + "leaf": ": Leaf to be removed.", + "proofPathIndices": ": Path of the proof of membership.", + "proofSiblings": ": Array of the sibling nodes of the proof of membership.", + "self": ": Tree data." + } + }, + "update(BinaryIMTData storage,uint256,uint256,uint256[],uint8[])": { + "details": "Updates a leaf in the tree.", + "params": { + "leaf": ": Leaf to be updated.", + "newLeaf": ": New leaf.", + "proofPathIndices": ": Path of the proof of membership.", + "proofSiblings": ": Array of the sibling nodes of the proof of membership.", + "self": ": Tree data." + } + } + }, + "title": "Incremental binary Merkle tree.", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/sepolia/PoseidonHasher.json b/deployments/sepolia/PoseidonHasher.json index 3b3627e..2ae98d0 100644 --- a/deployments/sepolia/PoseidonHasher.json +++ b/deployments/sepolia/PoseidonHasher.json @@ -1,12 +1,25 @@ { - "address": "0xa1554EAF0DF18C05956249aac375e212edeD2CcF", + "address": "0x2092b99411d480b8Dd04BfD68EF1F0d545b0eB1D", "abi": [ + { + "inputs": [], + "name": "Q", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { - "internalType": "uint256", - "name": "input", - "type": "uint256" + "internalType": "uint256[2]", + "name": "inputs", + "type": "uint256[2]" } ], "name": "hash", @@ -21,34 +34,37 @@ "type": "function" } ], - "transactionHash": "0x6dec9da454c44cc5b4e0a1cf2fe6637253cfa1a7aaa37526b7cbe7a35b8a14d4", + "transactionHash": "0xb9cbd9ced88f02d5877148ce3032e95cc7937c2e96b960105887b36b58f46606", "receipt": { "to": null, - "from": "0xc2eB015aCb170177F726626707C82f994736ef15", - "contractAddress": "0xa1554EAF0DF18C05956249aac375e212edeD2CcF", - "transactionIndex": 30, - "gasUsed": "3488307", + "from": "0x3F47b2a1dF96DE2e198d646b598C37251CCC3b98", + "contractAddress": "0x2092b99411d480b8Dd04BfD68EF1F0d545b0eB1D", + "transactionIndex": 54, + "gasUsed": "291087", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x1f955aba5bf7056bdb643bd6dc31cb0923439ec5eb811db8e0ff01bed0d886d5", - "transactionHash": "0x6dec9da454c44cc5b4e0a1cf2fe6637253cfa1a7aaa37526b7cbe7a35b8a14d4", + "blockHash": "0x53846a4d829aec125afa5568fa18cd6661fcdd93a72be34ca60900d7aaa689f1", + "transactionHash": "0xb9cbd9ced88f02d5877148ce3032e95cc7937c2e96b960105887b36b58f46606", "logs": [], - "blockNumber": 3193047, - "cumulativeGasUsed": "6488158", + "blockNumber": 4794982, + "cumulativeGasUsed": "12466353", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "d5475cf869d23da2a838dd607679cc44", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"input\",\"type\":\"uint256\"}],\"name\":\"hash\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"hash(uint256)\":{\"params\":{\"input\":\"The input to hash\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"hash(uint256)\":{\"notice\":\"Hashes the input using the Poseidon hash function, n = 2, second input is the constant 0\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/PoseidonHasher.sol\":\"PoseidonHasher\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\"]},\"sources\":{\"contracts/PoseidonHasher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Forked from https://github.com/kilic/rlnapp/\\n\\npragma solidity 0.8.15;\\n\\ninterface IPoseidonHasher {\\n /// @notice Hashes the input using the Poseidon hash function, n = 2, second input is the constant 0\\n /// @param input The input to hash\\n function hash(uint256 input) external pure returns (uint256 result);\\n}\\n\\ncontract PoseidonHasher is IPoseidonHasher {\\n uint256 constant Q =\\n 21888242871839275222246405745257275088548364400416034343698204186575808495617;\\n uint256 constant C0 =\\n 4417881134626180770308697923359573201005643519861877412381846989312604493735;\\n uint256 constant C1 =\\n 5433650512959517612316327474713065966758808864213826738576266661723522780033;\\n uint256 constant C2 =\\n 13641176377184356099764086973022553863760045607496549923679278773208775739952;\\n uint256 constant C3 =\\n 17949713444224994136330421782109149544629237834775211751417461773584374506783;\\n uint256 constant C4 =\\n 13765628375339178273710281891027109699578766420463125835325926111705201856003;\\n uint256 constant C5 =\\n 19179513468172002314585757290678967643352171735526887944518845346318719730387;\\n uint256 constant C6 =\\n 5157412437176756884543472904098424903141745259452875378101256928559722612176;\\n uint256 constant C7 =\\n 535160875740282236955320458485730000677124519901643397458212725410971557409;\\n uint256 constant C8 =\\n 1050793453380762984940163090920066886770841063557081906093018330633089036729;\\n uint256 constant C9 =\\n 10665495010329663932664894101216428400933984666065399374198502106997623173873;\\n uint256 constant C10 =\\n 19965634623406616956648724894636666805991993496469370618546874926025059150737;\\n uint256 constant C11 =\\n 13007250030070838431593222885902415182312449212965120303174723305710127422213;\\n uint256 constant C12 =\\n 16877538715074991604507979123743768693428157847423939051086744213162455276374;\\n uint256 constant C13 =\\n 18211747749504876135588847560312685184956239426147543810126553367063157141465;\\n uint256 constant C14 =\\n 18151553319826126919739798892854572062191241985315767086020821632812331245635;\\n uint256 constant C15 =\\n 19957033149976712666746140949846950406660099037474791840946955175819555930825;\\n uint256 constant C16 =\\n 3469514863538261843186854830917934449567467100548474599735384052339577040841;\\n uint256 constant C17 =\\n 989698510043911779243192466312362856042600749099921773896924315611668507708;\\n uint256 constant C18 =\\n 12568377015646290945235387813564567111330046038050864455358059568128000172201;\\n uint256 constant C19 =\\n 20856104135605479600325529349246932565148587186338606236677138505306779314172;\\n uint256 constant C20 =\\n 8206918720503535523121349917159924938835810381723474192155637697065780938424;\\n uint256 constant C21 =\\n 1309058477013932989380617265069188723120054926187607548493110334522527703566;\\n uint256 constant C22 =\\n 14076116939332667074621703729512195584105250395163383769419390236426287710606;\\n uint256 constant C23 =\\n 10153498892749751942204288991871286290442690932856658983589258153608012428674;\\n uint256 constant C24 =\\n 18202499207234128286137597834010475797175973146805180988367589376893530181575;\\n uint256 constant C25 =\\n 12739388830157083522877690211447248168864006284243907142044329113461613743052;\\n uint256 constant C26 =\\n 15123358710467780770838026754240340042441262572309759635224051333176022613949;\\n uint256 constant C27 =\\n 19925004701844594370904593774447343836015483888496504201331110250494635362184;\\n uint256 constant C28 =\\n 10352416606816998476681131583320899030072315953910679608943150613208329645891;\\n uint256 constant C29 =\\n 10567371822366244361703342347428230537114808440249611395507235283708966113221;\\n uint256 constant C30 =\\n 5635498582763880627392290206431559361272660937399944184533035305989295959602;\\n uint256 constant C31 =\\n 11866432933224219174041051738704352719163271639958083608224676028593315904909;\\n uint256 constant C32 =\\n 5795020705294401441272215064554385591292330721703923167136157291459784140431;\\n uint256 constant C33 =\\n 9482202378699252817564375087302794636287866584767523335624368774856230692758;\\n uint256 constant C34 =\\n 4245237636894546151746468406560945873445548423466753843402086544922216329298;\\n uint256 constant C35 =\\n 12000500941313982757584712677991730019124834399479314697467598397927435905133;\\n uint256 constant C36 =\\n 7596790274058425558167520209857956363736666939016807569082239187494363541787;\\n uint256 constant C37 =\\n 2484867918246116343205467273440098378820186751202461278013576281097918148877;\\n uint256 constant C38 =\\n 18312645949449997391810445935615409295369169383463185688973803378104013950190;\\n uint256 constant C39 =\\n 15320686572748723004980855263301182130424010735782762814513954166519592552733;\\n uint256 constant C40 =\\n 12618438900597948888520621062416758747872180395546164387827245287017031303859;\\n uint256 constant C41 =\\n 17438141672027706116733201008397064011774368832458707512367404736905021019585;\\n uint256 constant C42 =\\n 6374197807230665998865688675365359100400438034755781666913068586172586548950;\\n uint256 constant C43 =\\n 2189398913433273865510950346186699930188746169476472274335177556702504595264;\\n uint256 constant C44 =\\n 6268495580028970231803791523870131137294646402347399003576649137450213034606;\\n uint256 constant C45 =\\n 17896250365994900261202920044129628104272791547990619503076839618914047059275;\\n uint256 constant C46 =\\n 13692156312448722528008862371944543449350293305158722920787736248435893008873;\\n uint256 constant C47 =\\n 15234446864368744483209945022439268713300180233589581910497691316744177619376;\\n uint256 constant C48 =\\n 1572426502623310766593681563281600503979671244997798691029595521622402217227;\\n uint256 constant C49 =\\n 80103447810215150918585162168214870083573048458555897999822831203653996617;\\n uint256 constant C50 =\\n 8228820324013669567851850635126713973797711779951230446503353812192849106342;\\n uint256 constant C51 =\\n 5375851433746509614045812476958526065449377558695752132494533666370449415873;\\n uint256 constant C52 =\\n 12115998939203497346386774317892338270561208357481805380546938146796257365018;\\n uint256 constant C53 =\\n 9764067909645821279940531410531154041386008396840887338272986634350423466622;\\n uint256 constant C54 =\\n 8538708244538850542384936174629541085495830544298260335345008245230827876882;\\n uint256 constant C55 =\\n 7140127896620013355910287215441004676619168261422440177712039790284719613114;\\n uint256 constant C56 =\\n 14297402962228458726038826185823085337698917275385741292940049024977027409762;\\n uint256 constant C57 =\\n 6667115556431351074165934212337261254608231545257434281887966406956835140819;\\n uint256 constant C58 =\\n 20226761165244293291042617464655196752671169026542832236139342122602741090001;\\n uint256 constant C59 =\\n 12038289506489256655759141386763477208196694421666339040483042079632134429119;\\n uint256 constant C60 =\\n 19027757334170818571203982241812412991528769934917288000224335655934473717551;\\n uint256 constant C61 =\\n 16272152964456553579565580463468069884359929612321610357528838696790370074720;\\n uint256 constant C62 =\\n 2500392889689246014710135696485946334448570271481948765283016105301740284071;\\n uint256 constant C63 =\\n 8595254970528530312401637448610398388203855633951264114100575485022581946023;\\n uint256 constant C64 =\\n 11635945688914011450976408058407206367914559009113158286982919675551688078198;\\n uint256 constant C65 =\\n 614739068603482619581328040478536306925147663946742687395148680260956671871;\\n uint256 constant C66 =\\n 18692271780377861570175282183255720350972693125537599213951106550953176268753;\\n uint256 constant C67 =\\n 4987059230784976306647166378298632695585915319042844495357753339378260807164;\\n uint256 constant C68 =\\n 21851403978498723616722415377430107676258664746210815234490134600998983955497;\\n uint256 constant C69 =\\n 9830635451186415300891533983087800047564037813328875992115573428596207326204;\\n uint256 constant C70 =\\n 4842706106434537116860242620706030229206345167233200482994958847436425185478;\\n uint256 constant C71 =\\n 6422235064906823218421386871122109085799298052314922856340127798647926126490;\\n uint256 constant C72 =\\n 4564364104986856861943331689105797031330091877115997069096365671501473357846;\\n uint256 constant C73 =\\n 1944043894089780613038197112872830569538541856657037469098448708685350671343;\\n uint256 constant C74 =\\n 21179865974855950600518216085229498748425990426231530451599322283119880194955;\\n uint256 constant C75 =\\n 14296697761894107574369608843560006996183955751502547883167824879840894933162;\\n uint256 constant C76 =\\n 12274619649702218570450581712439138337725246879938860735460378251639845671898;\\n uint256 constant C77 =\\n 16371396450276899401411886674029075408418848209575273031725505038938314070356;\\n uint256 constant C78 =\\n 3702561221750983937578095019779188631407216522704543451228773892695044653565;\\n uint256 constant C79 =\\n 19721616877735564664624984774636557499099875603996426215495516594530838681980;\\n uint256 constant C80 =\\n 6383350109027696789969911008057747025018308755462287526819231672217685282429;\\n uint256 constant C81 =\\n 20860583956177367265984596617324237471765572961978977333122281041544719622905;\\n uint256 constant C82 =\\n 5766390934595026947545001478457407504285452477687752470140790011329357286275;\\n uint256 constant C83 =\\n 4043175758319898049344746138515323336207420888499903387536875603879441092484;\\n uint256 constant C84 =\\n 15579382179133608217098622223834161692266188678101563820988612253342538956534;\\n uint256 constant C85 =\\n 1864640783252634743892105383926602930909039567065240010338908865509831749824;\\n uint256 constant C86 =\\n 15943719865023133586707144161652035291705809358178262514871056013754142625673;\\n uint256 constant C87 =\\n 2326415993032390211558498780803238091925402878871059708106213703504162832999;\\n uint256 constant C88 =\\n 19995326402773833553207196590622808505547443523750970375738981396588337910289;\\n uint256 constant C89 =\\n 5143583711361588952673350526320181330406047695593201009385718506918735286622;\\n uint256 constant C90 =\\n 15436006486881920976813738625999473183944244531070780793506388892313517319583;\\n uint256 constant C91 =\\n 16660446760173633166698660166238066533278664023818938868110282615200613695857;\\n uint256 constant C92 =\\n 4966065365695755376133119391352131079892396024584848298231004326013366253934;\\n uint256 constant C93 =\\n 20683781957411705574951987677641476019618457561419278856689645563561076926702;\\n uint256 constant C94 =\\n 17280836839165902792086432296371645107551519324565649849400948918605456875699;\\n uint256 constant C95 =\\n 17045635513701208892073056357048619435743564064921155892004135325530808465371;\\n uint256 constant C96 =\\n 17055032967194400710390142791334572297458033582458169295920670679093585707295;\\n uint256 constant C97 =\\n 15727174639569115300068198908071514334002742825679221638729902577962862163505;\\n uint256 constant C98 =\\n 1001755657610446661315902885492677747789366510875120894840818704741370398633;\\n uint256 constant C99 =\\n 18638547332826171619311285502376343504539399518545103511265465604926625041234;\\n uint256 constant C100 =\\n 6751954224763196429755298529194402870632445298969935050224267844020826420799;\\n uint256 constant C101 =\\n 3526747115904224771452549517614107688674036840088422555827581348280834879405;\\n uint256 constant C102 =\\n 15705897908180497062880001271426561999724005008972544196300715293701537574122;\\n uint256 constant C103 =\\n 574386695213920937259007343820417029802510752426579750428758189312416867750;\\n uint256 constant C104 =\\n 15973040855000600860816974646787367136127946402908768408978806375685439868553;\\n uint256 constant C105 =\\n 20934130413948796333037139460875996342810005558806621330680156931816867321122;\\n uint256 constant C106 =\\n 6918585327145564636398173845411579411526758237572034236476079610890705810764;\\n uint256 constant C107 =\\n 14158163500813182062258176233162498241310167509137716527054939926126453647182;\\n uint256 constant C108 =\\n 4164602626597695668474100217150111342272610479949122406544277384862187287433;\\n uint256 constant C109 =\\n 12146526846507496913615390662823936206892812880963914267275606265272996025304;\\n uint256 constant C110 =\\n 10153527926900017763244212043512822363696541810586522108597162891799345289938;\\n uint256 constant C111 =\\n 13564663485965299104296214940873270349072051793008946663855767889066202733588;\\n uint256 constant C112 =\\n 5612449256997576125867742696783020582952387615430650198777254717398552960096;\\n uint256 constant C113 =\\n 12151885480032032868507892738683067544172874895736290365318623681886999930120;\\n uint256 constant C114 =\\n 380452237704664384810613424095477896605414037288009963200982915188629772177;\\n uint256 constant C115 =\\n 9067557551252570188533509616805287919563636482030947363841198066124642069518;\\n uint256 constant C116 =\\n 21280306817619711661335268484199763923870315733198162896599997188206277056900;\\n uint256 constant C117 =\\n 5567165819557297006750252582140767993422097822227408837378089569369734876257;\\n uint256 constant C118 =\\n 10411936321072105429908396649383171465939606386380071222095155850987201580137;\\n uint256 constant C119 =\\n 21338390051413922944780864872652000187403217966653363270851298678606449622266;\\n uint256 constant C120 =\\n 12156296560457833712186127325312904760045212412680904475497938949653569234473;\\n uint256 constant C121 =\\n 4271647814574748734312113971565139132510281260328947438246615707172526380757;\\n uint256 constant C122 =\\n 9061738206062369647211128232833114177054715885442782773131292534862178874950;\\n uint256 constant C123 =\\n 10134551893627587797380445583959894183158393780166496661696555422178052339133;\\n uint256 constant C124 =\\n 8932270237664043612366044102088319242789325050842783721780970129656616386103;\\n uint256 constant C125 =\\n 3339412934966886386194449782756711637636784424032779155216609410591712750636;\\n uint256 constant C126 =\\n 9704903972004596791086522314847373103670545861209569267884026709445485704400;\\n uint256 constant C127 =\\n 17467570179597572575614276429760169990940929887711661192333523245667228809456;\\n uint256 constant M00 =\\n 2910766817845651019878574839501801340070030115151021261302834310722729507541;\\n uint256 constant M01 =\\n 19727366863391167538122140361473584127147630672623100827934084310230022599144;\\n uint256 constant M10 =\\n 5776684794125549462448597414050232243778680302179439492664047328281728356345;\\n uint256 constant M11 =\\n 8348174920934122550483593999453880006756108121341067172388445916328941978568;\\n\\n function hash(\\n uint256 input\\n ) external pure override returns (uint256 result) {\\n return _hash(input);\\n }\\n\\n function _hash(uint256 input) internal pure returns (uint256 result) {\\n assembly {\\n // Poseidon parameters should be t = 2, RF = 8, RP = 56\\n\\n // We load the characteristic\\n let q := Q\\n\\n // In zerokit implementation, if we pass inp = [a0,a1,..,an] to Poseidon what is effectively hashed is [0,a0,a1,..,an]\\n // Note that a sequence of MIX-ARK involves 3 Bn254 field additions before the mulmod happens. Worst case we have a value corresponding to 2*(p-1) which is less than 2^256 and hence doesn't overflow\\n //ROUND 0 - FULL\\n let s0 := C0\\n let s1 := add(input, C1)\\n // SBOX\\n let t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 1 - FULL\\n s0 := add(s0, C2)\\n s1 := add(s1, C3)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 2 - FULL\\n s0 := add(s0, C4)\\n s1 := add(s1, C5)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 3 - FULL\\n s0 := add(s0, C6)\\n s1 := add(s1, C7)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 4 - PARTIAL\\n s0 := add(s0, C8)\\n s1 := add(s1, C9)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 5 - PARTIAL\\n s0 := add(s0, C10)\\n s1 := add(s1, C11)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 6 - PARTIAL\\n s0 := add(s0, C12)\\n s1 := add(s1, C13)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 7 - PARTIAL\\n s0 := add(s0, C14)\\n s1 := add(s1, C15)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 8 - PARTIAL\\n s0 := add(s0, C16)\\n s1 := add(s1, C17)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 9 - PARTIAL\\n s0 := add(s0, C18)\\n s1 := add(s1, C19)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 10 - PARTIAL\\n s0 := add(s0, C20)\\n s1 := add(s1, C21)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 11 - PARTIAL\\n s0 := add(s0, C22)\\n s1 := add(s1, C23)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 12 - PARTIAL\\n s0 := add(s0, C24)\\n s1 := add(s1, C25)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 13 - PARTIAL\\n s0 := add(s0, C26)\\n s1 := add(s1, C27)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 14 - PARTIAL\\n s0 := add(s0, C28)\\n s1 := add(s1, C29)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 15 - PARTIAL\\n s0 := add(s0, C30)\\n s1 := add(s1, C31)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 16 - PARTIAL\\n s0 := add(s0, C32)\\n s1 := add(s1, C33)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 17 - PARTIAL\\n s0 := add(s0, C34)\\n s1 := add(s1, C35)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 18 - PARTIAL\\n s0 := add(s0, C36)\\n s1 := add(s1, C37)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 19 - PARTIAL\\n s0 := add(s0, C38)\\n s1 := add(s1, C39)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 20 - PARTIAL\\n s0 := add(s0, C40)\\n s1 := add(s1, C41)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 21 - PARTIAL\\n s0 := add(s0, C42)\\n s1 := add(s1, C43)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 22 - PARTIAL\\n s0 := add(s0, C44)\\n s1 := add(s1, C45)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 23 - PARTIAL\\n s0 := add(s0, C46)\\n s1 := add(s1, C47)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 24 - PARTIAL\\n s0 := add(s0, C48)\\n s1 := add(s1, C49)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 25 - PARTIAL\\n s0 := add(s0, C50)\\n s1 := add(s1, C51)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 26 - PARTIAL\\n s0 := add(s0, C52)\\n s1 := add(s1, C53)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 27 - PARTIAL\\n s0 := add(s0, C54)\\n s1 := add(s1, C55)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 28 - PARTIAL\\n s0 := add(s0, C56)\\n s1 := add(s1, C57)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 29 - PARTIAL\\n s0 := add(s0, C58)\\n s1 := add(s1, C59)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 30 - PARTIAL\\n s0 := add(s0, C60)\\n s1 := add(s1, C61)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 31 - PARTIAL\\n s0 := add(s0, C62)\\n s1 := add(s1, C63)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 32 - PARTIAL\\n s0 := add(s0, C64)\\n s1 := add(s1, C65)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 33 - PARTIAL\\n s0 := add(s0, C66)\\n s1 := add(s1, C67)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 34 - PARTIAL\\n s0 := add(s0, C68)\\n s1 := add(s1, C69)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 35 - PARTIAL\\n s0 := add(s0, C70)\\n s1 := add(s1, C71)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 36 - PARTIAL\\n s0 := add(s0, C72)\\n s1 := add(s1, C73)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 37 - PARTIAL\\n s0 := add(s0, C74)\\n s1 := add(s1, C75)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 38 - PARTIAL\\n s0 := add(s0, C76)\\n s1 := add(s1, C77)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 39 - PARTIAL\\n s0 := add(s0, C78)\\n s1 := add(s1, C79)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 40 - PARTIAL\\n s0 := add(s0, C80)\\n s1 := add(s1, C81)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 41 - PARTIAL\\n s0 := add(s0, C82)\\n s1 := add(s1, C83)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 42 - PARTIAL\\n s0 := add(s0, C84)\\n s1 := add(s1, C85)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 43 - PARTIAL\\n s0 := add(s0, C86)\\n s1 := add(s1, C87)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 44 - PARTIAL\\n s0 := add(s0, C88)\\n s1 := add(s1, C89)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 45 - PARTIAL\\n s0 := add(s0, C90)\\n s1 := add(s1, C91)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 46 - PARTIAL\\n s0 := add(s0, C92)\\n s1 := add(s1, C93)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 47 - PARTIAL\\n s0 := add(s0, C94)\\n s1 := add(s1, C95)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 48 - PARTIAL\\n s0 := add(s0, C96)\\n s1 := add(s1, C97)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 49 - PARTIAL\\n s0 := add(s0, C98)\\n s1 := add(s1, C99)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 50 - PARTIAL\\n s0 := add(s0, C100)\\n s1 := add(s1, C101)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 51 - PARTIAL\\n s0 := add(s0, C102)\\n s1 := add(s1, C103)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 52 - PARTIAL\\n s0 := add(s0, C104)\\n s1 := add(s1, C105)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 53 - PARTIAL\\n s0 := add(s0, C106)\\n s1 := add(s1, C107)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 54 - PARTIAL\\n s0 := add(s0, C108)\\n s1 := add(s1, C109)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 55 - PARTIAL\\n s0 := add(s0, C110)\\n s1 := add(s1, C111)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 56 - PARTIAL\\n s0 := add(s0, C112)\\n s1 := add(s1, C113)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 57 - PARTIAL\\n s0 := add(s0, C114)\\n s1 := add(s1, C115)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 58 - PARTIAL\\n s0 := add(s0, C116)\\n s1 := add(s1, C117)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 59 - PARTIAL\\n s0 := add(s0, C118)\\n s1 := add(s1, C119)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 60 - FULL\\n s0 := add(s0, C120)\\n s1 := add(s1, C121)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 61 - FULL\\n s0 := add(s0, C122)\\n s1 := add(s1, C123)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 62 - FULL\\n s0 := add(s0, C124)\\n s1 := add(s1, C125)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 63 - FULL\\n s0 := add(s0, C126)\\n s1 := add(s1, C127)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n s0 := mod(add(mulmod(s0, M00, q), mulmod(s1, M01, q)), q)\\n\\n result := s0\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf351af92fff6ed1dc02f1180c0c4906e79f1b825dd76df186caa787029a8de6a\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50613e0b806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063b189fd4c14610030575b600080fd5b61004a60048036038101906100459190613d7e565b610060565b6040516100579190613dba565b60405180910390f35b600061006b82610072565b9050919050565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000017f09c46e9ec68e9bd4fe1faaba294cba38a71aa177534cdd1b6c7dc0dbd0abd7a77f0c0356530896eec42a97ed937f3135cfc5142b3ae405b8343c1d83ffa604cb81840182828309838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1e28a1d935698ad1142e51182bb54cf4a00ea5aabd6268bd317ea977cc154a30830192507f27af2d831a9d2748080965db30e298e40e5757c3e008db964cf9e2b12b91251f82019150838384099050838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1e6f11ce60fc8f513a6a3cfe16ae175a41291462f214cd0879aaf43545b74e03830192507f2a67384d3bbd5e438541819cb681f0be04462ed14c3613d8f719206268d142d382019150838384099050838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0b66fdf356093a611609f8e12fbfecf0b985e381f025188936408f5d5c9f45d0830192507f012ee3ec1e78d470830c61093c2ade370b26c83cc5cebeeddaa6852dbdb09e2182019150838384099050838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0252ba5f6760bfbdfd88f67f8175e3fd6cd1c431b099b6bb2d108e7b445bb1b9830192507f179474cceca5ff676c6bec3cef54296354391a8935ff71d6ef5aeaad7ca932f182019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2c24261379a51bfa9228ff4a503fd4ed9c1f974a264969b37e1a2589bbed2b91830192507f1cc1d7b62692e63eac2f288bd0695b43c2f63f5001fc0fc553e66c0551801b0582019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f255059301aada98bb2ed55f852979e9600784dbf17fbacd05d9eff5fd9c91b56830192507f28437be3ac1cb2e479e1f5c0eccd32b3aea24234970a8193b11c29ce7e59efd982019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f28216a442f2e1f711ca4fa6b53766eb118548da8fb4f78d4338762c37f5f2043830192507f2c1f47cd17fa5adf1f39f4e7056dd03feee1efce03094581131f2377323482c982019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f07abad02b7a5ebc48632bcc9356ceb7dd9dafca276638a63646b8566a621afc9830192507f0230264601ffdf29275b33ffaab51dfe9429f90880a69cd137da0c4d15f96c3c82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1bc973054e51d905a0f168656497ca40a864414557ee289e717e5d66899aa0a9830192507f2e1c22f964435008206c3157e86341edd249aff5c2d8421f2a6b22288f0a67fc82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1224f38df67c5378121c1d5f461bbc509e8ea1598e46c9f7a70452bc2bba86b8830192507f02e4e69d8ba59e519280b4bd9ed0068fd7bfe8cd9dfeda1969d2989186cde20e82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1f1eccc34aaba0137f5df81fc04ff3ee4f19ee364e653f076d47e9735d98018e830192507f1672ad3d709a353974266c3039a9a7311424448032cd1819eacb8a4d4284f58282019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f283e3fdc2c6e420c56f44af5192b4ae9cda6961f284d24991d2ed602df8c8fc7830192507f1c2a3d120c550ecfd0db0957170fa013683751f8fdff59d6614fbd69ff394bcc82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f216f84877aac6172f7897a7323456efe143a9a43773ea6f296cb6b8177653fbd830192507f2c0d272becf2a75764ba7e8e3e28d12bceaa47ea61ca59a411a1f51552f9478882019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f16e34299865c0e28484ee7a74c454e9f170a5480abe0508fcb4a6c3d89546f43830192507f175ceba599e96f5b375a232a6fb9cc71772047765802290f48cd939755488fc582019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0c7594440dc48c16fead9e1758b028066aa410bfbc354f54d8c5ffbb44a1ee32830192507f1a3c29bc39f21bb5c466db7d7eb6fd8f760e20013ccf912c92479882d919fd8d82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0ccfdd906f3426e5c0986ea049b253400855d349074f5a6695c8eeabcd22e68f830192507f14f6bc81d9f186f62bdb475ce6c9411866a7a8a3fd065b3ce0e699b67dd9e79682019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0962b82789fb3d129702ca70b2f6c5aacc099810c9c495c888edeb7386b97052830192507f1a880af7074d18b3bf20c79de25127bc13284ab01ef02575afef0c8f6a31a86d82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f10cba18419a6a332cd5e77f0211c154b20af2924fc20ff3f4c3012bb7ae9311b830192507f057e62a9a8f89b3ebdc76ba63a9eaca8fa27b7319cae3406756a2849f302f10d82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f287c971de91dc0abd44adf5384b4988cb961303bbf65cff5afa0413b44280cee830192507f21df3388af1687bbb3bca9da0cca908f1e562bc46d4aba4e6f7f7960e306891d82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1be5c887d25bce703e25cc974d0934cd789df8f70b498fd83eff8b560e1682b3830192507f268da36f76e568fb68117175cea2cd0dd2cb5d42fda5acea48d59c2706a0d5c182019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0e17ab091f6eae50c609beaf5510ececc5d8bb74135ebd05bd06460cc26a5ed6830192507f04d727e728ffa0a67aee535ab074a43091ef62d8cf83d270040f5caa1f62af4082019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0ddbd7bf9c29341581b549762bc022ed33702ac10f1bfd862b15417d7e39ca6e830192507f2790eb3351621752768162e82989c6c234f5b0d1d3af9b588a29c49c8789654b82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1e457c601a63b73e4471950193d8a570395f3d9ab8b2fd0984b764206142f9e9830192507f21ae64301dca9625638d6ab2bbe7135ffa90ecd0c43ff91fc4c686fc46e091b082019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0379f63c8ce3468d4da293166f494928854be9e3432e09555858534eed8d350b830192507e2d56420359d0266a744a080809e054ca0e4921a46686ac8c9f58a324c3504982019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f123158e5965b5d9b1d68b3cd32e10bbeda8d62459e21f4090fc2c5af963515a6830192507f0be29fc40847a941661d14bbf6cbe0420fbb2b6f52836d4e60c80eb49cad9ec182019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1ac96991dec2bb0557716142015a453c36db9d859cad5f9a233802f24fdf4c1a830192507f1596443f763dbcc25f4964fc61d23b3e5e12c9fa97f18a9251ca3355bcb0627e82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f12e0bcd3654bdfa76b2861d4ec3aeae0f1857d9f17e715aed6d049eae3ba3212830192507f0fc92b4f1bbea82b9ea73d4af9af2a50ceabac7f37154b1904e6c76c7cf964ba82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1f9c0b1610446442d6f2e592a8013f40b14f7c7722236f4f9c7e965233872762830192507f0ebd74244ae72675f8cde06157a782f4050d914da38b4c058d159f643dbbf4d382019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2cb7f0ed39e16e9f69a9fafd4ab951c03b0671e97346ee397a839839dccfc6d1830192507f1a9d6e2ecff022cc5605443ee41bab20ce761d0514ce526690c72bca7352d9bf82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2a115439607f335a5ea83c3bc44a9331d0c13326a9a7ba3087da182d648ec72f830192507f23f9b6529b5d040d15b8fa7aee3e3410e738b56305cd44f29535c115c5a4c06082019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f05872c16db0f72a2249ac6ba484bb9c3a3ce97c16d58b68b260eb939f0e6e8a7830192507f1300bdee08bb7824ca20fb80118075f40219b6151d55b5c52b624a7cdeddf6a782019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f19b9b63d2f108e17e63817863a8f6c288d7ad29916d98cb1072e4e7b7d52b376830192507f015bee1357e3c015b5bda237668522f613d1c88726b5ec4224a20128481b4f7f82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2953736e94bb6b9f1b9707a4f1615e4efe1e1ce4bab218cbea92c785b128ffd1830192507f0b069353ba091618862f806180c0385f851b98d372b45f544ce7266ed6608dfc82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f304f74d461ccc13115e4e0bcfb93817e55aeb7eb9306b64e4f588ac97d81f429830192507f15bbf146ce9bca09e8a33f5e77dfe4f5aad2a164a4617a4cb8ee5415cde913fc82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0ab4dfe0c2742cde44901031487964ed9b8f4b850405c10ca9ff23859572c8c6830192507f0e32db320a044e3197f45f7649a19675ef5eedfea546dea9251de39f9639779a82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0a1756aa1f378ca4b27635a78b6888e66797733a82774896a3078efa516da016830192507f044c4a33b10f693447fd17177f952ef895e61d328f85efa94254d6a2a25d93ef82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2ed3611b725b8a70be655b537f66f700fe0879d79a496891d37b07b5466c4b8b830192507f1f9ba4e8bab7ce42c8ecc3d722aa2e0eadfdeb9cfdd347b5d8339ea7120858aa82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1b233043052e8c288f7ee907a84e518aa38e82ac4502066db74056f865c5d3da830192507f2431e1cc164bb8d074031ab72bd55b4c902053bfc0f14db0ca2f97b02087595482019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f082f934c91f5aac330cd6953a0a7db45a13e322097583319a791f273965801fd830192507f2b9a0a223e7538b0a34be074315542a3c77245e2ae7cbe999ad6bb930c48997c82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0e1cd91edd2cfa2cceb85483b887a9be8164163e75a8a00eb0b589cc70214e7d830192507f2e1eac0f2bfdfd63c951f61477e3698999774f19854d00f588d324601cebe2f982019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0cbfa95f37fb74060c76158e769d6d157345784d8efdb33c23d748115b500b83830192507f08f05b3be923ed44d65ad49d8a61e9a676d991e3a77513d9980c232dfa4a4f8482019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f22719e2a070bcd0852bf8e21984d0443e7284925dc0758a325a2dd510c047ef6830192507f041f596a9ee1cb2bc060f7fcc3a1ab4c7bdbf036119982c0f41f62b2f26830c082019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f233fd35de1be520a87628eb06f6b1d4c021be1c2d0dc464a19fcdd0986b10f89830192507f0524b46d1aa87a5e4325e0a423ebc810d31e078aa1b4707eefcb453c61c9c26782019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2c34f424c81e5716ce47fcac894b85824227bb954b0f3199cc4486237c515211830192507f0b5f2a4b63387819207effc2b5541fb72dd2025b5457cc97f33010327de4915e82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f22207856082ccc54c5b72fe439d2cfd6c17435d2f57af6ceaefac41fe05c659f830192507f24d57a8bf5da63fe4e24159b7f8950b5cdfb210194caf79f27854048ce2c817182019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0afab181fdd5e0583b371d75bd693f98374ad7097bb01a8573919bb23b79396e830192507f2dba9b108f208772998a52efac7cbd5676c0057194c16c0bf16290d62b1128ee82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f26349b66edb8b16f56f881c788f53f83cbb83de0bd592b255aff13e6bce420b3830192507f25af7ce0e5e10357685e95f92339753ad81a56d28ecc193b235288a3e6f137db82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f25b4ce7bd2294390c094d6a55edd68b970eed7aae88b2bff1f7c0187fe35011f830192507f22c543f10f6c89ec387e53f1908a88e5de9cef28ebdf30b18cb9d54c1e02b63182019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0236f93e7789c4724fc7908a9f191e1e425e906a919d7a34df668e74882f87a9830192507f29350b401166ca010e7d27e37d05da99652bdae114eb01659cb497af980c4b5282019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0eed787d65820d3f6bd31bbab547f75a65edb75d844ebb89ee1260916652363f830192507f07cc1170f13b46f2036a753f520b3291fdcd0e99bd94297d1906f656f4de6fad82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f22b939233b1d7205f49bcf613a3d30b1908786d7f9f5d10c2059435689e8acea830192507f01451762a0aab81c8aad1dc8bc33e870740f083a5aa85438add650ace60ae5a682019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f23506bb5d8727d4461fabf1025d46d1fe32eaa61dec7da57e704fec0892fce89830192507f2e484c44e838aea0bac06ae3f71bdd092a3709531e1efea97f8bd6890735552282019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0f4bc7d07ebafd64379e78c50bd2e42baf4a594545cedc2545418da26835b54c830192507f1f4d3c8f6583e9e5fa76637862faaee851582388725df460e620996d50d8e74e82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f093514e0c70711f82660d07be0e4a988fae02abc7b681d9153eb9bcb48fe7389830192507f1adab0c8e2b3bad346699a2b5f3bc03643ee83ece47228f24a58e0a347e153d882019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1672b1726057d99dd14709ebb474641a378c1b94b8072bac1a22dbef9e80dad2830192507f1dfd53d4576af2e38f44f53fdcab468cc5d8e2fae0acc4ee30d47b239b479c1482019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0c6888a10b75b0f3a70a36263a37e17fe6d77d640f6fc3debc7f207753205c60830192507f1addb933a65be77092b34a7e77d12fe8611a61e00ee6848b85091ecca9d1e50882019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507ed7540dcd268a845c10ae18d1de933cf638ff5425f0afff7935628e299d1791830192507f140c0e42687e9ead01b2827a5664ca9c26fedde4acd99db1d316939d20b82c0e82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2f0c3a115d4317d191ba89b8d13d1806c20a0f9b24f8c5edc091e2ae56565984830192507f0c4ee778ff7c14553006ed220cf9c81008a0cff670b22b82d8c538a1dc958c6182019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1704f2766d46f82c3693f00440ccc3609424ed26c0acc66227c3d7485de74c69830192507f2f2d19cc3ea5d78ea7a02c1b51d244abf0769c9f8544e40239b66fe9009c3cfa82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1ae03853b75fcaba5053f112e2a8e8dcdd7ee6cb9cfed9c7d6c766a806fc6629830192507f0971aabf795241df51d131d0fa61aa5f3556921b2d6f014e4e41a86ddaf056d582019150838384099050838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1408c316e6014e1a91d4cf6b6e0de73eda624f8380df1c875f5c29f7bfe2f646830192507f1667f3fe2edbe850248abe42b543093b6c89f1f773ef285341691f39822ef5bd82019150838384099050838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f13bf7c5d0d2c4376a48b0a03557cdf915b81718409e5c133424c69576500fe37830192507f07620a6dfb0b6cec3016adf3d3533c24024b95347856b79719bc0ba743a62c2c82019150838384099050838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1574c7ef0c43545f36a8ca08bdbdd8b075d2959e2f322b731675de3e1982b4d0830192507f269e4b5b7a2eb21afd567970a717ceec5bd4184571c254fdc06e03a7ff8378f08201915083838409905083838583840909925083828309905083828583840909915083847f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88409857f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad586090106925082945050505050919050565b600080fd5b6000819050919050565b613d5b81613d48565b8114613d6657600080fd5b50565b600081359050613d7881613d52565b92915050565b600060208284031215613d9457613d93613d43565b5b6000613da284828501613d69565b91505092915050565b613db481613d48565b82525050565b6000602082019050613dcf6000830184613dab565b9291505056fea2646970667358221220990df31685b31c63744b01bc207e4768c1c06108de2290d14567b05c11973cb064736f6c634300080f0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063b189fd4c14610030575b600080fd5b61004a60048036038101906100459190613d7e565b610060565b6040516100579190613dba565b60405180910390f35b600061006b82610072565b9050919050565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000017f09c46e9ec68e9bd4fe1faaba294cba38a71aa177534cdd1b6c7dc0dbd0abd7a77f0c0356530896eec42a97ed937f3135cfc5142b3ae405b8343c1d83ffa604cb81840182828309838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1e28a1d935698ad1142e51182bb54cf4a00ea5aabd6268bd317ea977cc154a30830192507f27af2d831a9d2748080965db30e298e40e5757c3e008db964cf9e2b12b91251f82019150838384099050838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1e6f11ce60fc8f513a6a3cfe16ae175a41291462f214cd0879aaf43545b74e03830192507f2a67384d3bbd5e438541819cb681f0be04462ed14c3613d8f719206268d142d382019150838384099050838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0b66fdf356093a611609f8e12fbfecf0b985e381f025188936408f5d5c9f45d0830192507f012ee3ec1e78d470830c61093c2ade370b26c83cc5cebeeddaa6852dbdb09e2182019150838384099050838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0252ba5f6760bfbdfd88f67f8175e3fd6cd1c431b099b6bb2d108e7b445bb1b9830192507f179474cceca5ff676c6bec3cef54296354391a8935ff71d6ef5aeaad7ca932f182019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2c24261379a51bfa9228ff4a503fd4ed9c1f974a264969b37e1a2589bbed2b91830192507f1cc1d7b62692e63eac2f288bd0695b43c2f63f5001fc0fc553e66c0551801b0582019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f255059301aada98bb2ed55f852979e9600784dbf17fbacd05d9eff5fd9c91b56830192507f28437be3ac1cb2e479e1f5c0eccd32b3aea24234970a8193b11c29ce7e59efd982019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f28216a442f2e1f711ca4fa6b53766eb118548da8fb4f78d4338762c37f5f2043830192507f2c1f47cd17fa5adf1f39f4e7056dd03feee1efce03094581131f2377323482c982019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f07abad02b7a5ebc48632bcc9356ceb7dd9dafca276638a63646b8566a621afc9830192507f0230264601ffdf29275b33ffaab51dfe9429f90880a69cd137da0c4d15f96c3c82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1bc973054e51d905a0f168656497ca40a864414557ee289e717e5d66899aa0a9830192507f2e1c22f964435008206c3157e86341edd249aff5c2d8421f2a6b22288f0a67fc82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1224f38df67c5378121c1d5f461bbc509e8ea1598e46c9f7a70452bc2bba86b8830192507f02e4e69d8ba59e519280b4bd9ed0068fd7bfe8cd9dfeda1969d2989186cde20e82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1f1eccc34aaba0137f5df81fc04ff3ee4f19ee364e653f076d47e9735d98018e830192507f1672ad3d709a353974266c3039a9a7311424448032cd1819eacb8a4d4284f58282019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f283e3fdc2c6e420c56f44af5192b4ae9cda6961f284d24991d2ed602df8c8fc7830192507f1c2a3d120c550ecfd0db0957170fa013683751f8fdff59d6614fbd69ff394bcc82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f216f84877aac6172f7897a7323456efe143a9a43773ea6f296cb6b8177653fbd830192507f2c0d272becf2a75764ba7e8e3e28d12bceaa47ea61ca59a411a1f51552f9478882019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f16e34299865c0e28484ee7a74c454e9f170a5480abe0508fcb4a6c3d89546f43830192507f175ceba599e96f5b375a232a6fb9cc71772047765802290f48cd939755488fc582019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0c7594440dc48c16fead9e1758b028066aa410bfbc354f54d8c5ffbb44a1ee32830192507f1a3c29bc39f21bb5c466db7d7eb6fd8f760e20013ccf912c92479882d919fd8d82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0ccfdd906f3426e5c0986ea049b253400855d349074f5a6695c8eeabcd22e68f830192507f14f6bc81d9f186f62bdb475ce6c9411866a7a8a3fd065b3ce0e699b67dd9e79682019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0962b82789fb3d129702ca70b2f6c5aacc099810c9c495c888edeb7386b97052830192507f1a880af7074d18b3bf20c79de25127bc13284ab01ef02575afef0c8f6a31a86d82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f10cba18419a6a332cd5e77f0211c154b20af2924fc20ff3f4c3012bb7ae9311b830192507f057e62a9a8f89b3ebdc76ba63a9eaca8fa27b7319cae3406756a2849f302f10d82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f287c971de91dc0abd44adf5384b4988cb961303bbf65cff5afa0413b44280cee830192507f21df3388af1687bbb3bca9da0cca908f1e562bc46d4aba4e6f7f7960e306891d82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1be5c887d25bce703e25cc974d0934cd789df8f70b498fd83eff8b560e1682b3830192507f268da36f76e568fb68117175cea2cd0dd2cb5d42fda5acea48d59c2706a0d5c182019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0e17ab091f6eae50c609beaf5510ececc5d8bb74135ebd05bd06460cc26a5ed6830192507f04d727e728ffa0a67aee535ab074a43091ef62d8cf83d270040f5caa1f62af4082019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0ddbd7bf9c29341581b549762bc022ed33702ac10f1bfd862b15417d7e39ca6e830192507f2790eb3351621752768162e82989c6c234f5b0d1d3af9b588a29c49c8789654b82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1e457c601a63b73e4471950193d8a570395f3d9ab8b2fd0984b764206142f9e9830192507f21ae64301dca9625638d6ab2bbe7135ffa90ecd0c43ff91fc4c686fc46e091b082019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0379f63c8ce3468d4da293166f494928854be9e3432e09555858534eed8d350b830192507e2d56420359d0266a744a080809e054ca0e4921a46686ac8c9f58a324c3504982019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f123158e5965b5d9b1d68b3cd32e10bbeda8d62459e21f4090fc2c5af963515a6830192507f0be29fc40847a941661d14bbf6cbe0420fbb2b6f52836d4e60c80eb49cad9ec182019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1ac96991dec2bb0557716142015a453c36db9d859cad5f9a233802f24fdf4c1a830192507f1596443f763dbcc25f4964fc61d23b3e5e12c9fa97f18a9251ca3355bcb0627e82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f12e0bcd3654bdfa76b2861d4ec3aeae0f1857d9f17e715aed6d049eae3ba3212830192507f0fc92b4f1bbea82b9ea73d4af9af2a50ceabac7f37154b1904e6c76c7cf964ba82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1f9c0b1610446442d6f2e592a8013f40b14f7c7722236f4f9c7e965233872762830192507f0ebd74244ae72675f8cde06157a782f4050d914da38b4c058d159f643dbbf4d382019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2cb7f0ed39e16e9f69a9fafd4ab951c03b0671e97346ee397a839839dccfc6d1830192507f1a9d6e2ecff022cc5605443ee41bab20ce761d0514ce526690c72bca7352d9bf82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2a115439607f335a5ea83c3bc44a9331d0c13326a9a7ba3087da182d648ec72f830192507f23f9b6529b5d040d15b8fa7aee3e3410e738b56305cd44f29535c115c5a4c06082019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f05872c16db0f72a2249ac6ba484bb9c3a3ce97c16d58b68b260eb939f0e6e8a7830192507f1300bdee08bb7824ca20fb80118075f40219b6151d55b5c52b624a7cdeddf6a782019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f19b9b63d2f108e17e63817863a8f6c288d7ad29916d98cb1072e4e7b7d52b376830192507f015bee1357e3c015b5bda237668522f613d1c88726b5ec4224a20128481b4f7f82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2953736e94bb6b9f1b9707a4f1615e4efe1e1ce4bab218cbea92c785b128ffd1830192507f0b069353ba091618862f806180c0385f851b98d372b45f544ce7266ed6608dfc82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f304f74d461ccc13115e4e0bcfb93817e55aeb7eb9306b64e4f588ac97d81f429830192507f15bbf146ce9bca09e8a33f5e77dfe4f5aad2a164a4617a4cb8ee5415cde913fc82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0ab4dfe0c2742cde44901031487964ed9b8f4b850405c10ca9ff23859572c8c6830192507f0e32db320a044e3197f45f7649a19675ef5eedfea546dea9251de39f9639779a82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0a1756aa1f378ca4b27635a78b6888e66797733a82774896a3078efa516da016830192507f044c4a33b10f693447fd17177f952ef895e61d328f85efa94254d6a2a25d93ef82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2ed3611b725b8a70be655b537f66f700fe0879d79a496891d37b07b5466c4b8b830192507f1f9ba4e8bab7ce42c8ecc3d722aa2e0eadfdeb9cfdd347b5d8339ea7120858aa82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1b233043052e8c288f7ee907a84e518aa38e82ac4502066db74056f865c5d3da830192507f2431e1cc164bb8d074031ab72bd55b4c902053bfc0f14db0ca2f97b02087595482019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f082f934c91f5aac330cd6953a0a7db45a13e322097583319a791f273965801fd830192507f2b9a0a223e7538b0a34be074315542a3c77245e2ae7cbe999ad6bb930c48997c82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0e1cd91edd2cfa2cceb85483b887a9be8164163e75a8a00eb0b589cc70214e7d830192507f2e1eac0f2bfdfd63c951f61477e3698999774f19854d00f588d324601cebe2f982019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0cbfa95f37fb74060c76158e769d6d157345784d8efdb33c23d748115b500b83830192507f08f05b3be923ed44d65ad49d8a61e9a676d991e3a77513d9980c232dfa4a4f8482019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f22719e2a070bcd0852bf8e21984d0443e7284925dc0758a325a2dd510c047ef6830192507f041f596a9ee1cb2bc060f7fcc3a1ab4c7bdbf036119982c0f41f62b2f26830c082019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f233fd35de1be520a87628eb06f6b1d4c021be1c2d0dc464a19fcdd0986b10f89830192507f0524b46d1aa87a5e4325e0a423ebc810d31e078aa1b4707eefcb453c61c9c26782019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2c34f424c81e5716ce47fcac894b85824227bb954b0f3199cc4486237c515211830192507f0b5f2a4b63387819207effc2b5541fb72dd2025b5457cc97f33010327de4915e82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f22207856082ccc54c5b72fe439d2cfd6c17435d2f57af6ceaefac41fe05c659f830192507f24d57a8bf5da63fe4e24159b7f8950b5cdfb210194caf79f27854048ce2c817182019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0afab181fdd5e0583b371d75bd693f98374ad7097bb01a8573919bb23b79396e830192507f2dba9b108f208772998a52efac7cbd5676c0057194c16c0bf16290d62b1128ee82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f26349b66edb8b16f56f881c788f53f83cbb83de0bd592b255aff13e6bce420b3830192507f25af7ce0e5e10357685e95f92339753ad81a56d28ecc193b235288a3e6f137db82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f25b4ce7bd2294390c094d6a55edd68b970eed7aae88b2bff1f7c0187fe35011f830192507f22c543f10f6c89ec387e53f1908a88e5de9cef28ebdf30b18cb9d54c1e02b63182019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0236f93e7789c4724fc7908a9f191e1e425e906a919d7a34df668e74882f87a9830192507f29350b401166ca010e7d27e37d05da99652bdae114eb01659cb497af980c4b5282019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0eed787d65820d3f6bd31bbab547f75a65edb75d844ebb89ee1260916652363f830192507f07cc1170f13b46f2036a753f520b3291fdcd0e99bd94297d1906f656f4de6fad82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f22b939233b1d7205f49bcf613a3d30b1908786d7f9f5d10c2059435689e8acea830192507f01451762a0aab81c8aad1dc8bc33e870740f083a5aa85438add650ace60ae5a682019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f23506bb5d8727d4461fabf1025d46d1fe32eaa61dec7da57e704fec0892fce89830192507f2e484c44e838aea0bac06ae3f71bdd092a3709531e1efea97f8bd6890735552282019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0f4bc7d07ebafd64379e78c50bd2e42baf4a594545cedc2545418da26835b54c830192507f1f4d3c8f6583e9e5fa76637862faaee851582388725df460e620996d50d8e74e82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f093514e0c70711f82660d07be0e4a988fae02abc7b681d9153eb9bcb48fe7389830192507f1adab0c8e2b3bad346699a2b5f3bc03643ee83ece47228f24a58e0a347e153d882019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1672b1726057d99dd14709ebb474641a378c1b94b8072bac1a22dbef9e80dad2830192507f1dfd53d4576af2e38f44f53fdcab468cc5d8e2fae0acc4ee30d47b239b479c1482019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f0c6888a10b75b0f3a70a36263a37e17fe6d77d640f6fc3debc7f207753205c60830192507f1addb933a65be77092b34a7e77d12fe8611a61e00ee6848b85091ecca9d1e50882019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507ed7540dcd268a845c10ae18d1de933cf638ff5425f0afff7935628e299d1791830192507f140c0e42687e9ead01b2827a5664ca9c26fedde4acd99db1d316939d20b82c0e82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f2f0c3a115d4317d191ba89b8d13d1806c20a0f9b24f8c5edc091e2ae56565984830192507f0c4ee778ff7c14553006ed220cf9c81008a0cff670b22b82d8c538a1dc958c6182019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1704f2766d46f82c3693f00440ccc3609424ed26c0acc66227c3d7485de74c69830192507f2f2d19cc3ea5d78ea7a02c1b51d244abf0769c9f8544e40239b66fe9009c3cfa82019150838384099050838385838409099250837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1ae03853b75fcaba5053f112e2a8e8dcdd7ee6cb9cfed9c7d6c766a806fc6629830192507f0971aabf795241df51d131d0fa61aa5f3556921b2d6f014e4e41a86ddaf056d582019150838384099050838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1408c316e6014e1a91d4cf6b6e0de73eda624f8380df1c875f5c29f7bfe2f646830192507f1667f3fe2edbe850248abe42b543093b6c89f1f773ef285341691f39822ef5bd82019150838384099050838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f13bf7c5d0d2c4376a48b0a03557cdf915b81718409e5c133424c69576500fe37830192507f07620a6dfb0b6cec3016adf3d3533c24024b95347856b79719bc0ba743a62c2c82019150838384099050838385838409099250838283099050838285838409099150837f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88309847f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad58509019050837f1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c88309847f0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff985090191508092507f1574c7ef0c43545f36a8ca08bdbdd8b075d2959e2f322b731675de3e1982b4d0830192507f269e4b5b7a2eb21afd567970a717ceec5bd4184571c254fdc06e03a7ff8378f08201915083838409905083838583840909925083828309905083828583840909915083847f2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e88409857f066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad586090106925082945050505050919050565b600080fd5b6000819050919050565b613d5b81613d48565b8114613d6657600080fd5b50565b600081359050613d7881613d52565b92915050565b600060208284031215613d9457613d93613d43565b5b6000613da284828501613d69565b91505092915050565b613db481613d48565b82525050565b6000602082019050613dcf6000830184613dab565b9291505056fea2646970667358221220990df31685b31c63744b01bc207e4768c1c06108de2290d14567b05c11973cb064736f6c634300080f0033", + "numDeployments": 1, + "solcInputHash": "3f87313134e2217cb187bd594084789f", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"Q\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"inputs\",\"type\":\"uint256[2]\"}],\"name\":\"hash\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"hash(uint256[2])\":{\"params\":{\"inputs\":\"The input to hash\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"hash(uint256[2])\":{\"notice\":\"Hashes the input using the Poseidon hash function, n = 2\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/PoseidonHasher.sol\":\"PoseidonHasher\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\"]},\"sources\":{\"contracts/PoseidonHasher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.15;\\n\\nimport {PoseidonT3} from \\\"poseidon-solidity/PoseidonT3.sol\\\";\\n\\ninterface IPoseidonHasher {\\n /// @notice Hashes the input using the Poseidon hash function, n = 2\\n /// @param inputs The input to hash\\n function hash(uint256[2] memory inputs) external pure returns (uint256 result);\\n}\\n\\ncontract PoseidonHasher is IPoseidonHasher {\\n uint256 public constant Q = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\\n\\n function hash(uint256[2] memory inputs) external pure override returns (uint256 result) {\\n return PoseidonT3.hash(inputs);\\n }\\n}\\n\",\"keccak256\":\"0xdc41072af08ab2875f030e6ccc5781a7d5906aeaccc44535bb076e09146e86f9\",\"license\":\"MIT\"},\"poseidon-solidity/PoseidonT3.sol\":{\"content\":\"/// SPDX-License-Identifier: MIT\\npragma solidity >=0.7.0;\\n\\nlibrary PoseidonT3 {\\n uint constant M00 = 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b;\\n uint constant M01 = 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771;\\n uint constant M02 = 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7;\\n uint constant M10 = 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0;\\n uint constant M11 = 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23;\\n uint constant M12 = 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911;\\n\\n // See here for a simplified implementation: https://github.com/vimwitch/poseidon-solidity/blob/e57becdabb65d99fdc586fe1e1e09e7108202d53/contracts/Poseidon.sol#L40\\n // Inspired by: https://github.com/iden3/circomlibjs/blob/v0.0.8/src/poseidon_slow.js\\n function hash(uint[2] memory) public pure returns (uint) {\\n assembly {\\n let F := 21888242871839275222246405745257275088548364400416034343698204186575808495617\\n let M20 := 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d\\n let M21 := 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa\\n let M22 := 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0\\n\\n // load the inputs from memory\\n let state1 := add(mod(mload(0x80), F), 0x00f1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864)\\n let state2 := add(mod(mload(0xa0), F), 0x08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5)\\n let scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n scratch0 := add(\\n 0x2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d0,\\n add(add(15452833169820924772166449970675545095234312153403844297388521437673434406763, mulmod(state1, M10, F)), mulmod(state2, M20, F))\\n )\\n let scratch1 := add(\\n 0x2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf2,\\n add(add(18674271267752038776579386132900109523609358935013267566297499497165104279117, mulmod(state1, M11, F)), mulmod(state2, M21, F))\\n )\\n let scratch2 := add(\\n 0x0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa,\\n add(add(14817777843080276494683266178512808687156649753153012854386334860566696099579, mulmod(state1, M12, F)), mulmod(state2, M22, F))\\n )\\n let state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc632, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n scratch0 := add(0x15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c8705, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd1, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x005032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c887, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da53, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0081c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb38, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c502, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x00ef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba89, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c5, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e4, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e13, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a90035, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db69, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b8, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c77, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x002e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x00b9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c3512, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x00248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a808, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f09, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e8284, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd800, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f178, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e504233, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d59, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f88948, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d142, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c0, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a58, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d01, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc792, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea6111, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa336, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d6, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f451, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf77, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc630, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c2320, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n scratch0 := add(0x0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f8, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e4228325161, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n\\n mstore(0x0, mod(add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)), F))\\n\\n return(0, 0x20)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0102caa303bbc6690508f3615604f7730789ed990058c9513a87ccb30e4835be\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061044f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063561558fe1461003b578063e493ef8c1461006b575b600080fd5b610055600480360381019061005091906102ba565b610089565b60405161006291906102f6565b60405180910390f35b61007361010a565b60405161008091906102f6565b60405180910390f35b600073beeeAcde37Bce9011326137a49Bd5CA8153E9FCD63561558fe836040518263ffffffff1660e01b81526004016100c291906103bc565b602060405180830381865af41580156100df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061010391906103ec565b9050919050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6000604051905090565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61018b82610142565b810181811067ffffffffffffffff821117156101aa576101a9610153565b5b80604052505050565b60006101bd61012e565b90506101c98282610182565b919050565b600067ffffffffffffffff8211156101e9576101e8610153565b5b602082029050919050565b600080fd5b6000819050919050565b61020c816101f9565b811461021757600080fd5b50565b60008135905061022981610203565b92915050565b600061024261023d846101ce565b6101b3565b9050806020840283018581111561025c5761025b6101f4565b5b835b818110156102855780610271888261021a565b84526020840193505060208101905061025e565b5050509392505050565b600082601f8301126102a4576102a361013d565b5b60026102b184828561022f565b91505092915050565b6000604082840312156102d0576102cf610138565b5b60006102de8482850161028f565b91505092915050565b6102f0816101f9565b82525050565b600060208201905061030b60008301846102e7565b92915050565b600060029050919050565b600081905092915050565b6000819050919050565b61033a816101f9565b82525050565b600061034c8383610331565b60208301905092915050565b6000602082019050919050565b61036e81610311565b610378818461031c565b925061038382610327565b8060005b838110156103b457815161039b8782610340565b96506103a683610358565b925050600181019050610387565b505050505050565b60006040820190506103d16000830184610365565b92915050565b6000815190506103e681610203565b92915050565b60006020828403121561040257610401610138565b5b6000610410848285016103d7565b9150509291505056fea26469706673582212207d88c1e3e3770369b8191d659faefd696dbbefdede5e363482a4a6619719344864736f6c634300080f0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063561558fe1461003b578063e493ef8c1461006b575b600080fd5b610055600480360381019061005091906102ba565b610089565b60405161006291906102f6565b60405180910390f35b61007361010a565b60405161008091906102f6565b60405180910390f35b600073__$75f79a42d9bcbdbb69ad79ebd80f556f39$__63561558fe836040518263ffffffff1660e01b81526004016100c291906103bc565b602060405180830381865af41580156100df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061010391906103ec565b9050919050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181565b6000604051905090565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61018b82610142565b810181811067ffffffffffffffff821117156101aa576101a9610153565b5b80604052505050565b60006101bd61012e565b90506101c98282610182565b919050565b600067ffffffffffffffff8211156101e9576101e8610153565b5b602082029050919050565b600080fd5b6000819050919050565b61020c816101f9565b811461021757600080fd5b50565b60008135905061022981610203565b92915050565b600061024261023d846101ce565b6101b3565b9050806020840283018581111561025c5761025b6101f4565b5b835b818110156102855780610271888261021a565b84526020840193505060208101905061025e565b5050509392505050565b600082601f8301126102a4576102a361013d565b5b60026102b184828561022f565b91505092915050565b6000604082840312156102d0576102cf610138565b5b60006102de8482850161028f565b91505092915050565b6102f0816101f9565b82525050565b600060208201905061030b60008301846102e7565b92915050565b600060029050919050565b600081905092915050565b6000819050919050565b61033a816101f9565b82525050565b600061034c8383610331565b60208301905092915050565b6000602082019050919050565b61036e81610311565b610378818461031c565b925061038382610327565b8060005b838110156103b457815161039b8782610340565b96506103a683610358565b925050600181019050610387565b505050505050565b60006040820190506103d16000830184610365565b92915050565b6000815190506103e681610203565b92915050565b60006020828403121561040257610401610138565b5b6000610410848285016103d7565b9150509291505056fea26469706673582212207d88c1e3e3770369b8191d659faefd696dbbefdede5e363482a4a6619719344864736f6c634300080f0033", + "libraries": { + "PoseidonT3": "0xbeeeAcde37Bce9011326137a49Bd5CA8153E9FCD" + }, "devdoc": { "kind": "dev", "methods": { - "hash(uint256)": { + "hash(uint256[2])": { "params": { - "input": "The input to hash" + "inputs": "The input to hash" } } }, @@ -57,8 +73,8 @@ "userdoc": { "kind": "user", "methods": { - "hash(uint256)": { - "notice": "Hashes the input using the Poseidon hash function, n = 2, second input is the constant 0" + "hash(uint256[2])": { + "notice": "Hashes the input using the Poseidon hash function, n = 2" } }, "version": 1 diff --git a/deployments/sepolia/PoseidonT3.json b/deployments/sepolia/PoseidonT3.json new file mode 100644 index 0000000..f94307c --- /dev/null +++ b/deployments/sepolia/PoseidonT3.json @@ -0,0 +1,60 @@ +{ + "address": "0xbeeeAcde37Bce9011326137a49Bd5CA8153E9FCD", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256[2]", + "name": "", + "type": "uint256[2]" + } + ], + "name": "hash", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x1e99a6d0b487cc40622a4b4ef969b50357cdd1b6780637e9f77fcad2bba69453", + "receipt": { + "to": null, + "from": "0x3F47b2a1dF96DE2e198d646b598C37251CCC3b98", + "contractAddress": "0xbeeeAcde37Bce9011326137a49Bd5CA8153E9FCD", + "transactionIndex": 31, + "gasUsed": "5245581", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x96ec0b98d724a2e2c109e2c48ce4c7031b05705d5d9d28b5737b01a3c21a1330", + "transactionHash": "0x1e99a6d0b487cc40622a4b4ef969b50357cdd1b6780637e9f77fcad2bba69453", + "logs": [], + "blockNumber": 4794981, + "cumulativeGasUsed": "12450588", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "3f87313134e2217cb187bd594084789f", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"\",\"type\":\"uint256[2]\"}],\"name\":\"hash\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"poseidon-solidity/PoseidonT3.sol\":\"PoseidonT3\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\"]},\"sources\":{\"poseidon-solidity/PoseidonT3.sol\":{\"content\":\"/// SPDX-License-Identifier: MIT\\npragma solidity >=0.7.0;\\n\\nlibrary PoseidonT3 {\\n uint constant M00 = 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b;\\n uint constant M01 = 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771;\\n uint constant M02 = 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7;\\n uint constant M10 = 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0;\\n uint constant M11 = 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23;\\n uint constant M12 = 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911;\\n\\n // See here for a simplified implementation: https://github.com/vimwitch/poseidon-solidity/blob/e57becdabb65d99fdc586fe1e1e09e7108202d53/contracts/Poseidon.sol#L40\\n // Inspired by: https://github.com/iden3/circomlibjs/blob/v0.0.8/src/poseidon_slow.js\\n function hash(uint[2] memory) public pure returns (uint) {\\n assembly {\\n let F := 21888242871839275222246405745257275088548364400416034343698204186575808495617\\n let M20 := 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d\\n let M21 := 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa\\n let M22 := 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0\\n\\n // load the inputs from memory\\n let state1 := add(mod(mload(0x80), F), 0x00f1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864)\\n let state2 := add(mod(mload(0xa0), F), 0x08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5)\\n let scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n scratch0 := add(\\n 0x2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d0,\\n add(add(15452833169820924772166449970675545095234312153403844297388521437673434406763, mulmod(state1, M10, F)), mulmod(state2, M20, F))\\n )\\n let scratch1 := add(\\n 0x2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf2,\\n add(add(18674271267752038776579386132900109523609358935013267566297499497165104279117, mulmod(state1, M11, F)), mulmod(state2, M21, F))\\n )\\n let scratch2 := add(\\n 0x0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa,\\n add(add(14817777843080276494683266178512808687156649753153012854386334860566696099579, mulmod(state1, M12, F)), mulmod(state2, M22, F))\\n )\\n let state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc632, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n scratch0 := add(0x15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c8705, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd1, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x005032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c887, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da53, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0081c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb38, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c502, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x00ef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba89, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c5, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e4, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e13, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a90035, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db69, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b8, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c77, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x002e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x00b9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c3512, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x00248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a808, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f09, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e8284, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd800, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f178, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e504233, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d59, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f88948, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d142, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c0, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a58, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d01, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc792, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea6111, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa336, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d6, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f451, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf77, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc630, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c2320, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n scratch0 := add(0x0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f8, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e4228325161, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n\\n mstore(0x0, mod(add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)), F))\\n\\n return(0, 0x20)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0102caa303bbc6690508f3615604f7730789ed990058c9513a87ccb30e4835be\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x615dc862000054600b82828239805160001a607314610047577f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100355760003560e01c8063561558fe1461003a575b600080fd5b610054600480360381019061004f9190615d3b565b61006a565b6040516100619190615d77565b60405180910390f35b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000017f2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d7f101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa7f19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e07ef1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e8648460805106017f08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f58560a05106018582830986838883840909925086828309905086828883840909915086868309877f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085097f2229fe5e63f56eef4bfba02c26292de10ac2b2b045e6184acff16e4660c05f6b01017f2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d001905086858309877f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385097f2949435275a29cdbffe3e4101a45669873f9408a5d11e21b4ec6edf8501eee4d01017f2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf20187858409887f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291186097f20c290a7269657965092ef5700a447f5bc2c41dfca932f527cb2600ac9bcfefb01017f0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa018883840989848b83840909935089838409905089838b83840909925089828309905089828b838409099150898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc63201945089818209935089818b86870909905089868709935089868b86870909955089858609935089858b868709099450898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c01915089848509905089848b83840909935089838409905089838b83840909925089828309905089828b838409099150898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c870501945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd101945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017e5032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc001915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c88701915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da5301945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017e81c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb3801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a001915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c50201945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017eef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba8901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c501945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e401915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e1301945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a9003501945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db6901945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c7701945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017e2e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017eb9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c351201945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017e248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a80801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f0901945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e828401915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd80001915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f17801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e50423301945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc001915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d5901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f8894801945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d14201915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c001945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a5801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d0101945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc79201945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea611101915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa33601945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d601915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f45101945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf7701915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc63001945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc01915089848509905089848b83840909935089838409905089838b83840909925089828309905089828b838409099150898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c232001945089818209935089818b86870909905089868709935089868b86870909955089858609935089858b868709099450898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f801915089848509905089848b83840909935089838409905089838b83840909925089828309905089828b838409099150898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e422832516101945089818209935089818b86870909905089868709935089868b86870909955089858609935089858b868709099450898a8a87098b7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e089098c7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b850901010660005260206000f35b6000604051905090565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b615c0c82615bc3565b810181811067ffffffffffffffff82111715615c2b57615c2a615bd4565b5b80604052505050565b6000615c3e615baf565b9050615c4a8282615c03565b919050565b600067ffffffffffffffff821115615c6a57615c69615bd4565b5b602082029050919050565b600080fd5b6000819050919050565b615c8d81615c7a565b8114615c9857600080fd5b50565b600081359050615caa81615c84565b92915050565b6000615cc3615cbe84615c4f565b615c34565b90508060208402830185811115615cdd57615cdc615c75565b5b835b81811015615d065780615cf28882615c9b565b845260208401935050602081019050615cdf565b5050509392505050565b600082601f830112615d2557615d24615bbe565b5b6002615d32848285615cb0565b91505092915050565b600060408284031215615d5157615d50615bb9565b5b6000615d5f84828501615d10565b91505092915050565b615d7181615c7a565b82525050565b6000602082019050615d8c6000830184615d68565b9291505056fea26469706673582212205e9ebc76a30def89ee11daab057c925ab867e4e5f0c6f5642d9b9d5f1d4bbcc164736f6c634300080f0033", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600436106100355760003560e01c8063561558fe1461003a575b600080fd5b610054600480360381019061004f9190615d3b565b61006a565b6040516100619190615d77565b60405180910390f35b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000017f2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d7f101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa7f19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e07ef1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e8648460805106017f08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f58560a05106018582830986838883840909925086828309905086828883840909915086868309877f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085097f2229fe5e63f56eef4bfba02c26292de10ac2b2b045e6184acff16e4660c05f6b01017f2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d001905086858309877f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385097f2949435275a29cdbffe3e4101a45669873f9408a5d11e21b4ec6edf8501eee4d01017f2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf20187858409887f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291186097f20c290a7269657965092ef5700a447f5bc2c41dfca932f527cb2600ac9bcfefb01017f0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa018883840989848b83840909935089838409905089838b83840909925089828309905089828b838409099150898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc63201945089818209935089818b86870909905089868709935089868b86870909955089858609935089858b868709099450898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c01915089848509905089848b83840909935089838409905089838b83840909925089828309905089828b838409099150898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c870501945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd101945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017e5032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc001915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c88701915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da5301945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017e81c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb3801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a001915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c50201945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017eef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba8901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c501945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e401915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e1301945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a9003501945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db6901945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c7701945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017e2e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017eb9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c351201945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017e248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a80801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f0901945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e828401915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd80001915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f17801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e50423301945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc001915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d5901915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f8894801945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d14201915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c001945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a5801915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d0101945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc79201945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea611101915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa33601945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d601915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f45101945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf7701915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc63001945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc01915089848509905089848b838409099350898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f01945089818209935089818b868709099050898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc01915089848509905089848b83840909935089838409905089838b83840909925089828309905089828b838409099150898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c232001945089818209935089818b86870909905089868709935089868b86870909955089858609935089858b868709099450898986098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e088098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b840901017f0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870019350898886098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2388098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771840901017f193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba019250898786098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291188098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7840901017f102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f801915089848509905089848b83840909935089838409905089838b83840909925089828309905089828b838409099150898983098a7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e085098b7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b870901017f0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1019050898883098a7f2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe2385098b7f2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771870901017f216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22019550898783098a7f176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee291185098b7f143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7870901017f1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e422832516101945089818209935089818b86870909905089868709935089868b86870909955089858609935089858b868709099450898a8a87098b7f16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e089098c7f109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b850901010660005260206000f35b6000604051905090565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b615c0c82615bc3565b810181811067ffffffffffffffff82111715615c2b57615c2a615bd4565b5b80604052505050565b6000615c3e615baf565b9050615c4a8282615c03565b919050565b600067ffffffffffffffff821115615c6a57615c69615bd4565b5b602082029050919050565b600080fd5b6000819050919050565b615c8d81615c7a565b8114615c9857600080fd5b50565b600081359050615caa81615c84565b92915050565b6000615cc3615cbe84615c4f565b615c34565b90508060208402830185811115615cdd57615cdc615c75565b5b835b81811015615d065780615cf28882615c9b565b845260208401935050602081019050615cdf565b5050509392505050565b600082601f830112615d2557615d24615bbe565b5b6002615d32848285615cb0565b91505092915050565b600060408284031215615d5157615d50615bb9565b5b6000615d5f84828501615d10565b91505092915050565b615d7181615c7a565b82525050565b6000602082019050615d8c6000830184615d68565b9291505056fea26469706673582212205e9ebc76a30def89ee11daab057c925ab867e4e5f0c6f5642d9b9d5f1d4bbcc164736f6c634300080f0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/sepolia/RLN.json b/deployments/sepolia/RLN.json index 1c1d4f5..d57301d 100644 --- a/deployments/sepolia/RLN.json +++ b/deployments/sepolia/RLN.json @@ -1,5 +1,5 @@ { - "address": "0xB8144E3214080f179D037bbb4dcaaa6B87f224E4", + "address": "0x3d2dcfF8Ee904C3F5Bf3043642C605DFcA7BEBA9", "abi": [ { "inputs": [ @@ -63,6 +63,17 @@ "name": "InsufficientWithdrawalBalance", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "idCommitment", + "type": "uint256" + } + ], + "name": "InvalidIdCommitment", + "type": "error" + }, { "inputs": [], "name": "InvalidProof", @@ -178,6 +189,32 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "computeRoot", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deployedBlockNumber", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "idCommitmentIndex", @@ -191,6 +228,72 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "imtData", + "outputs": [ + { + "internalType": "uint256", + "name": "depth", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "root", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "numberOfLeaves", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "useDefaultZeroes", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "idCommitment", + "type": "uint256" + } + ], + "name": "isValidCommitment", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "memberExists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -215,7 +318,7 @@ "name": "poseidonHasher", "outputs": [ { - "internalType": "contract IPoseidonHasher", + "internalType": "contract PoseidonHasher", "name": "", "type": "address" } @@ -318,33 +421,36 @@ "type": "function" } ], - "transactionHash": "0x953b7b48bfb80dfc2f08d130e7d7d8e1dd7a057cb620fec2bad94c014682c88b", + "transactionHash": "0x7ea7d070252093c16cd14e2b26fe436341510158619fcd3476e7525073600375", "receipt": { "to": null, "from": "0x3F47b2a1dF96DE2e198d646b598C37251CCC3b98", - "contractAddress": "0xB8144E3214080f179D037bbb4dcaaa6B87f224E4", - "transactionIndex": 14, - "gasUsed": "1051126", + "contractAddress": "0x3d2dcfF8Ee904C3F5Bf3043642C605DFcA7BEBA9", + "transactionIndex": 49, + "gasUsed": "1396320", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xd8c07196dd7465cfe900b8c5be3b810b409c93e22cfdc288e9be51793f218fab", - "transactionHash": "0x953b7b48bfb80dfc2f08d130e7d7d8e1dd7a057cb620fec2bad94c014682c88b", + "blockHash": "0x25b250fe02f9a4ef673a037a70113a4499249b16602d114fef61bfcdda73aa8f", + "transactionHash": "0x7ea7d070252093c16cd14e2b26fe436341510158619fcd3476e7525073600375", "logs": [], - "blockNumber": 3594457, - "cumulativeGasUsed": "1799720", + "blockNumber": 4794985, + "cumulativeGasUsed": "17170834", "status": 1, "byzantium": true }, "args": [ 1000000000000000, 20, - "0xa1554EAF0DF18C05956249aac375e212edeD2CcF", - "0xb81Faa6F0126dedB55A45eb63E8430B270A00303" + "0x2092b99411d480b8Dd04BfD68EF1F0d545b0eB1D", + "0xe36940B40aDe98F02a4829414F7e8d636CCf3663" ], - "numDeployments": 3, - "solcInputHash": "0e0cac683e804dc76f2f24c8a5b4012c", - "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"membershipDeposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"depth\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_poseidonHasher\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verifier\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"DuplicateIdCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FullTree\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientContractBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"provided\",\"type\":\"uint256\"}],\"name\":\"InsufficientDeposit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientWithdrawalBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"InvalidReceiverAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"}],\"name\":\"MemberHasNoStake\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"}],\"name\":\"MemberNotRegistered\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"MemberRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"MemberWithdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEPTH\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MEMBERSHIP_DEPOSIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SET_SIZE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"idCommitmentIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poseidonHasher\",\"outputs\":[{\"internalType\":\"contract IPoseidonHasher\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256[8]\",\"name\":\"proof\",\"type\":\"uint256[8]\"}],\"name\":\"slash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"stakedAmounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verifier\",\"outputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"withdrawalBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"InsufficientDeposit(uint256,uint256)\":[{\"params\":{\"provided\":\"The provided deposit amount\",\"required\":\"The required deposit amount\"}}]},\"events\":{\"MemberRegistered(uint256,uint256)\":{\"params\":{\"idCommitment\":\"The idCommitment of the member\",\"index\":\"The index of the member in the set\"}},\"MemberWithdrawn(uint256,uint256)\":{\"params\":{\"idCommitment\":\"The idCommitment of the member\",\"index\":\"The index of the member in the set\"}}},\"kind\":\"dev\",\"methods\":{\"register(uint256)\":{\"params\":{\"idCommitment\":\"The idCommitment of the member\"}},\"slash(uint256,address,uint256[8])\":{\"details\":\"Allows a user to slash a member\",\"params\":{\"idCommitment\":\"The idCommitment of the member\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"DuplicateIdCommitment()\":[{\"notice\":\"Member is already registered\"}],\"FullTree()\":[{\"notice\":\"The tree is full\"}],\"InsufficientContractBalance()\":[{\"notice\":\"Contract has insufficient balance to return\"}],\"InsufficientDeposit(uint256,uint256)\":[{\"notice\":\"Invalid deposit amount\"}],\"InsufficientWithdrawalBalance()\":[{\"notice\":\"User has insufficient balance to withdraw\"}],\"InvalidProof()\":[{\"notice\":\"Invalid proof\"}],\"InvalidReceiverAddress(address)\":[{\"notice\":\"Invalid receiver address, when the receiver is the contract itself or 0x0\"}],\"MemberHasNoStake(uint256)\":[{\"notice\":\"Member has no stake\"}],\"MemberNotRegistered(uint256)\":[{\"notice\":\"Member is not registered\"}]},\"events\":{\"MemberRegistered(uint256,uint256)\":{\"notice\":\"Emitted when a new member is added to the set\"},\"MemberWithdrawn(uint256,uint256)\":{\"notice\":\"Emitted when a member is removed from the set\"}},\"kind\":\"user\",\"methods\":{\"DEPTH()\":{\"notice\":\"The depth of the merkle tree\"},\"MEMBERSHIP_DEPOSIT()\":{\"notice\":\"The deposit amount required to register as a member\"},\"SET_SIZE()\":{\"notice\":\"The size of the merkle tree, i.e 2^depth\"},\"idCommitmentIndex()\":{\"notice\":\"The index of the next member to be registered\"},\"members(uint256)\":{\"notice\":\"The membership status of each member maps from idCommitment to their index in the set\"},\"poseidonHasher()\":{\"notice\":\"The Poseidon hasher contract\"},\"register(uint256)\":{\"notice\":\"Allows a user to register as a member\"},\"stakedAmounts(uint256)\":{\"notice\":\"The amount of eth staked by each member maps from idCommitment to the amount staked\"},\"verifier()\":{\"notice\":\"The groth16 verifier contract\"},\"withdraw()\":{\"notice\":\"Allows a user to withdraw funds allocated to them upon slashing a member\"},\"withdrawalBalance(address)\":{\"notice\":\"The balance of each user that can be withdrawn\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Rln.sol\":\"RLN\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\"]},\"sources\":{\"contracts/IVerifier.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0 OR MIT\\npragma solidity 0.8.15;\\n\\ninterface IVerifier {\\n function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)\\n external\\n view\\n returns (bool);\\n}\\n\",\"keccak256\":\"0x538e61fbb62bf1ef9f0c3f7e7d771ddfc8506a97e7d98aada763830fc741d8b8\",\"license\":\"Apache-2.0 OR MIT\"},\"contracts/PoseidonHasher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Forked from https://github.com/kilic/rlnapp/\\n\\npragma solidity 0.8.15;\\n\\ninterface IPoseidonHasher {\\n /// @notice Hashes the input using the Poseidon hash function, n = 2, second input is the constant 0\\n /// @param input The input to hash\\n function hash(uint256 input) external pure returns (uint256 result);\\n}\\n\\ncontract PoseidonHasher is IPoseidonHasher {\\n uint256 constant Q =\\n 21888242871839275222246405745257275088548364400416034343698204186575808495617;\\n uint256 constant C0 =\\n 4417881134626180770308697923359573201005643519861877412381846989312604493735;\\n uint256 constant C1 =\\n 5433650512959517612316327474713065966758808864213826738576266661723522780033;\\n uint256 constant C2 =\\n 13641176377184356099764086973022553863760045607496549923679278773208775739952;\\n uint256 constant C3 =\\n 17949713444224994136330421782109149544629237834775211751417461773584374506783;\\n uint256 constant C4 =\\n 13765628375339178273710281891027109699578766420463125835325926111705201856003;\\n uint256 constant C5 =\\n 19179513468172002314585757290678967643352171735526887944518845346318719730387;\\n uint256 constant C6 =\\n 5157412437176756884543472904098424903141745259452875378101256928559722612176;\\n uint256 constant C7 =\\n 535160875740282236955320458485730000677124519901643397458212725410971557409;\\n uint256 constant C8 =\\n 1050793453380762984940163090920066886770841063557081906093018330633089036729;\\n uint256 constant C9 =\\n 10665495010329663932664894101216428400933984666065399374198502106997623173873;\\n uint256 constant C10 =\\n 19965634623406616956648724894636666805991993496469370618546874926025059150737;\\n uint256 constant C11 =\\n 13007250030070838431593222885902415182312449212965120303174723305710127422213;\\n uint256 constant C12 =\\n 16877538715074991604507979123743768693428157847423939051086744213162455276374;\\n uint256 constant C13 =\\n 18211747749504876135588847560312685184956239426147543810126553367063157141465;\\n uint256 constant C14 =\\n 18151553319826126919739798892854572062191241985315767086020821632812331245635;\\n uint256 constant C15 =\\n 19957033149976712666746140949846950406660099037474791840946955175819555930825;\\n uint256 constant C16 =\\n 3469514863538261843186854830917934449567467100548474599735384052339577040841;\\n uint256 constant C17 =\\n 989698510043911779243192466312362856042600749099921773896924315611668507708;\\n uint256 constant C18 =\\n 12568377015646290945235387813564567111330046038050864455358059568128000172201;\\n uint256 constant C19 =\\n 20856104135605479600325529349246932565148587186338606236677138505306779314172;\\n uint256 constant C20 =\\n 8206918720503535523121349917159924938835810381723474192155637697065780938424;\\n uint256 constant C21 =\\n 1309058477013932989380617265069188723120054926187607548493110334522527703566;\\n uint256 constant C22 =\\n 14076116939332667074621703729512195584105250395163383769419390236426287710606;\\n uint256 constant C23 =\\n 10153498892749751942204288991871286290442690932856658983589258153608012428674;\\n uint256 constant C24 =\\n 18202499207234128286137597834010475797175973146805180988367589376893530181575;\\n uint256 constant C25 =\\n 12739388830157083522877690211447248168864006284243907142044329113461613743052;\\n uint256 constant C26 =\\n 15123358710467780770838026754240340042441262572309759635224051333176022613949;\\n uint256 constant C27 =\\n 19925004701844594370904593774447343836015483888496504201331110250494635362184;\\n uint256 constant C28 =\\n 10352416606816998476681131583320899030072315953910679608943150613208329645891;\\n uint256 constant C29 =\\n 10567371822366244361703342347428230537114808440249611395507235283708966113221;\\n uint256 constant C30 =\\n 5635498582763880627392290206431559361272660937399944184533035305989295959602;\\n uint256 constant C31 =\\n 11866432933224219174041051738704352719163271639958083608224676028593315904909;\\n uint256 constant C32 =\\n 5795020705294401441272215064554385591292330721703923167136157291459784140431;\\n uint256 constant C33 =\\n 9482202378699252817564375087302794636287866584767523335624368774856230692758;\\n uint256 constant C34 =\\n 4245237636894546151746468406560945873445548423466753843402086544922216329298;\\n uint256 constant C35 =\\n 12000500941313982757584712677991730019124834399479314697467598397927435905133;\\n uint256 constant C36 =\\n 7596790274058425558167520209857956363736666939016807569082239187494363541787;\\n uint256 constant C37 =\\n 2484867918246116343205467273440098378820186751202461278013576281097918148877;\\n uint256 constant C38 =\\n 18312645949449997391810445935615409295369169383463185688973803378104013950190;\\n uint256 constant C39 =\\n 15320686572748723004980855263301182130424010735782762814513954166519592552733;\\n uint256 constant C40 =\\n 12618438900597948888520621062416758747872180395546164387827245287017031303859;\\n uint256 constant C41 =\\n 17438141672027706116733201008397064011774368832458707512367404736905021019585;\\n uint256 constant C42 =\\n 6374197807230665998865688675365359100400438034755781666913068586172586548950;\\n uint256 constant C43 =\\n 2189398913433273865510950346186699930188746169476472274335177556702504595264;\\n uint256 constant C44 =\\n 6268495580028970231803791523870131137294646402347399003576649137450213034606;\\n uint256 constant C45 =\\n 17896250365994900261202920044129628104272791547990619503076839618914047059275;\\n uint256 constant C46 =\\n 13692156312448722528008862371944543449350293305158722920787736248435893008873;\\n uint256 constant C47 =\\n 15234446864368744483209945022439268713300180233589581910497691316744177619376;\\n uint256 constant C48 =\\n 1572426502623310766593681563281600503979671244997798691029595521622402217227;\\n uint256 constant C49 =\\n 80103447810215150918585162168214870083573048458555897999822831203653996617;\\n uint256 constant C50 =\\n 8228820324013669567851850635126713973797711779951230446503353812192849106342;\\n uint256 constant C51 =\\n 5375851433746509614045812476958526065449377558695752132494533666370449415873;\\n uint256 constant C52 =\\n 12115998939203497346386774317892338270561208357481805380546938146796257365018;\\n uint256 constant C53 =\\n 9764067909645821279940531410531154041386008396840887338272986634350423466622;\\n uint256 constant C54 =\\n 8538708244538850542384936174629541085495830544298260335345008245230827876882;\\n uint256 constant C55 =\\n 7140127896620013355910287215441004676619168261422440177712039790284719613114;\\n uint256 constant C56 =\\n 14297402962228458726038826185823085337698917275385741292940049024977027409762;\\n uint256 constant C57 =\\n 6667115556431351074165934212337261254608231545257434281887966406956835140819;\\n uint256 constant C58 =\\n 20226761165244293291042617464655196752671169026542832236139342122602741090001;\\n uint256 constant C59 =\\n 12038289506489256655759141386763477208196694421666339040483042079632134429119;\\n uint256 constant C60 =\\n 19027757334170818571203982241812412991528769934917288000224335655934473717551;\\n uint256 constant C61 =\\n 16272152964456553579565580463468069884359929612321610357528838696790370074720;\\n uint256 constant C62 =\\n 2500392889689246014710135696485946334448570271481948765283016105301740284071;\\n uint256 constant C63 =\\n 8595254970528530312401637448610398388203855633951264114100575485022581946023;\\n uint256 constant C64 =\\n 11635945688914011450976408058407206367914559009113158286982919675551688078198;\\n uint256 constant C65 =\\n 614739068603482619581328040478536306925147663946742687395148680260956671871;\\n uint256 constant C66 =\\n 18692271780377861570175282183255720350972693125537599213951106550953176268753;\\n uint256 constant C67 =\\n 4987059230784976306647166378298632695585915319042844495357753339378260807164;\\n uint256 constant C68 =\\n 21851403978498723616722415377430107676258664746210815234490134600998983955497;\\n uint256 constant C69 =\\n 9830635451186415300891533983087800047564037813328875992115573428596207326204;\\n uint256 constant C70 =\\n 4842706106434537116860242620706030229206345167233200482994958847436425185478;\\n uint256 constant C71 =\\n 6422235064906823218421386871122109085799298052314922856340127798647926126490;\\n uint256 constant C72 =\\n 4564364104986856861943331689105797031330091877115997069096365671501473357846;\\n uint256 constant C73 =\\n 1944043894089780613038197112872830569538541856657037469098448708685350671343;\\n uint256 constant C74 =\\n 21179865974855950600518216085229498748425990426231530451599322283119880194955;\\n uint256 constant C75 =\\n 14296697761894107574369608843560006996183955751502547883167824879840894933162;\\n uint256 constant C76 =\\n 12274619649702218570450581712439138337725246879938860735460378251639845671898;\\n uint256 constant C77 =\\n 16371396450276899401411886674029075408418848209575273031725505038938314070356;\\n uint256 constant C78 =\\n 3702561221750983937578095019779188631407216522704543451228773892695044653565;\\n uint256 constant C79 =\\n 19721616877735564664624984774636557499099875603996426215495516594530838681980;\\n uint256 constant C80 =\\n 6383350109027696789969911008057747025018308755462287526819231672217685282429;\\n uint256 constant C81 =\\n 20860583956177367265984596617324237471765572961978977333122281041544719622905;\\n uint256 constant C82 =\\n 5766390934595026947545001478457407504285452477687752470140790011329357286275;\\n uint256 constant C83 =\\n 4043175758319898049344746138515323336207420888499903387536875603879441092484;\\n uint256 constant C84 =\\n 15579382179133608217098622223834161692266188678101563820988612253342538956534;\\n uint256 constant C85 =\\n 1864640783252634743892105383926602930909039567065240010338908865509831749824;\\n uint256 constant C86 =\\n 15943719865023133586707144161652035291705809358178262514871056013754142625673;\\n uint256 constant C87 =\\n 2326415993032390211558498780803238091925402878871059708106213703504162832999;\\n uint256 constant C88 =\\n 19995326402773833553207196590622808505547443523750970375738981396588337910289;\\n uint256 constant C89 =\\n 5143583711361588952673350526320181330406047695593201009385718506918735286622;\\n uint256 constant C90 =\\n 15436006486881920976813738625999473183944244531070780793506388892313517319583;\\n uint256 constant C91 =\\n 16660446760173633166698660166238066533278664023818938868110282615200613695857;\\n uint256 constant C92 =\\n 4966065365695755376133119391352131079892396024584848298231004326013366253934;\\n uint256 constant C93 =\\n 20683781957411705574951987677641476019618457561419278856689645563561076926702;\\n uint256 constant C94 =\\n 17280836839165902792086432296371645107551519324565649849400948918605456875699;\\n uint256 constant C95 =\\n 17045635513701208892073056357048619435743564064921155892004135325530808465371;\\n uint256 constant C96 =\\n 17055032967194400710390142791334572297458033582458169295920670679093585707295;\\n uint256 constant C97 =\\n 15727174639569115300068198908071514334002742825679221638729902577962862163505;\\n uint256 constant C98 =\\n 1001755657610446661315902885492677747789366510875120894840818704741370398633;\\n uint256 constant C99 =\\n 18638547332826171619311285502376343504539399518545103511265465604926625041234;\\n uint256 constant C100 =\\n 6751954224763196429755298529194402870632445298969935050224267844020826420799;\\n uint256 constant C101 =\\n 3526747115904224771452549517614107688674036840088422555827581348280834879405;\\n uint256 constant C102 =\\n 15705897908180497062880001271426561999724005008972544196300715293701537574122;\\n uint256 constant C103 =\\n 574386695213920937259007343820417029802510752426579750428758189312416867750;\\n uint256 constant C104 =\\n 15973040855000600860816974646787367136127946402908768408978806375685439868553;\\n uint256 constant C105 =\\n 20934130413948796333037139460875996342810005558806621330680156931816867321122;\\n uint256 constant C106 =\\n 6918585327145564636398173845411579411526758237572034236476079610890705810764;\\n uint256 constant C107 =\\n 14158163500813182062258176233162498241310167509137716527054939926126453647182;\\n uint256 constant C108 =\\n 4164602626597695668474100217150111342272610479949122406544277384862187287433;\\n uint256 constant C109 =\\n 12146526846507496913615390662823936206892812880963914267275606265272996025304;\\n uint256 constant C110 =\\n 10153527926900017763244212043512822363696541810586522108597162891799345289938;\\n uint256 constant C111 =\\n 13564663485965299104296214940873270349072051793008946663855767889066202733588;\\n uint256 constant C112 =\\n 5612449256997576125867742696783020582952387615430650198777254717398552960096;\\n uint256 constant C113 =\\n 12151885480032032868507892738683067544172874895736290365318623681886999930120;\\n uint256 constant C114 =\\n 380452237704664384810613424095477896605414037288009963200982915188629772177;\\n uint256 constant C115 =\\n 9067557551252570188533509616805287919563636482030947363841198066124642069518;\\n uint256 constant C116 =\\n 21280306817619711661335268484199763923870315733198162896599997188206277056900;\\n uint256 constant C117 =\\n 5567165819557297006750252582140767993422097822227408837378089569369734876257;\\n uint256 constant C118 =\\n 10411936321072105429908396649383171465939606386380071222095155850987201580137;\\n uint256 constant C119 =\\n 21338390051413922944780864872652000187403217966653363270851298678606449622266;\\n uint256 constant C120 =\\n 12156296560457833712186127325312904760045212412680904475497938949653569234473;\\n uint256 constant C121 =\\n 4271647814574748734312113971565139132510281260328947438246615707172526380757;\\n uint256 constant C122 =\\n 9061738206062369647211128232833114177054715885442782773131292534862178874950;\\n uint256 constant C123 =\\n 10134551893627587797380445583959894183158393780166496661696555422178052339133;\\n uint256 constant C124 =\\n 8932270237664043612366044102088319242789325050842783721780970129656616386103;\\n uint256 constant C125 =\\n 3339412934966886386194449782756711637636784424032779155216609410591712750636;\\n uint256 constant C126 =\\n 9704903972004596791086522314847373103670545861209569267884026709445485704400;\\n uint256 constant C127 =\\n 17467570179597572575614276429760169990940929887711661192333523245667228809456;\\n uint256 constant M00 =\\n 2910766817845651019878574839501801340070030115151021261302834310722729507541;\\n uint256 constant M01 =\\n 19727366863391167538122140361473584127147630672623100827934084310230022599144;\\n uint256 constant M10 =\\n 5776684794125549462448597414050232243778680302179439492664047328281728356345;\\n uint256 constant M11 =\\n 8348174920934122550483593999453880006756108121341067172388445916328941978568;\\n\\n function hash(\\n uint256 input\\n ) external pure override returns (uint256 result) {\\n return _hash(input);\\n }\\n\\n function _hash(uint256 input) internal pure returns (uint256 result) {\\n assembly {\\n // Poseidon parameters should be t = 2, RF = 8, RP = 56\\n\\n // We load the characteristic\\n let q := Q\\n\\n // In zerokit implementation, if we pass inp = [a0,a1,..,an] to Poseidon what is effectively hashed is [0,a0,a1,..,an]\\n // Note that a sequence of MIX-ARK involves 3 Bn254 field additions before the mulmod happens. Worst case we have a value corresponding to 2*(p-1) which is less than 2^256 and hence doesn't overflow\\n //ROUND 0 - FULL\\n let s0 := C0\\n let s1 := add(input, C1)\\n // SBOX\\n let t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 1 - FULL\\n s0 := add(s0, C2)\\n s1 := add(s1, C3)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 2 - FULL\\n s0 := add(s0, C4)\\n s1 := add(s1, C5)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 3 - FULL\\n s0 := add(s0, C6)\\n s1 := add(s1, C7)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 4 - PARTIAL\\n s0 := add(s0, C8)\\n s1 := add(s1, C9)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 5 - PARTIAL\\n s0 := add(s0, C10)\\n s1 := add(s1, C11)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 6 - PARTIAL\\n s0 := add(s0, C12)\\n s1 := add(s1, C13)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 7 - PARTIAL\\n s0 := add(s0, C14)\\n s1 := add(s1, C15)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 8 - PARTIAL\\n s0 := add(s0, C16)\\n s1 := add(s1, C17)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 9 - PARTIAL\\n s0 := add(s0, C18)\\n s1 := add(s1, C19)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 10 - PARTIAL\\n s0 := add(s0, C20)\\n s1 := add(s1, C21)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 11 - PARTIAL\\n s0 := add(s0, C22)\\n s1 := add(s1, C23)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 12 - PARTIAL\\n s0 := add(s0, C24)\\n s1 := add(s1, C25)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 13 - PARTIAL\\n s0 := add(s0, C26)\\n s1 := add(s1, C27)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 14 - PARTIAL\\n s0 := add(s0, C28)\\n s1 := add(s1, C29)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 15 - PARTIAL\\n s0 := add(s0, C30)\\n s1 := add(s1, C31)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 16 - PARTIAL\\n s0 := add(s0, C32)\\n s1 := add(s1, C33)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 17 - PARTIAL\\n s0 := add(s0, C34)\\n s1 := add(s1, C35)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 18 - PARTIAL\\n s0 := add(s0, C36)\\n s1 := add(s1, C37)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 19 - PARTIAL\\n s0 := add(s0, C38)\\n s1 := add(s1, C39)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 20 - PARTIAL\\n s0 := add(s0, C40)\\n s1 := add(s1, C41)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 21 - PARTIAL\\n s0 := add(s0, C42)\\n s1 := add(s1, C43)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 22 - PARTIAL\\n s0 := add(s0, C44)\\n s1 := add(s1, C45)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 23 - PARTIAL\\n s0 := add(s0, C46)\\n s1 := add(s1, C47)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 24 - PARTIAL\\n s0 := add(s0, C48)\\n s1 := add(s1, C49)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 25 - PARTIAL\\n s0 := add(s0, C50)\\n s1 := add(s1, C51)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 26 - PARTIAL\\n s0 := add(s0, C52)\\n s1 := add(s1, C53)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 27 - PARTIAL\\n s0 := add(s0, C54)\\n s1 := add(s1, C55)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 28 - PARTIAL\\n s0 := add(s0, C56)\\n s1 := add(s1, C57)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 29 - PARTIAL\\n s0 := add(s0, C58)\\n s1 := add(s1, C59)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 30 - PARTIAL\\n s0 := add(s0, C60)\\n s1 := add(s1, C61)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 31 - PARTIAL\\n s0 := add(s0, C62)\\n s1 := add(s1, C63)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 32 - PARTIAL\\n s0 := add(s0, C64)\\n s1 := add(s1, C65)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 33 - PARTIAL\\n s0 := add(s0, C66)\\n s1 := add(s1, C67)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 34 - PARTIAL\\n s0 := add(s0, C68)\\n s1 := add(s1, C69)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 35 - PARTIAL\\n s0 := add(s0, C70)\\n s1 := add(s1, C71)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 36 - PARTIAL\\n s0 := add(s0, C72)\\n s1 := add(s1, C73)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 37 - PARTIAL\\n s0 := add(s0, C74)\\n s1 := add(s1, C75)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 38 - PARTIAL\\n s0 := add(s0, C76)\\n s1 := add(s1, C77)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 39 - PARTIAL\\n s0 := add(s0, C78)\\n s1 := add(s1, C79)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 40 - PARTIAL\\n s0 := add(s0, C80)\\n s1 := add(s1, C81)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 41 - PARTIAL\\n s0 := add(s0, C82)\\n s1 := add(s1, C83)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 42 - PARTIAL\\n s0 := add(s0, C84)\\n s1 := add(s1, C85)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 43 - PARTIAL\\n s0 := add(s0, C86)\\n s1 := add(s1, C87)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 44 - PARTIAL\\n s0 := add(s0, C88)\\n s1 := add(s1, C89)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 45 - PARTIAL\\n s0 := add(s0, C90)\\n s1 := add(s1, C91)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 46 - PARTIAL\\n s0 := add(s0, C92)\\n s1 := add(s1, C93)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 47 - PARTIAL\\n s0 := add(s0, C94)\\n s1 := add(s1, C95)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 48 - PARTIAL\\n s0 := add(s0, C96)\\n s1 := add(s1, C97)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 49 - PARTIAL\\n s0 := add(s0, C98)\\n s1 := add(s1, C99)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 50 - PARTIAL\\n s0 := add(s0, C100)\\n s1 := add(s1, C101)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 51 - PARTIAL\\n s0 := add(s0, C102)\\n s1 := add(s1, C103)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 52 - PARTIAL\\n s0 := add(s0, C104)\\n s1 := add(s1, C105)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 53 - PARTIAL\\n s0 := add(s0, C106)\\n s1 := add(s1, C107)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 54 - PARTIAL\\n s0 := add(s0, C108)\\n s1 := add(s1, C109)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 55 - PARTIAL\\n s0 := add(s0, C110)\\n s1 := add(s1, C111)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 56 - PARTIAL\\n s0 := add(s0, C112)\\n s1 := add(s1, C113)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 57 - PARTIAL\\n s0 := add(s0, C114)\\n s1 := add(s1, C115)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 58 - PARTIAL\\n s0 := add(s0, C116)\\n s1 := add(s1, C117)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 59 - PARTIAL\\n s0 := add(s0, C118)\\n s1 := add(s1, C119)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 60 - FULL\\n s0 := add(s0, C120)\\n s1 := add(s1, C121)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 61 - FULL\\n s0 := add(s0, C122)\\n s1 := add(s1, C123)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 62 - FULL\\n s0 := add(s0, C124)\\n s1 := add(s1, C125)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\\n s0 := t\\n\\n //ROUND 63 - FULL\\n s0 := add(s0, C126)\\n s1 := add(s1, C127)\\n // SBOX\\n t := mulmod(s0, s0, q)\\n s0 := mulmod(mulmod(t, t, q), s0, q)\\n t := mulmod(s1, s1, q)\\n s1 := mulmod(mulmod(t, t, q), s1, q)\\n // MIX\\n s0 := mod(add(mulmod(s0, M00, q), mulmod(s1, M01, q)), q)\\n\\n result := s0\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf351af92fff6ed1dc02f1180c0c4906e79f1b825dd76df186caa787029a8de6a\",\"license\":\"MIT\"},\"contracts/Rln.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.15;\\n\\nimport {IPoseidonHasher} from \\\"./PoseidonHasher.sol\\\";\\nimport {IVerifier} from \\\"./IVerifier.sol\\\";\\n\\n/// The tree is full\\nerror FullTree();\\n\\n/// Invalid deposit amount\\n/// @param required The required deposit amount\\n/// @param provided The provided deposit amount\\nerror InsufficientDeposit(uint256 required, uint256 provided);\\n\\n/// Member is already registered\\nerror DuplicateIdCommitment();\\n\\n/// Invalid receiver address, when the receiver is the contract itself or 0x0\\nerror InvalidReceiverAddress(address to);\\n\\n/// Member is not registered\\nerror MemberNotRegistered(uint256 idCommitment);\\n\\n/// Member has no stake\\nerror MemberHasNoStake(uint256 idCommitment);\\n\\n/// User has insufficient balance to withdraw\\nerror InsufficientWithdrawalBalance();\\n\\n/// Contract has insufficient balance to return\\nerror InsufficientContractBalance();\\n\\n/// Invalid proof\\nerror InvalidProof();\\n\\ncontract RLN {\\n /// @notice The deposit amount required to register as a member\\n uint256 public immutable MEMBERSHIP_DEPOSIT;\\n\\n /// @notice The depth of the merkle tree\\n uint256 public immutable DEPTH;\\n\\n /// @notice The size of the merkle tree, i.e 2^depth\\n uint256 public immutable SET_SIZE;\\n\\n /// @notice The index of the next member to be registered\\n uint256 public idCommitmentIndex = 1;\\n\\n /// @notice The amount of eth staked by each member\\n /// maps from idCommitment to the amount staked\\n mapping(uint256 => uint256) public stakedAmounts;\\n\\n /// @notice The membership status of each member\\n /// maps from idCommitment to their index in the set\\n mapping(uint256 => uint256) public members;\\n\\n /// @notice The balance of each user that can be withdrawn\\n mapping(address => uint256) public withdrawalBalance;\\n\\n /// @notice The Poseidon hasher contract\\n IPoseidonHasher public immutable poseidonHasher;\\n\\n /// @notice The groth16 verifier contract\\n IVerifier public immutable verifier;\\n\\n /// Emitted when a new member is added to the set\\n /// @param idCommitment The idCommitment of the member\\n /// @param index The index of the member in the set\\n event MemberRegistered(uint256 idCommitment, uint256 index);\\n\\n /// Emitted when a member is removed from the set\\n /// @param idCommitment The idCommitment of the member\\n /// @param index The index of the member in the set\\n event MemberWithdrawn(uint256 idCommitment, uint256 index);\\n\\n constructor(uint256 membershipDeposit, uint256 depth, address _poseidonHasher, address _verifier) {\\n MEMBERSHIP_DEPOSIT = membershipDeposit;\\n DEPTH = depth;\\n SET_SIZE = 1 << depth;\\n poseidonHasher = IPoseidonHasher(_poseidonHasher);\\n verifier = IVerifier(_verifier);\\n }\\n\\n /// Allows a user to register as a member\\n /// @param idCommitment The idCommitment of the member\\n function register(uint256 idCommitment) external payable {\\n if (msg.value != MEMBERSHIP_DEPOSIT) {\\n revert InsufficientDeposit(MEMBERSHIP_DEPOSIT, msg.value);\\n }\\n _register(idCommitment, msg.value);\\n }\\n\\n /// Registers a member\\n /// @param idCommitment The idCommitment of the member\\n /// @param stake The amount of eth staked by the member\\n function _register(uint256 idCommitment, uint256 stake) internal {\\n if (members[idCommitment] != 0) revert DuplicateIdCommitment();\\n if (idCommitmentIndex >= SET_SIZE) revert FullTree();\\n\\n members[idCommitment] = idCommitmentIndex;\\n stakedAmounts[idCommitment] = stake;\\n\\n emit MemberRegistered(idCommitment, idCommitmentIndex);\\n idCommitmentIndex += 1;\\n }\\n\\n /// @dev Allows a user to slash a member\\n /// @param idCommitment The idCommitment of the member\\n function slash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof) external {\\n _slash(idCommitment, receiver, proof);\\n }\\n\\n /// @dev Slashes a member by removing them from the set, and adding their\\n /// stake to the receiver's available withdrawal balance\\n /// @param idCommitment The idCommitment of the member\\n /// @param receiver The address to receive the funds\\n function _slash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof) internal {\\n if (receiver == address(this) || receiver == address(0)) {\\n revert InvalidReceiverAddress(receiver);\\n }\\n\\n if (members[idCommitment] == 0) revert MemberNotRegistered(idCommitment);\\n // check if member is registered\\n if (stakedAmounts[idCommitment] == 0) {\\n revert MemberHasNoStake(idCommitment);\\n }\\n\\n if (!_verifyProof(idCommitment, receiver, proof)) {\\n revert InvalidProof();\\n }\\n\\n uint256 amountToTransfer = stakedAmounts[idCommitment];\\n\\n // delete member\\n uint256 index = members[idCommitment];\\n members[idCommitment] = 0;\\n stakedAmounts[idCommitment] = 0;\\n\\n // refund deposit\\n withdrawalBalance[receiver] += amountToTransfer;\\n\\n emit MemberWithdrawn(idCommitment, index);\\n }\\n\\n /// Allows a user to withdraw funds allocated to them upon slashing a member\\n function withdraw() external {\\n uint256 amount = withdrawalBalance[msg.sender];\\n\\n if (amount == 0) revert InsufficientWithdrawalBalance();\\n if (amount > address(this).balance) {\\n revert InsufficientContractBalance();\\n }\\n\\n withdrawalBalance[msg.sender] = 0;\\n\\n payable(msg.sender).transfer(amount);\\n }\\n\\n /// Hashes a value using the Poseidon hasher\\n /// NOTE: The variant of Poseidon we use accepts only 1 input, assume n=2, and the second input is 0\\n /// @param input The value to hash\\n function hash(uint256 input) internal view returns (uint256) {\\n return poseidonHasher.hash(input);\\n }\\n\\n /// @dev Groth16 proof verification\\n function _verifyProof(uint256 idCommitment, address receiver, uint256[8] calldata proof)\\n internal\\n view\\n returns (bool)\\n {\\n return verifier.verifyProof(\\n [proof[0], proof[1]],\\n [[proof[2], proof[3]], [proof[4], proof[5]]],\\n [proof[6], proof[7]],\\n [idCommitment, uint256(uint160(receiver))]\\n );\\n }\\n}\\n\",\"keccak256\":\"0xaba729711978a308143b0e44a95f0925ff4fac1f65864ff6b9895f000fc851ee\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x61012060405260016000553480156200001757600080fd5b50604051620013dc380380620013dc83398181016040528101906200003d919062000171565b83608081815250508260a08181525050826001901b60c081815250508173ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff166101008173ffffffffffffffffffffffffffffffffffffffff168152505050505050620001e3565b600080fd5b6000819050919050565b620000e681620000d1565b8114620000f257600080fd5b50565b6000815190506200010681620000db565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000139826200010c565b9050919050565b6200014b816200012c565b81146200015757600080fd5b50565b6000815190506200016b8162000140565b92915050565b600080600080608085870312156200018e576200018d620000cc565b5b60006200019e87828801620000f5565b9450506020620001b187828801620000f5565b9350506040620001c4878288016200015a565b9250506060620001d7878288016200015a565b91505092959194509250565b60805160a05160c05160e0516101005161119862000244600039600081816102c30152610973015260006102e70152600081816104d4015261088c0152600061047a0152600081816104f80152818161051f015261058b01526111986000f3fe6080604052600436106100a75760003560e01c8063ae74552a11610064578063ae74552a146101aa578063bc499128146101d5578063c5b208ff14610212578063d0383d681461024f578063f207564e1461027a578063f220b9ec14610296576100a7565b80632b7ac3f3146100ac578063331b6ab3146100d75780633ccfd60b146101025780635daf08ca146101195780638be9b1191461015657806398366e351461017f575b600080fd5b3480156100b857600080fd5b506100c16102c1565b6040516100ce9190610be7565b60405180910390f35b3480156100e357600080fd5b506100ec6102e5565b6040516100f99190610c23565b60405180910390f35b34801561010e57600080fd5b50610117610309565b005b34801561012557600080fd5b50610140600480360381019061013b9190610c79565b610450565b60405161014d9190610cb5565b60405180910390f35b34801561016257600080fd5b5061017d60048036038101906101789190610d35565b610468565b005b34801561018b57600080fd5b50610194610478565b6040516101a19190610cb5565b60405180910390f35b3480156101b657600080fd5b506101bf61049c565b6040516101cc9190610cb5565b60405180910390f35b3480156101e157600080fd5b506101fc60048036038101906101f79190610c79565b6104a2565b6040516102099190610cb5565b60405180910390f35b34801561021e57600080fd5b5061023960048036038101906102349190610dc7565b6104ba565b6040516102469190610cb5565b60405180910390f35b34801561025b57600080fd5b506102646104d2565b6040516102719190610cb5565b60405180910390f35b610294600480360381019061028f9190610c79565b6104f6565b005b3480156102a257600080fd5b506102ab610589565b6040516102b89190610cb5565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103610387576040517f6f50367a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b478111156103c1576040517f786e0a9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561044c573d6000803e3d6000fd5b5050565b60026020528060005260406000206000915090505481565b6104738383836105ad565b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60005481565b60016020528060005260406000206000915090505481565b60036020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f0000000000000000000000000000000000000000000000000000000000000000341461057c577f0000000000000000000000000000000000000000000000000000000000000000346040517f25c3f46e000000000000000000000000000000000000000000000000000000008152600401610573929190610df4565b60405180910390fd5b610586813461083e565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614806106135750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b1561065557816040517f4a149d0800000000000000000000000000000000000000000000000000000000815260040161064c9190610e3e565b60405180910390fd5b60006002600085815260200190815260200160002054036106ad57826040517f5a971ebb0000000000000000000000000000000000000000000000000000000081526004016106a49190610cb5565b60405180910390fd5b600060016000858152602001908152602001600020540361070557826040517faabeeba50000000000000000000000000000000000000000000000000000000081526004016106fc9190610cb5565b60405180910390fd5b61071083838361096f565b610746576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060016000858152602001908152602001600020549050600060026000868152602001908152602001600020549050600060026000878152602001908152602001600020819055506000600160008781526020019081526020016000208190555081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546107f79190610e88565b925050819055507f62ec3a516d22a993ce5cb4e7593e878c74f4d799dde522a88dc27a994fd5a943858260405161082f929190610df4565b60405180910390a15050505050565b600060026000848152602001908152602001600020541461088a576040517e0a60f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000600054106108e5576040517f57f6953100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005460026000848152602001908152602001600020819055508060016000848152602001908152602001600020819055507f5a92c2530f207992057b9c3e544108ffce3beda4a63719f316967c49bf6159d28260005460405161094a929190610df4565b60405180910390a160016000808282546109649190610e88565b925050819055505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f5c9d69e6040518060400160405280856000600881106109cc576109cb610ede565b5b60200201358152602001856001600881106109ea576109e9610ede565b5b60200201358152506040518060400160405280604051806040016040528088600260088110610a1c57610a1b610ede565b5b6020020135815260200188600360088110610a3a57610a39610ede565b5b60200201358152508152602001604051806040016040528088600460088110610a6657610a65610ede565b5b6020020135815260200188600560088110610a8457610a83610ede565b5b6020020135815250815250604051806040016040528087600660088110610aae57610aad610ede565b5b6020020135815260200187600760088110610acc57610acb610ede565b5b602002013581525060405180604001604052808a81526020018973ffffffffffffffffffffffffffffffffffffffff168152506040518563ffffffff1660e01b8152600401610b1e94939291906110b6565b602060405180830381865afa158015610b3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5f9190611135565b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000610bad610ba8610ba384610b68565b610b88565b610b68565b9050919050565b6000610bbf82610b92565b9050919050565b6000610bd182610bb4565b9050919050565b610be181610bc6565b82525050565b6000602082019050610bfc6000830184610bd8565b92915050565b6000610c0d82610bb4565b9050919050565b610c1d81610c02565b82525050565b6000602082019050610c386000830184610c14565b92915050565b600080fd5b6000819050919050565b610c5681610c43565b8114610c6157600080fd5b50565b600081359050610c7381610c4d565b92915050565b600060208284031215610c8f57610c8e610c3e565b5b6000610c9d84828501610c64565b91505092915050565b610caf81610c43565b82525050565b6000602082019050610cca6000830184610ca6565b92915050565b6000610cdb82610b68565b9050919050565b610ceb81610cd0565b8114610cf657600080fd5b50565b600081359050610d0881610ce2565b92915050565b600080fd5b600081905082602060080282011115610d2f57610d2e610d0e565b5b92915050565b60008060006101408486031215610d4f57610d4e610c3e565b5b6000610d5d86828701610c64565b9350506020610d6e86828701610cf9565b9250506040610d7f86828701610d13565b9150509250925092565b6000610d9482610b68565b9050919050565b610da481610d89565b8114610daf57600080fd5b50565b600081359050610dc181610d9b565b92915050565b600060208284031215610ddd57610ddc610c3e565b5b6000610deb84828501610db2565b91505092915050565b6000604082019050610e096000830185610ca6565b610e166020830184610ca6565b9392505050565b6000610e2882610bb4565b9050919050565b610e3881610e1d565b82525050565b6000602082019050610e536000830184610e2f565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610e9382610c43565b9150610e9e83610c43565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610ed357610ed2610e59565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060029050919050565b600081905092915050565b6000819050919050565b610f3681610c43565b82525050565b6000610f488383610f2d565b60208301905092915050565b6000602082019050919050565b610f6a81610f0d565b610f748184610f18565b9250610f7f82610f23565b8060005b83811015610fb0578151610f978782610f3c565b9650610fa283610f54565b925050600181019050610f83565b505050505050565b600060029050919050565b600081905092915050565b6000819050919050565b600081905092915050565b610fec81610f0d565b610ff68184610fd8565b925061100182610f23565b8060005b838110156110325781516110198782610f3c565b965061102483610f54565b925050600181019050611005565b505050505050565b60006110468383610fe3565b60408301905092915050565b6000602082019050919050565b61106881610fb8565b6110728184610fc3565b925061107d82610fce565b8060005b838110156110ae578151611095878261103a565b96506110a083611052565b925050600181019050611081565b505050505050565b6000610140820190506110cc6000830187610f61565b6110d9604083018661105f565b6110e660c0830185610f61565b6110f4610100830184610f61565b95945050505050565b60008115159050919050565b611112816110fd565b811461111d57600080fd5b50565b60008151905061112f81611109565b92915050565b60006020828403121561114b5761114a610c3e565b5b600061115984828501611120565b9150509291505056fea26469706673582212208074065fef168f5f0c27b80d2553070a161db1c01092b76699947b2e28c96b5064736f6c634300080f0033", - "deployedBytecode": "0x6080604052600436106100a75760003560e01c8063ae74552a11610064578063ae74552a146101aa578063bc499128146101d5578063c5b208ff14610212578063d0383d681461024f578063f207564e1461027a578063f220b9ec14610296576100a7565b80632b7ac3f3146100ac578063331b6ab3146100d75780633ccfd60b146101025780635daf08ca146101195780638be9b1191461015657806398366e351461017f575b600080fd5b3480156100b857600080fd5b506100c16102c1565b6040516100ce9190610be7565b60405180910390f35b3480156100e357600080fd5b506100ec6102e5565b6040516100f99190610c23565b60405180910390f35b34801561010e57600080fd5b50610117610309565b005b34801561012557600080fd5b50610140600480360381019061013b9190610c79565b610450565b60405161014d9190610cb5565b60405180910390f35b34801561016257600080fd5b5061017d60048036038101906101789190610d35565b610468565b005b34801561018b57600080fd5b50610194610478565b6040516101a19190610cb5565b60405180910390f35b3480156101b657600080fd5b506101bf61049c565b6040516101cc9190610cb5565b60405180910390f35b3480156101e157600080fd5b506101fc60048036038101906101f79190610c79565b6104a2565b6040516102099190610cb5565b60405180910390f35b34801561021e57600080fd5b5061023960048036038101906102349190610dc7565b6104ba565b6040516102469190610cb5565b60405180910390f35b34801561025b57600080fd5b506102646104d2565b6040516102719190610cb5565b60405180910390f35b610294600480360381019061028f9190610c79565b6104f6565b005b3480156102a257600080fd5b506102ab610589565b6040516102b89190610cb5565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103610387576040517f6f50367a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b478111156103c1576040517f786e0a9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561044c573d6000803e3d6000fd5b5050565b60026020528060005260406000206000915090505481565b6104738383836105ad565b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60005481565b60016020528060005260406000206000915090505481565b60036020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f0000000000000000000000000000000000000000000000000000000000000000341461057c577f0000000000000000000000000000000000000000000000000000000000000000346040517f25c3f46e000000000000000000000000000000000000000000000000000000008152600401610573929190610df4565b60405180910390fd5b610586813461083e565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614806106135750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b1561065557816040517f4a149d0800000000000000000000000000000000000000000000000000000000815260040161064c9190610e3e565b60405180910390fd5b60006002600085815260200190815260200160002054036106ad57826040517f5a971ebb0000000000000000000000000000000000000000000000000000000081526004016106a49190610cb5565b60405180910390fd5b600060016000858152602001908152602001600020540361070557826040517faabeeba50000000000000000000000000000000000000000000000000000000081526004016106fc9190610cb5565b60405180910390fd5b61071083838361096f565b610746576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060016000858152602001908152602001600020549050600060026000868152602001908152602001600020549050600060026000878152602001908152602001600020819055506000600160008781526020019081526020016000208190555081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546107f79190610e88565b925050819055507f62ec3a516d22a993ce5cb4e7593e878c74f4d799dde522a88dc27a994fd5a943858260405161082f929190610df4565b60405180910390a15050505050565b600060026000848152602001908152602001600020541461088a576040517e0a60f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000600054106108e5576040517f57f6953100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005460026000848152602001908152602001600020819055508060016000848152602001908152602001600020819055507f5a92c2530f207992057b9c3e544108ffce3beda4a63719f316967c49bf6159d28260005460405161094a929190610df4565b60405180910390a160016000808282546109649190610e88565b925050819055505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f5c9d69e6040518060400160405280856000600881106109cc576109cb610ede565b5b60200201358152602001856001600881106109ea576109e9610ede565b5b60200201358152506040518060400160405280604051806040016040528088600260088110610a1c57610a1b610ede565b5b6020020135815260200188600360088110610a3a57610a39610ede565b5b60200201358152508152602001604051806040016040528088600460088110610a6657610a65610ede565b5b6020020135815260200188600560088110610a8457610a83610ede565b5b6020020135815250815250604051806040016040528087600660088110610aae57610aad610ede565b5b6020020135815260200187600760088110610acc57610acb610ede565b5b602002013581525060405180604001604052808a81526020018973ffffffffffffffffffffffffffffffffffffffff168152506040518563ffffffff1660e01b8152600401610b1e94939291906110b6565b602060405180830381865afa158015610b3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5f9190611135565b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000610bad610ba8610ba384610b68565b610b88565b610b68565b9050919050565b6000610bbf82610b92565b9050919050565b6000610bd182610bb4565b9050919050565b610be181610bc6565b82525050565b6000602082019050610bfc6000830184610bd8565b92915050565b6000610c0d82610bb4565b9050919050565b610c1d81610c02565b82525050565b6000602082019050610c386000830184610c14565b92915050565b600080fd5b6000819050919050565b610c5681610c43565b8114610c6157600080fd5b50565b600081359050610c7381610c4d565b92915050565b600060208284031215610c8f57610c8e610c3e565b5b6000610c9d84828501610c64565b91505092915050565b610caf81610c43565b82525050565b6000602082019050610cca6000830184610ca6565b92915050565b6000610cdb82610b68565b9050919050565b610ceb81610cd0565b8114610cf657600080fd5b50565b600081359050610d0881610ce2565b92915050565b600080fd5b600081905082602060080282011115610d2f57610d2e610d0e565b5b92915050565b60008060006101408486031215610d4f57610d4e610c3e565b5b6000610d5d86828701610c64565b9350506020610d6e86828701610cf9565b9250506040610d7f86828701610d13565b9150509250925092565b6000610d9482610b68565b9050919050565b610da481610d89565b8114610daf57600080fd5b50565b600081359050610dc181610d9b565b92915050565b600060208284031215610ddd57610ddc610c3e565b5b6000610deb84828501610db2565b91505092915050565b6000604082019050610e096000830185610ca6565b610e166020830184610ca6565b9392505050565b6000610e2882610bb4565b9050919050565b610e3881610e1d565b82525050565b6000602082019050610e536000830184610e2f565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610e9382610c43565b9150610e9e83610c43565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610ed357610ed2610e59565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060029050919050565b600081905092915050565b6000819050919050565b610f3681610c43565b82525050565b6000610f488383610f2d565b60208301905092915050565b6000602082019050919050565b610f6a81610f0d565b610f748184610f18565b9250610f7f82610f23565b8060005b83811015610fb0578151610f978782610f3c565b9650610fa283610f54565b925050600181019050610f83565b505050505050565b600060029050919050565b600081905092915050565b6000819050919050565b600081905092915050565b610fec81610f0d565b610ff68184610fd8565b925061100182610f23565b8060005b838110156110325781516110198782610f3c565b965061102483610f54565b925050600181019050611005565b505050505050565b60006110468383610fe3565b60408301905092915050565b6000602082019050919050565b61106881610fb8565b6110728184610fc3565b925061107d82610fce565b8060005b838110156110ae578151611095878261103a565b96506110a083611052565b925050600181019050611081565b505050505050565b6000610140820190506110cc6000830187610f61565b6110d9604083018661105f565b6110e660c0830185610f61565b6110f4610100830184610f61565b95945050505050565b60008115159050919050565b611112816110fd565b811461111d57600080fd5b50565b60008151905061112f81611109565b92915050565b60006020828403121561114b5761114a610c3e565b5b600061115984828501611120565b9150509291505056fea26469706673582212208074065fef168f5f0c27b80d2553070a161db1c01092b76699947b2e28c96b5064736f6c634300080f0033", + "numDeployments": 1, + "solcInputHash": "3f87313134e2217cb187bd594084789f", + "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"membershipDeposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"depth\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_poseidonHasher\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_verifier\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"DuplicateIdCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FullTree\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientContractBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"provided\",\"type\":\"uint256\"}],\"name\":\"InsufficientDeposit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientWithdrawalBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"}],\"name\":\"InvalidIdCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"InvalidReceiverAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"}],\"name\":\"MemberHasNoStake\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"}],\"name\":\"MemberNotRegistered\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"MemberRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"MemberWithdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEPTH\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MEMBERSHIP_DEPOSIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SET_SIZE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"computeRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deployedBlockNumber\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"idCommitmentIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"imtData\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"depth\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"root\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"numberOfLeaves\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"useDefaultZeroes\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"}],\"name\":\"isValidCommitment\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"memberExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poseidonHasher\",\"outputs\":[{\"internalType\":\"contract PoseidonHasher\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"idCommitment\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256[8]\",\"name\":\"proof\",\"type\":\"uint256[8]\"}],\"name\":\"slash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"stakedAmounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verifier\",\"outputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"withdrawalBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"InsufficientDeposit(uint256,uint256)\":[{\"params\":{\"provided\":\"The provided deposit amount\",\"required\":\"The required deposit amount\"}}]},\"kind\":\"dev\",\"methods\":{\"register(uint256)\":{\"params\":{\"idCommitment\":\"The idCommitment of the member\"}},\"slash(uint256,address,uint256[8])\":{\"details\":\"Allows a user to slash a member\",\"params\":{\"idCommitment\":\"The idCommitment of the member\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"DuplicateIdCommitment()\":[{\"notice\":\"Member is already registered\"}],\"FullTree()\":[{\"notice\":\"The tree is full\"}],\"InsufficientContractBalance()\":[{\"notice\":\"Contract has insufficient balance to return\"}],\"InsufficientDeposit(uint256,uint256)\":[{\"notice\":\"Invalid deposit amount\"}],\"InsufficientWithdrawalBalance()\":[{\"notice\":\"User has insufficient balance to withdraw\"}],\"InvalidIdCommitment(uint256)\":[{\"notice\":\"Invalid idCommitment\"}],\"InvalidProof()\":[{\"notice\":\"Invalid proof\"}],\"InvalidReceiverAddress(address)\":[{\"notice\":\"Invalid receiver address, when the receiver is the contract itself or 0x0\"}],\"MemberHasNoStake(uint256)\":[{\"notice\":\"Member has no stake\"}],\"MemberNotRegistered(uint256)\":[{\"notice\":\"Member is not registered\"}]},\"events\":{\"MemberRegistered(uint256,uint256)\":{\"notice\":\"Emitted when a new member is added to the set\"},\"MemberWithdrawn(uint256,uint256)\":{\"notice\":\"Emitted when a member is removed from the set\"}},\"kind\":\"user\",\"methods\":{\"DEPTH()\":{\"notice\":\"The depth of the merkle tree\"},\"MEMBERSHIP_DEPOSIT()\":{\"notice\":\"The deposit amount required to register as a member\"},\"SET_SIZE()\":{\"notice\":\"The size of the merkle tree, i.e 2^depth\"},\"deployedBlockNumber()\":{\"notice\":\"the deployed block number\"},\"idCommitmentIndex()\":{\"notice\":\"The index of the next member to be registered\"},\"imtData()\":{\"notice\":\"the Incremental Merkle Tree\"},\"memberExists(uint256)\":{\"notice\":\"The membership status of each member\"},\"members(uint256)\":{\"notice\":\"The membership status of each member maps from idCommitment to their index in the set\"},\"poseidonHasher()\":{\"notice\":\"The Poseidon hasher contract\"},\"register(uint256)\":{\"notice\":\"Allows a user to register as a member\"},\"stakedAmounts(uint256)\":{\"notice\":\"The amount of eth staked by each member maps from idCommitment to the amount staked\"},\"verifier()\":{\"notice\":\"The groth16 verifier contract\"},\"withdraw()\":{\"notice\":\"Allows a user to withdraw funds allocated to them upon slashing a member\"},\"withdrawalBalance(address)\":{\"notice\":\"The balance of each user that can be withdrawn\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Rln.sol\":\"RLN\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\"]},\"sources\":{\"@zk-kit/imt.sol/BinaryIMT.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport {PoseidonT3} from \\\"poseidon-solidity/PoseidonT3.sol\\\";\\n\\n// Each incremental tree has certain properties and data that will\\n// be used to add new leaves.\\nstruct BinaryIMTData {\\n uint256 depth; // Depth of the tree (levels - 1).\\n uint256 root; // Root hash of the tree.\\n uint256 numberOfLeaves; // Number of leaves of the tree.\\n mapping(uint256 => uint256) zeroes; // Zero hashes used for empty nodes (level -> zero hash).\\n // The nodes of the subtrees used in the last addition of a leaf (level -> [left node, right node]).\\n mapping(uint256 => uint256[2]) lastSubtrees; // Caching these values is essential to efficient appends.\\n bool useDefaultZeroes;\\n}\\n\\n/// @title Incremental binary Merkle tree.\\n/// @dev The incremental tree allows to calculate the root hash each time a leaf is added, ensuring\\n/// the integrity of the tree.\\nlibrary BinaryIMT {\\n uint8 public constant MAX_DEPTH = 32;\\n uint256 public constant SNARK_SCALAR_FIELD =\\n 21888242871839275222246405745257275088548364400416034343698204186575808495617;\\n\\n uint256 public constant Z_0 = 0;\\n uint256 public constant Z_1 = 14744269619966411208579211824598458697587494354926760081771325075741142829156;\\n uint256 public constant Z_2 = 7423237065226347324353380772367382631490014989348495481811164164159255474657;\\n uint256 public constant Z_3 = 11286972368698509976183087595462810875513684078608517520839298933882497716792;\\n uint256 public constant Z_4 = 3607627140608796879659380071776844901612302623152076817094415224584923813162;\\n uint256 public constant Z_5 = 19712377064642672829441595136074946683621277828620209496774504837737984048981;\\n uint256 public constant Z_6 = 20775607673010627194014556968476266066927294572720319469184847051418138353016;\\n uint256 public constant Z_7 = 3396914609616007258851405644437304192397291162432396347162513310381425243293;\\n uint256 public constant Z_8 = 21551820661461729022865262380882070649935529853313286572328683688269863701601;\\n uint256 public constant Z_9 = 6573136701248752079028194407151022595060682063033565181951145966236778420039;\\n uint256 public constant Z_10 = 12413880268183407374852357075976609371175688755676981206018884971008854919922;\\n uint256 public constant Z_11 = 14271763308400718165336499097156975241954733520325982997864342600795471836726;\\n uint256 public constant Z_12 = 20066985985293572387227381049700832219069292839614107140851619262827735677018;\\n uint256 public constant Z_13 = 9394776414966240069580838672673694685292165040808226440647796406499139370960;\\n uint256 public constant Z_14 = 11331146992410411304059858900317123658895005918277453009197229807340014528524;\\n uint256 public constant Z_15 = 15819538789928229930262697811477882737253464456578333862691129291651619515538;\\n uint256 public constant Z_16 = 19217088683336594659449020493828377907203207941212636669271704950158751593251;\\n uint256 public constant Z_17 = 21035245323335827719745544373081896983162834604456827698288649288827293579666;\\n uint256 public constant Z_18 = 6939770416153240137322503476966641397417391950902474480970945462551409848591;\\n uint256 public constant Z_19 = 10941962436777715901943463195175331263348098796018438960955633645115732864202;\\n uint256 public constant Z_20 = 15019797232609675441998260052101280400536945603062888308240081994073687793470;\\n uint256 public constant Z_21 = 11702828337982203149177882813338547876343922920234831094975924378932809409969;\\n uint256 public constant Z_22 = 11217067736778784455593535811108456786943573747466706329920902520905755780395;\\n uint256 public constant Z_23 = 16072238744996205792852194127671441602062027943016727953216607508365787157389;\\n uint256 public constant Z_24 = 17681057402012993898104192736393849603097507831571622013521167331642182653248;\\n uint256 public constant Z_25 = 21694045479371014653083846597424257852691458318143380497809004364947786214945;\\n uint256 public constant Z_26 = 8163447297445169709687354538480474434591144168767135863541048304198280615192;\\n uint256 public constant Z_27 = 14081762237856300239452543304351251708585712948734528663957353575674639038357;\\n uint256 public constant Z_28 = 16619959921569409661790279042024627172199214148318086837362003702249041851090;\\n uint256 public constant Z_29 = 7022159125197495734384997711896547675021391130223237843255817587255104160365;\\n uint256 public constant Z_30 = 4114686047564160449611603615418567457008101555090703535405891656262658644463;\\n uint256 public constant Z_31 = 12549363297364877722388257367377629555213421373705596078299904496781819142130;\\n uint256 public constant Z_32 = 21443572485391568159800782191812935835534334817699172242223315142338162256601;\\n\\n function defaultZero(uint256 index) public pure returns (uint256) {\\n if (index == 0) return Z_0;\\n if (index == 1) return Z_1;\\n if (index == 2) return Z_2;\\n if (index == 3) return Z_3;\\n if (index == 4) return Z_4;\\n if (index == 5) return Z_5;\\n if (index == 6) return Z_6;\\n if (index == 7) return Z_7;\\n if (index == 8) return Z_8;\\n if (index == 9) return Z_9;\\n if (index == 10) return Z_10;\\n if (index == 11) return Z_11;\\n if (index == 12) return Z_12;\\n if (index == 13) return Z_13;\\n if (index == 14) return Z_14;\\n if (index == 15) return Z_15;\\n if (index == 16) return Z_16;\\n if (index == 17) return Z_17;\\n if (index == 18) return Z_18;\\n if (index == 19) return Z_19;\\n if (index == 20) return Z_20;\\n if (index == 21) return Z_21;\\n if (index == 22) return Z_22;\\n if (index == 23) return Z_23;\\n if (index == 24) return Z_24;\\n if (index == 25) return Z_25;\\n if (index == 26) return Z_26;\\n if (index == 27) return Z_27;\\n if (index == 28) return Z_28;\\n if (index == 29) return Z_29;\\n if (index == 30) return Z_30;\\n if (index == 31) return Z_31;\\n if (index == 32) return Z_32;\\n revert(\\\"IncrementalBinaryTree: defaultZero bad index\\\");\\n }\\n\\n /// @dev Initializes a tree.\\n /// @param self: Tree data.\\n /// @param depth: Depth of the tree.\\n /// @param zero: Zero value to be used.\\n function init(BinaryIMTData storage self, uint256 depth, uint256 zero) public {\\n require(zero < SNARK_SCALAR_FIELD, \\\"BinaryIMT: leaf must be < SNARK_SCALAR_FIELD\\\");\\n require(depth > 0 && depth <= MAX_DEPTH, \\\"BinaryIMT: tree depth must be between 1 and 32\\\");\\n\\n self.depth = depth;\\n\\n for (uint8 i = 0; i < depth; ) {\\n self.zeroes[i] = zero;\\n zero = PoseidonT3.hash([zero, zero]);\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n self.root = zero;\\n }\\n\\n function initWithDefaultZeroes(BinaryIMTData storage self, uint256 depth) public {\\n require(depth > 0 && depth <= MAX_DEPTH, \\\"BinaryIMT: tree depth must be between 1 and 32\\\");\\n\\n self.depth = depth;\\n self.useDefaultZeroes = true;\\n\\n self.root = defaultZero(depth);\\n }\\n\\n /// @dev Inserts a leaf in the tree.\\n /// @param self: Tree data.\\n /// @param leaf: Leaf to be inserted.\\n function insert(BinaryIMTData storage self, uint256 leaf) public returns (uint256) {\\n uint256 depth = self.depth;\\n\\n require(leaf < SNARK_SCALAR_FIELD, \\\"BinaryIMT: leaf must be < SNARK_SCALAR_FIELD\\\");\\n require(self.numberOfLeaves < 2 ** depth, \\\"BinaryIMT: tree is full\\\");\\n\\n uint256 index = self.numberOfLeaves;\\n uint256 hash = leaf;\\n bool useDefaultZeroes = self.useDefaultZeroes;\\n\\n for (uint8 i = 0; i < depth; ) {\\n if (index & 1 == 0) {\\n self.lastSubtrees[i] = [hash, useDefaultZeroes ? defaultZero(i) : self.zeroes[i]];\\n } else {\\n self.lastSubtrees[i][1] = hash;\\n }\\n\\n hash = PoseidonT3.hash(self.lastSubtrees[i]);\\n index >>= 1;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n self.root = hash;\\n self.numberOfLeaves += 1;\\n return hash;\\n }\\n\\n /// @dev Updates a leaf in the tree.\\n /// @param self: Tree data.\\n /// @param leaf: Leaf to be updated.\\n /// @param newLeaf: New leaf.\\n /// @param proofSiblings: Array of the sibling nodes of the proof of membership.\\n /// @param proofPathIndices: Path of the proof of membership.\\n function update(\\n BinaryIMTData storage self,\\n uint256 leaf,\\n uint256 newLeaf,\\n uint256[] calldata proofSiblings,\\n uint8[] calldata proofPathIndices\\n ) public {\\n require(newLeaf != leaf, \\\"BinaryIMT: new leaf cannot be the same as the old one\\\");\\n require(newLeaf < SNARK_SCALAR_FIELD, \\\"BinaryIMT: new leaf must be < SNARK_SCALAR_FIELD\\\");\\n require(verify(self, leaf, proofSiblings, proofPathIndices), \\\"BinaryIMT: leaf is not part of the tree\\\");\\n\\n uint256 depth = self.depth;\\n uint256 hash = newLeaf;\\n uint256 updateIndex;\\n\\n for (uint8 i = 0; i < depth; ) {\\n updateIndex |= uint256(proofPathIndices[i]) << uint256(i);\\n\\n if (proofPathIndices[i] == 0) {\\n if (proofSiblings[i] == self.lastSubtrees[i][1]) {\\n self.lastSubtrees[i][0] = hash;\\n }\\n\\n hash = PoseidonT3.hash([hash, proofSiblings[i]]);\\n } else {\\n if (proofSiblings[i] == self.lastSubtrees[i][0]) {\\n self.lastSubtrees[i][1] = hash;\\n }\\n\\n hash = PoseidonT3.hash([proofSiblings[i], hash]);\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n require(updateIndex < self.numberOfLeaves, \\\"BinaryIMT: leaf index out of range\\\");\\n\\n self.root = hash;\\n }\\n\\n /// @dev Removes a leaf from the tree.\\n /// @param self: Tree data.\\n /// @param leaf: Leaf to be removed.\\n /// @param proofSiblings: Array of the sibling nodes of the proof of membership.\\n /// @param proofPathIndices: Path of the proof of membership.\\n function remove(\\n BinaryIMTData storage self,\\n uint256 leaf,\\n uint256[] calldata proofSiblings,\\n uint8[] calldata proofPathIndices\\n ) public {\\n update(self, leaf, self.useDefaultZeroes ? Z_0 : self.zeroes[0], proofSiblings, proofPathIndices);\\n }\\n\\n /// @dev Verify if the path is correct and the leaf is part of the tree.\\n /// @param self: Tree data.\\n /// @param leaf: Leaf to be removed.\\n /// @param proofSiblings: Array of the sibling nodes of the proof of membership.\\n /// @param proofPathIndices: Path of the proof of membership.\\n /// @return True or false.\\n function verify(\\n BinaryIMTData storage self,\\n uint256 leaf,\\n uint256[] calldata proofSiblings,\\n uint8[] calldata proofPathIndices\\n ) private view returns (bool) {\\n require(leaf < SNARK_SCALAR_FIELD, \\\"BinaryIMT: leaf must be < SNARK_SCALAR_FIELD\\\");\\n uint256 depth = self.depth;\\n require(\\n proofPathIndices.length == depth && proofSiblings.length == depth,\\n \\\"BinaryIMT: length of path is not correct\\\"\\n );\\n\\n uint256 hash = leaf;\\n\\n for (uint8 i = 0; i < depth; ) {\\n require(proofSiblings[i] < SNARK_SCALAR_FIELD, \\\"BinaryIMT: sibling node must be < SNARK_SCALAR_FIELD\\\");\\n\\n require(proofPathIndices[i] == 1 || proofPathIndices[i] == 0, \\\"BinaryIMT: path index is neither 0 nor 1\\\");\\n\\n if (proofPathIndices[i] == 0) {\\n hash = PoseidonT3.hash([hash, proofSiblings[i]]);\\n } else {\\n hash = PoseidonT3.hash([proofSiblings[i], hash]);\\n }\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return hash == self.root;\\n }\\n}\\n\",\"keccak256\":\"0xdc7e7cc2e8176bb76bbd788ae2d50a4e9db13d3256d8b07a695856e073a78586\",\"license\":\"MIT\"},\"contracts/IVerifier.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0 OR MIT\\npragma solidity 0.8.15;\\n\\ninterface IVerifier {\\n function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)\\n external\\n view\\n returns (bool);\\n}\\n\",\"keccak256\":\"0x538e61fbb62bf1ef9f0c3f7e7d771ddfc8506a97e7d98aada763830fc741d8b8\",\"license\":\"Apache-2.0 OR MIT\"},\"contracts/PoseidonHasher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.15;\\n\\nimport {PoseidonT3} from \\\"poseidon-solidity/PoseidonT3.sol\\\";\\n\\ninterface IPoseidonHasher {\\n /// @notice Hashes the input using the Poseidon hash function, n = 2\\n /// @param inputs The input to hash\\n function hash(uint256[2] memory inputs) external pure returns (uint256 result);\\n}\\n\\ncontract PoseidonHasher is IPoseidonHasher {\\n uint256 public constant Q = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\\n\\n function hash(uint256[2] memory inputs) external pure override returns (uint256 result) {\\n return PoseidonT3.hash(inputs);\\n }\\n}\\n\",\"keccak256\":\"0xdc41072af08ab2875f030e6ccc5781a7d5906aeaccc44535bb076e09146e86f9\",\"license\":\"MIT\"},\"contracts/Rln.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\nimport \\\"./RlnBase.sol\\\";\\n\\ncontract RLN is RlnBase {\\n constructor(uint256 membershipDeposit, uint256 depth, address _poseidonHasher, address _verifier)\\n RlnBase(membershipDeposit, depth, _poseidonHasher, _verifier)\\n {}\\n\\n function _validateRegistration(uint256 idCommitment) internal pure override {}\\n\\n function _validateSlash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)\\n internal\\n pure\\n override\\n {}\\n}\\n\",\"keccak256\":\"0x32563f17d27b3468d141b47935cc7efaad748e44cb7605c9df0e9f4da62f4167\",\"license\":\"MIT\"},\"contracts/RlnBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.15;\\n\\nimport {PoseidonHasher} from \\\"./PoseidonHasher.sol\\\";\\nimport {IVerifier} from \\\"./IVerifier.sol\\\";\\nimport {BinaryIMT, BinaryIMTData} from \\\"@zk-kit/imt.sol/BinaryIMT.sol\\\";\\n\\n/// The tree is full\\nerror FullTree();\\n\\n/// Invalid deposit amount\\n/// @param required The required deposit amount\\n/// @param provided The provided deposit amount\\nerror InsufficientDeposit(uint256 required, uint256 provided);\\n\\n/// Member is already registered\\nerror DuplicateIdCommitment();\\n\\n/// Failed validation on registration/slashing\\nerror FailedValidation();\\n\\n/// Invalid idCommitment\\nerror InvalidIdCommitment(uint256 idCommitment);\\n\\n/// Invalid receiver address, when the receiver is the contract itself or 0x0\\nerror InvalidReceiverAddress(address to);\\n\\n/// Member is not registered\\nerror MemberNotRegistered(uint256 idCommitment);\\n\\n/// Member has no stake\\nerror MemberHasNoStake(uint256 idCommitment);\\n\\n/// User has insufficient balance to withdraw\\nerror InsufficientWithdrawalBalance();\\n\\n/// Contract has insufficient balance to return\\nerror InsufficientContractBalance();\\n\\n/// Invalid proof\\nerror InvalidProof();\\n\\nabstract contract RlnBase {\\n /// @notice The deposit amount required to register as a member\\n uint256 public immutable MEMBERSHIP_DEPOSIT;\\n\\n /// @notice The depth of the merkle tree\\n uint256 public immutable DEPTH;\\n\\n /// @notice The size of the merkle tree, i.e 2^depth\\n uint256 public immutable SET_SIZE;\\n\\n /// @notice The index of the next member to be registered\\n uint256 public idCommitmentIndex = 0;\\n\\n /// @notice The amount of eth staked by each member\\n /// maps from idCommitment to the amount staked\\n mapping(uint256 => uint256) public stakedAmounts;\\n\\n /// @notice The membership status of each member\\n /// maps from idCommitment to their index in the set\\n mapping(uint256 => uint256) public members;\\n\\n /// @notice The membership status of each member\\n mapping(uint256 => bool) public memberExists;\\n\\n /// @notice The balance of each user that can be withdrawn\\n mapping(address => uint256) public withdrawalBalance;\\n\\n /// @notice The Poseidon hasher contract\\n PoseidonHasher public immutable poseidonHasher;\\n\\n /// @notice The groth16 verifier contract\\n IVerifier public immutable verifier;\\n\\n /// @notice the deployed block number\\n uint32 public immutable deployedBlockNumber;\\n\\n /// @notice the Incremental Merkle Tree\\n BinaryIMTData public imtData;\\n\\n /// Emitted when a new member is added to the set\\n /// @param idCommitment The idCommitment of the member\\n /// @param index The index of the member in the set\\n event MemberRegistered(uint256 idCommitment, uint256 index);\\n\\n /// Emitted when a member is removed from the set\\n /// @param idCommitment The idCommitment of the member\\n /// @param index The index of the member in the set\\n event MemberWithdrawn(uint256 idCommitment, uint256 index);\\n\\n modifier onlyValidIdCommitment(uint256 idCommitment) {\\n if (!isValidCommitment(idCommitment)) revert InvalidIdCommitment(idCommitment);\\n _;\\n }\\n\\n constructor(uint256 membershipDeposit, uint256 depth, address _poseidonHasher, address _verifier) {\\n MEMBERSHIP_DEPOSIT = membershipDeposit;\\n DEPTH = depth;\\n SET_SIZE = 1 << depth;\\n poseidonHasher = PoseidonHasher(_poseidonHasher);\\n verifier = IVerifier(_verifier);\\n deployedBlockNumber = uint32(block.number);\\n BinaryIMT.initWithDefaultZeroes(imtData, 20);\\n }\\n\\n /// Allows a user to register as a member\\n /// @param idCommitment The idCommitment of the member\\n function register(uint256 idCommitment) external payable virtual onlyValidIdCommitment(idCommitment) {\\n if (msg.value != MEMBERSHIP_DEPOSIT) {\\n revert InsufficientDeposit(MEMBERSHIP_DEPOSIT, msg.value);\\n }\\n _validateRegistration(idCommitment);\\n _register(idCommitment, msg.value);\\n }\\n\\n /// Registers a member\\n /// @param idCommitment The idCommitment of the member\\n /// @param stake The amount of eth staked by the member\\n function _register(uint256 idCommitment, uint256 stake) internal virtual {\\n if (memberExists[idCommitment]) revert DuplicateIdCommitment();\\n if (idCommitmentIndex >= SET_SIZE) revert FullTree();\\n\\n members[idCommitment] = idCommitmentIndex;\\n memberExists[idCommitment] = true;\\n BinaryIMT.insert(imtData, idCommitment);\\n stakedAmounts[idCommitment] = stake;\\n\\n emit MemberRegistered(idCommitment, idCommitmentIndex);\\n idCommitmentIndex += 1;\\n }\\n\\n /// @dev Inheriting contracts MUST override this function\\n function _validateRegistration(uint256 idCommitment) internal view virtual;\\n\\n /// @dev Allows a user to slash a member\\n /// @param idCommitment The idCommitment of the member\\n function slash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)\\n external\\n virtual\\n onlyValidIdCommitment(idCommitment)\\n {\\n _validateSlash(idCommitment, receiver, proof);\\n _slash(idCommitment, receiver, proof);\\n }\\n\\n /// @dev Slashes a member by removing them from the set, and adding their\\n /// stake to the receiver's available withdrawal balance\\n /// @param idCommitment The idCommitment of the member\\n /// @param receiver The address to receive the funds\\n function _slash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof) internal virtual {\\n if (receiver == address(this) || receiver == address(0)) {\\n revert InvalidReceiverAddress(receiver);\\n }\\n\\n if (memberExists[idCommitment] == false) revert MemberNotRegistered(idCommitment);\\n // check if member is registered\\n if (stakedAmounts[idCommitment] == 0) {\\n revert MemberHasNoStake(idCommitment);\\n }\\n\\n if (!_verifyProof(idCommitment, receiver, proof)) {\\n revert InvalidProof();\\n }\\n\\n uint256 amountToTransfer = stakedAmounts[idCommitment];\\n\\n // delete member\\n uint256 index = members[idCommitment];\\n members[idCommitment] = 0;\\n memberExists[idCommitment] = false;\\n stakedAmounts[idCommitment] = 0;\\n // TODO: remove from IMT\\n\\n // refund deposit\\n withdrawalBalance[receiver] += amountToTransfer;\\n\\n emit MemberWithdrawn(idCommitment, index);\\n }\\n\\n function _validateSlash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)\\n internal\\n view\\n virtual;\\n\\n /// Allows a user to withdraw funds allocated to them upon slashing a member\\n function withdraw() external virtual {\\n uint256 amount = withdrawalBalance[msg.sender];\\n\\n if (amount == 0) revert InsufficientWithdrawalBalance();\\n if (amount > address(this).balance) {\\n revert InsufficientContractBalance();\\n }\\n\\n withdrawalBalance[msg.sender] = 0;\\n\\n payable(msg.sender).transfer(amount);\\n }\\n\\n /// Hashes a value using the Poseidon hasher\\n /// NOTE: The variant of Poseidon we use accepts only 1 input, assume n=2\\n /// @param inputs The values to hash\\n function hash(uint256[2] memory inputs) internal view returns (uint256) {\\n return poseidonHasher.hash(inputs);\\n }\\n\\n function isValidCommitment(uint256 idCommitment) public view returns (bool) {\\n return idCommitment != 0 && idCommitment < poseidonHasher.Q();\\n }\\n\\n /// @dev Groth16 proof verification\\n function _verifyProof(uint256 idCommitment, address receiver, uint256[8] calldata proof)\\n internal\\n view\\n virtual\\n returns (bool)\\n {\\n return verifier.verifyProof(\\n [proof[0], proof[1]],\\n [[proof[2], proof[3]], [proof[4], proof[5]]],\\n [proof[6], proof[7]],\\n [idCommitment, uint256(uint160(receiver))]\\n );\\n }\\n\\n function computeRoot() external view returns (uint256) {\\n return imtData.root;\\n }\\n}\\n\",\"keccak256\":\"0xe9068967bdc4e81b4ac05436fe967d60a62681a7c8df6798c847c1ab02b0aa1f\",\"license\":\"MIT\"},\"poseidon-solidity/PoseidonT3.sol\":{\"content\":\"/// SPDX-License-Identifier: MIT\\npragma solidity >=0.7.0;\\n\\nlibrary PoseidonT3 {\\n uint constant M00 = 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b;\\n uint constant M01 = 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771;\\n uint constant M02 = 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7;\\n uint constant M10 = 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0;\\n uint constant M11 = 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23;\\n uint constant M12 = 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911;\\n\\n // See here for a simplified implementation: https://github.com/vimwitch/poseidon-solidity/blob/e57becdabb65d99fdc586fe1e1e09e7108202d53/contracts/Poseidon.sol#L40\\n // Inspired by: https://github.com/iden3/circomlibjs/blob/v0.0.8/src/poseidon_slow.js\\n function hash(uint[2] memory) public pure returns (uint) {\\n assembly {\\n let F := 21888242871839275222246405745257275088548364400416034343698204186575808495617\\n let M20 := 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d\\n let M21 := 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa\\n let M22 := 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0\\n\\n // load the inputs from memory\\n let state1 := add(mod(mload(0x80), F), 0x00f1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864)\\n let state2 := add(mod(mload(0xa0), F), 0x08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5)\\n let scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n scratch0 := add(\\n 0x2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d0,\\n add(add(15452833169820924772166449970675545095234312153403844297388521437673434406763, mulmod(state1, M10, F)), mulmod(state2, M20, F))\\n )\\n let scratch1 := add(\\n 0x2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf2,\\n add(add(18674271267752038776579386132900109523609358935013267566297499497165104279117, mulmod(state1, M11, F)), mulmod(state2, M21, F))\\n )\\n let scratch2 := add(\\n 0x0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa,\\n add(add(14817777843080276494683266178512808687156649753153012854386334860566696099579, mulmod(state1, M12, F)), mulmod(state2, M22, F))\\n )\\n let state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc632, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n scratch0 := add(0x15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c8705, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd1, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x005032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c887, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da53, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0081c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb38, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c502, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x00ef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba89, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c5, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e4, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e13, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a90035, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db69, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b8, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c77, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x002e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x00b9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c3512, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x00248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a808, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f09, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e8284, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd800, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f178, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e504233, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d59, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f88948, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d142, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c0, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a58, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d01, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc792, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea6111, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa336, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d6, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f451, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf77, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc630, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := add(0x2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := add(0x054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c2320, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n scratch0 := add(0x0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\\n scratch1 := add(0x193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\\n scratch2 := add(0x102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f8, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\\n state0 := mulmod(scratch0, scratch0, F)\\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\\n state0 := mulmod(scratch1, scratch1, F)\\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\\n state0 := mulmod(scratch2, scratch2, F)\\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\\n state0 := add(0x0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\\n state1 := add(0x216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\\n state2 := add(0x1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e4228325161, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\\n scratch0 := mulmod(state0, state0, F)\\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\\n scratch0 := mulmod(state1, state1, F)\\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\\n scratch0 := mulmod(state2, state2, F)\\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\\n\\n mstore(0x0, mod(add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)), F))\\n\\n return(0, 0x20)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0102caa303bbc6690508f3615604f7730789ed990058c9513a87ccb30e4835be\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x610140604052600080553480156200001657600080fd5b5060405162001a3f38038062001a3f83398181016040528101906200003c9190620001fc565b8383838383608081815250508260a08181525050826001901b60c081815250508173ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff166101008173ffffffffffffffffffffffffffffffffffffffff16815250504363ffffffff166101208163ffffffff1681525050739Eae140A17Fd002B2ffA3B5df76C13100CDF909d6314d8c626600560146040518363ffffffff1660e01b815260040162000117929190620002c2565b60006040518083038186803b1580156200013057600080fd5b505af415801562000145573d6000803e3d6000fd5b505050505050505050505050620002ef565b600080fd5b6000819050919050565b62000171816200015c565b81146200017d57600080fd5b50565b600081519050620001918162000166565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001c48262000197565b9050919050565b620001d681620001b7565b8114620001e257600080fd5b50565b600081519050620001f681620001cb565b92915050565b6000806000806080858703121562000219576200021862000157565b5b6000620002298782880162000180565b94505060206200023c8782880162000180565b93505060406200024f87828801620001e5565b92505060606200026287828801620001e5565b91505092959194509250565b8082525050565b6000819050919050565b6000819050919050565b6000620002aa620002a46200029e8462000275565b6200027f565b6200015c565b9050919050565b620002bc8162000289565b82525050565b6000604082019050620002d960008301856200026e565b620002e86020830184620002b1565b9392505050565b60805160a05160c05160e05161010051610120516116dd6200036260003960006106850152600081816104cb0152610d8e01526000818161043201526104ef0152600081816107a20152610bff015260006107480152600081816108110152818161083801526108ae01526116dd6000f3fe6080604052600436106100fe5760003560e01c80636bdcc8ab11610095578063bc49912811610064578063bc4991281461032a578063c5b208ff14610367578063d0383d68146103a4578063f207564e146103cf578063f220b9ec146103eb576100fe565b80636bdcc8ab1461026e5780638be9b119146102ab57806398366e35146102d4578063ae74552a146102ff576100fe565b80633c979b5f116100d15780633c979b5f146101c15780633ccfd60b146101ef5780634add651e146102065780635daf08ca14610231576100fe565b806315068a5a1461010357806322d9730c1461012e5780632b7ac3f31461016b578063331b6ab314610196575b600080fd5b34801561010f57600080fd5b50610118610416565b6040516101259190610f9c565b60405180910390f35b34801561013a57600080fd5b5061015560048036038101906101509190610fe8565b610423565b6040516101629190611030565b60405180910390f35b34801561017757600080fd5b506101806104c9565b60405161018d91906110ca565b60405180910390f35b3480156101a257600080fd5b506101ab6104ed565b6040516101b89190611106565b60405180910390f35b3480156101cd57600080fd5b506101d6610511565b6040516101e69493929190611121565b60405180910390f35b3480156101fb57600080fd5b5061020461053c565b005b34801561021257600080fd5b5061021b610683565b6040516102289190611185565b60405180910390f35b34801561023d57600080fd5b5061025860048036038101906102539190610fe8565b6106a7565b6040516102659190610f9c565b60405180910390f35b34801561027a57600080fd5b5061029560048036038101906102909190610fe8565b6106bf565b6040516102a29190611030565b60405180910390f35b3480156102b757600080fd5b506102d260048036038101906102cd9190611205565b6106df565b005b3480156102e057600080fd5b506102e9610746565b6040516102f69190610f9c565b60405180910390f35b34801561030b57600080fd5b5061031461076a565b6040516103219190610f9c565b60405180910390f35b34801561033657600080fd5b50610351600480360381019061034c9190610fe8565b610770565b60405161035e9190610f9c565b60405180910390f35b34801561037357600080fd5b5061038e60048036038101906103899190611297565b610788565b60405161039b9190610f9c565b60405180910390f35b3480156103b057600080fd5b506103b96107a0565b6040516103c69190610f9c565b60405180910390f35b6103e960048036038101906103e49190610fe8565b6107c4565b005b3480156103f757600080fd5b506104006108ac565b60405161040d9190610f9c565b60405180910390f35b6000600560010154905090565b60008082141580156104c257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e493ef8c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561049b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bf91906112d9565b82105b9050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60058060000154908060010154908060020154908060050160009054906101000a900460ff16905084565b6000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600081036105ba576040517f6f50367a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b478111156105f4576040517f786e0a9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561067f573d6000803e3d6000fd5b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60026020528060005260406000206000915090505481565b60036020528060005260406000206000915054906101000a900460ff1681565b826106e981610423565b61072a57806040517f7f3e75af0000000000000000000000000000000000000000000000000000000081526004016107219190610f9c565b60405180910390fd5b6107358484846108d0565b6107408484846108d5565b50505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60005481565b60016020528060005260406000206000915090505481565b60046020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b806107ce81610423565b61080f57806040517f7f3e75af0000000000000000000000000000000000000000000000000000000081526004016108069190610f9c565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000003414610895577f0000000000000000000000000000000000000000000000000000000000000000346040517f25c3f46e00000000000000000000000000000000000000000000000000000000815260040161088c929190611306565b60405180910390fd5b61089e82610ba3565b6108a88234610ba6565b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b505050565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148061093b5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b1561097d57816040517f4a149d080000000000000000000000000000000000000000000000000000000081526004016109749190611350565b60405180910390fd5b600015156003600085815260200190815260200160002060009054906101000a900460ff161515036109e657826040517f5a971ebb0000000000000000000000000000000000000000000000000000000081526004016109dd9190610f9c565b60405180910390fd5b6000600160008581526020019081526020016000205403610a3e57826040517faabeeba5000000000000000000000000000000000000000000000000000000008152600401610a359190610f9c565b60405180910390fd5b610a49838383610d8a565b610a7f576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600160008581526020019081526020016000205490506000600260008681526020019081526020016000205490506000600260008781526020019081526020016000208190555060006003600087815260200190815260200160002060006101000a81548160ff0219169083151502179055506000600160008781526020019081526020016000208190555081600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610b5c919061139a565b925050819055507f62ec3a516d22a993ce5cb4e7593e878c74f4d799dde522a88dc27a994fd5a9438582604051610b94929190611306565b60405180910390a15050505050565b50565b6003600083815260200190815260200160002060009054906101000a900460ff1615610bfd576040517e0a60f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000060005410610c58576040517f57f6953100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054600260008481526020019081526020016000208190555060016003600084815260200190815260200160002060006101000a81548160ff021916908315150217905550739Eae140A17Fd002B2ffA3B5df76C13100CDF909d63143dc3836005846040518363ffffffff1660e01b8152600401610cd8929190611406565b602060405180830381865af4158015610cf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1991906112d9565b508060016000848152602001908152602001600020819055507f5a92c2530f207992057b9c3e544108ffce3beda4a63719f316967c49bf6159d282600054604051610d65929190611306565b60405180910390a16001600080828254610d7f919061139a565b925050819055505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f5c9d69e604051806040016040528085600060088110610de757610de661142f565b5b6020020135815260200185600160088110610e0557610e0461142f565b5b60200201358152506040518060400160405280604051806040016040528088600260088110610e3757610e3661142f565b5b6020020135815260200188600360088110610e5557610e5461142f565b5b60200201358152508152602001604051806040016040528088600460088110610e8157610e8061142f565b5b6020020135815260200188600560088110610e9f57610e9e61142f565b5b6020020135815250815250604051806040016040528087600660088110610ec957610ec861142f565b5b6020020135815260200187600760088110610ee757610ee661142f565b5b602002013581525060405180604001604052808a81526020018973ffffffffffffffffffffffffffffffffffffffff168152506040518563ffffffff1660e01b8152600401610f399493929190611607565b602060405180830381865afa158015610f56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7a919061167a565b90509392505050565b6000819050919050565b610f9681610f83565b82525050565b6000602082019050610fb16000830184610f8d565b92915050565b600080fd5b610fc581610f83565b8114610fd057600080fd5b50565b600081359050610fe281610fbc565b92915050565b600060208284031215610ffe57610ffd610fb7565b5b600061100c84828501610fd3565b91505092915050565b60008115159050919050565b61102a81611015565b82525050565b60006020820190506110456000830184611021565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061109061108b6110868461104b565b61106b565b61104b565b9050919050565b60006110a282611075565b9050919050565b60006110b482611097565b9050919050565b6110c4816110a9565b82525050565b60006020820190506110df60008301846110bb565b92915050565b60006110f082611097565b9050919050565b611100816110e5565b82525050565b600060208201905061111b60008301846110f7565b92915050565b60006080820190506111366000830187610f8d565b6111436020830186610f8d565b6111506040830185610f8d565b61115d6060830184611021565b95945050505050565b600063ffffffff82169050919050565b61117f81611166565b82525050565b600060208201905061119a6000830184611176565b92915050565b60006111ab8261104b565b9050919050565b6111bb816111a0565b81146111c657600080fd5b50565b6000813590506111d8816111b2565b92915050565b600080fd5b6000819050826020600802820111156111ff576111fe6111de565b5b92915050565b6000806000610140848603121561121f5761121e610fb7565b5b600061122d86828701610fd3565b935050602061123e868287016111c9565b925050604061124f868287016111e3565b9150509250925092565b60006112648261104b565b9050919050565b61127481611259565b811461127f57600080fd5b50565b6000813590506112918161126b565b92915050565b6000602082840312156112ad576112ac610fb7565b5b60006112bb84828501611282565b91505092915050565b6000815190506112d381610fbc565b92915050565b6000602082840312156112ef576112ee610fb7565b5b60006112fd848285016112c4565b91505092915050565b600060408201905061131b6000830185610f8d565b6113286020830184610f8d565b9392505050565b600061133a82611097565b9050919050565b61134a8161132f565b82525050565b60006020820190506113656000830184611341565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006113a582610f83565b91506113b083610f83565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156113e5576113e461136b565b5b828201905092915050565b8082525050565b61140081610f83565b82525050565b600060408201905061141b60008301856113f0565b61142860208301846113f7565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060029050919050565b600081905092915050565b6000819050919050565b61148781610f83565b82525050565b6000611499838361147e565b60208301905092915050565b6000602082019050919050565b6114bb8161145e565b6114c58184611469565b92506114d082611474565b8060005b838110156115015781516114e8878261148d565b96506114f3836114a5565b9250506001810190506114d4565b505050505050565b600060029050919050565b600081905092915050565b6000819050919050565b600081905092915050565b61153d8161145e565b6115478184611529565b925061155282611474565b8060005b8381101561158357815161156a878261148d565b9650611575836114a5565b925050600181019050611556565b505050505050565b60006115978383611534565b60408301905092915050565b6000602082019050919050565b6115b981611509565b6115c38184611514565b92506115ce8261151f565b8060005b838110156115ff5781516115e6878261158b565b96506115f1836115a3565b9250506001810190506115d2565b505050505050565b60006101408201905061161d60008301876114b2565b61162a60408301866115b0565b61163760c08301856114b2565b6116456101008301846114b2565b95945050505050565b61165781611015565b811461166257600080fd5b50565b6000815190506116748161164e565b92915050565b6000602082840312156116905761168f610fb7565b5b600061169e84828501611665565b9150509291505056fea26469706673582212202157fc09c0b2c118b7a22bafd75155e57be31040586feb6eb2ba8b28b1918a0764736f6c634300080f0033", + "deployedBytecode": "0x6080604052600436106100fe5760003560e01c80636bdcc8ab11610095578063bc49912811610064578063bc4991281461032a578063c5b208ff14610367578063d0383d68146103a4578063f207564e146103cf578063f220b9ec146103eb576100fe565b80636bdcc8ab1461026e5780638be9b119146102ab57806398366e35146102d4578063ae74552a146102ff576100fe565b80633c979b5f116100d15780633c979b5f146101c15780633ccfd60b146101ef5780634add651e146102065780635daf08ca14610231576100fe565b806315068a5a1461010357806322d9730c1461012e5780632b7ac3f31461016b578063331b6ab314610196575b600080fd5b34801561010f57600080fd5b50610118610416565b6040516101259190610f9c565b60405180910390f35b34801561013a57600080fd5b5061015560048036038101906101509190610fe8565b610423565b6040516101629190611030565b60405180910390f35b34801561017757600080fd5b506101806104c9565b60405161018d91906110ca565b60405180910390f35b3480156101a257600080fd5b506101ab6104ed565b6040516101b89190611106565b60405180910390f35b3480156101cd57600080fd5b506101d6610511565b6040516101e69493929190611121565b60405180910390f35b3480156101fb57600080fd5b5061020461053c565b005b34801561021257600080fd5b5061021b610683565b6040516102289190611185565b60405180910390f35b34801561023d57600080fd5b5061025860048036038101906102539190610fe8565b6106a7565b6040516102659190610f9c565b60405180910390f35b34801561027a57600080fd5b5061029560048036038101906102909190610fe8565b6106bf565b6040516102a29190611030565b60405180910390f35b3480156102b757600080fd5b506102d260048036038101906102cd9190611205565b6106df565b005b3480156102e057600080fd5b506102e9610746565b6040516102f69190610f9c565b60405180910390f35b34801561030b57600080fd5b5061031461076a565b6040516103219190610f9c565b60405180910390f35b34801561033657600080fd5b50610351600480360381019061034c9190610fe8565b610770565b60405161035e9190610f9c565b60405180910390f35b34801561037357600080fd5b5061038e60048036038101906103899190611297565b610788565b60405161039b9190610f9c565b60405180910390f35b3480156103b057600080fd5b506103b96107a0565b6040516103c69190610f9c565b60405180910390f35b6103e960048036038101906103e49190610fe8565b6107c4565b005b3480156103f757600080fd5b506104006108ac565b60405161040d9190610f9c565b60405180910390f35b6000600560010154905090565b60008082141580156104c257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e493ef8c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561049b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bf91906112d9565b82105b9050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60058060000154908060010154908060020154908060050160009054906101000a900460ff16905084565b6000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600081036105ba576040517f6f50367a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b478111156105f4576040517f786e0a9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561067f573d6000803e3d6000fd5b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60026020528060005260406000206000915090505481565b60036020528060005260406000206000915054906101000a900460ff1681565b826106e981610423565b61072a57806040517f7f3e75af0000000000000000000000000000000000000000000000000000000081526004016107219190610f9c565b60405180910390fd5b6107358484846108d0565b6107408484846108d5565b50505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60005481565b60016020528060005260406000206000915090505481565b60046020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b806107ce81610423565b61080f57806040517f7f3e75af0000000000000000000000000000000000000000000000000000000081526004016108069190610f9c565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000003414610895577f0000000000000000000000000000000000000000000000000000000000000000346040517f25c3f46e00000000000000000000000000000000000000000000000000000000815260040161088c929190611306565b60405180910390fd5b61089e82610ba3565b6108a88234610ba6565b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b505050565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148061093b5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b1561097d57816040517f4a149d080000000000000000000000000000000000000000000000000000000081526004016109749190611350565b60405180910390fd5b600015156003600085815260200190815260200160002060009054906101000a900460ff161515036109e657826040517f5a971ebb0000000000000000000000000000000000000000000000000000000081526004016109dd9190610f9c565b60405180910390fd5b6000600160008581526020019081526020016000205403610a3e57826040517faabeeba5000000000000000000000000000000000000000000000000000000008152600401610a359190610f9c565b60405180910390fd5b610a49838383610d8a565b610a7f576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600160008581526020019081526020016000205490506000600260008681526020019081526020016000205490506000600260008781526020019081526020016000208190555060006003600087815260200190815260200160002060006101000a81548160ff0219169083151502179055506000600160008781526020019081526020016000208190555081600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610b5c919061139a565b925050819055507f62ec3a516d22a993ce5cb4e7593e878c74f4d799dde522a88dc27a994fd5a9438582604051610b94929190611306565b60405180910390a15050505050565b50565b6003600083815260200190815260200160002060009054906101000a900460ff1615610bfd576040517e0a60f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000060005410610c58576040517f57f6953100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054600260008481526020019081526020016000208190555060016003600084815260200190815260200160002060006101000a81548160ff02191690831515021790555073__$156f483e97cedd2612cb663a75817771d9$__63143dc3836005846040518363ffffffff1660e01b8152600401610cd8929190611406565b602060405180830381865af4158015610cf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1991906112d9565b508060016000848152602001908152602001600020819055507f5a92c2530f207992057b9c3e544108ffce3beda4a63719f316967c49bf6159d282600054604051610d65929190611306565b60405180910390a16001600080828254610d7f919061139a565b925050819055505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f5c9d69e604051806040016040528085600060088110610de757610de661142f565b5b6020020135815260200185600160088110610e0557610e0461142f565b5b60200201358152506040518060400160405280604051806040016040528088600260088110610e3757610e3661142f565b5b6020020135815260200188600360088110610e5557610e5461142f565b5b60200201358152508152602001604051806040016040528088600460088110610e8157610e8061142f565b5b6020020135815260200188600560088110610e9f57610e9e61142f565b5b6020020135815250815250604051806040016040528087600660088110610ec957610ec861142f565b5b6020020135815260200187600760088110610ee757610ee661142f565b5b602002013581525060405180604001604052808a81526020018973ffffffffffffffffffffffffffffffffffffffff168152506040518563ffffffff1660e01b8152600401610f399493929190611607565b602060405180830381865afa158015610f56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7a919061167a565b90509392505050565b6000819050919050565b610f9681610f83565b82525050565b6000602082019050610fb16000830184610f8d565b92915050565b600080fd5b610fc581610f83565b8114610fd057600080fd5b50565b600081359050610fe281610fbc565b92915050565b600060208284031215610ffe57610ffd610fb7565b5b600061100c84828501610fd3565b91505092915050565b60008115159050919050565b61102a81611015565b82525050565b60006020820190506110456000830184611021565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061109061108b6110868461104b565b61106b565b61104b565b9050919050565b60006110a282611075565b9050919050565b60006110b482611097565b9050919050565b6110c4816110a9565b82525050565b60006020820190506110df60008301846110bb565b92915050565b60006110f082611097565b9050919050565b611100816110e5565b82525050565b600060208201905061111b60008301846110f7565b92915050565b60006080820190506111366000830187610f8d565b6111436020830186610f8d565b6111506040830185610f8d565b61115d6060830184611021565b95945050505050565b600063ffffffff82169050919050565b61117f81611166565b82525050565b600060208201905061119a6000830184611176565b92915050565b60006111ab8261104b565b9050919050565b6111bb816111a0565b81146111c657600080fd5b50565b6000813590506111d8816111b2565b92915050565b600080fd5b6000819050826020600802820111156111ff576111fe6111de565b5b92915050565b6000806000610140848603121561121f5761121e610fb7565b5b600061122d86828701610fd3565b935050602061123e868287016111c9565b925050604061124f868287016111e3565b9150509250925092565b60006112648261104b565b9050919050565b61127481611259565b811461127f57600080fd5b50565b6000813590506112918161126b565b92915050565b6000602082840312156112ad576112ac610fb7565b5b60006112bb84828501611282565b91505092915050565b6000815190506112d381610fbc565b92915050565b6000602082840312156112ef576112ee610fb7565b5b60006112fd848285016112c4565b91505092915050565b600060408201905061131b6000830185610f8d565b6113286020830184610f8d565b9392505050565b600061133a82611097565b9050919050565b61134a8161132f565b82525050565b60006020820190506113656000830184611341565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006113a582610f83565b91506113b083610f83565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156113e5576113e461136b565b5b828201905092915050565b8082525050565b61140081610f83565b82525050565b600060408201905061141b60008301856113f0565b61142860208301846113f7565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060029050919050565b600081905092915050565b6000819050919050565b61148781610f83565b82525050565b6000611499838361147e565b60208301905092915050565b6000602082019050919050565b6114bb8161145e565b6114c58184611469565b92506114d082611474565b8060005b838110156115015781516114e8878261148d565b96506114f3836114a5565b9250506001810190506114d4565b505050505050565b600060029050919050565b600081905092915050565b6000819050919050565b600081905092915050565b61153d8161145e565b6115478184611529565b925061155282611474565b8060005b8381101561158357815161156a878261148d565b9650611575836114a5565b925050600181019050611556565b505050505050565b60006115978383611534565b60408301905092915050565b6000602082019050919050565b6115b981611509565b6115c38184611514565b92506115ce8261151f565b8060005b838110156115ff5781516115e6878261158b565b96506115f1836115a3565b9250506001810190506115d2565b505050505050565b60006101408201905061161d60008301876114b2565b61162a60408301866115b0565b61163760c08301856114b2565b6116456101008301846114b2565b95945050505050565b61165781611015565b811461166257600080fd5b50565b6000815190506116748161164e565b92915050565b6000602082840312156116905761168f610fb7565b5b600061169e84828501611665565b9150509291505056fea26469706673582212202157fc09c0b2c118b7a22bafd75155e57be31040586feb6eb2ba8b28b1918a0764736f6c634300080f0033", + "libraries": { + "BinaryIMT": "0x9Eae140A17Fd002B2ffA3B5df76C13100CDF909d" + }, "devdoc": { "errors": { "InsufficientDeposit(uint256,uint256)": [ @@ -356,20 +462,6 @@ } ] }, - "events": { - "MemberRegistered(uint256,uint256)": { - "params": { - "idCommitment": "The idCommitment of the member", - "index": "The index of the member in the set" - } - }, - "MemberWithdrawn(uint256,uint256)": { - "params": { - "idCommitment": "The idCommitment of the member", - "index": "The index of the member in the set" - } - } - }, "kind": "dev", "methods": { "register(uint256)": { @@ -413,6 +505,11 @@ "notice": "User has insufficient balance to withdraw" } ], + "InvalidIdCommitment(uint256)": [ + { + "notice": "Invalid idCommitment" + } + ], "InvalidProof()": [ { "notice": "Invalid proof" @@ -453,9 +550,18 @@ "SET_SIZE()": { "notice": "The size of the merkle tree, i.e 2^depth" }, + "deployedBlockNumber()": { + "notice": "the deployed block number" + }, "idCommitmentIndex()": { "notice": "The index of the next member to be registered" }, + "imtData()": { + "notice": "the Incremental Merkle Tree" + }, + "memberExists(uint256)": { + "notice": "The membership status of each member" + }, "members(uint256)": { "notice": "The membership status of each member maps from idCommitment to their index in the set" }, @@ -483,7 +589,7 @@ "storageLayout": { "storage": [ { - "astId": 516, + "astId": 1069, "contract": "contracts/Rln.sol:RLN", "label": "idCommitmentIndex", "offset": 0, @@ -491,7 +597,7 @@ "type": "t_uint256" }, { - "astId": 521, + "astId": 1074, "contract": "contracts/Rln.sol:RLN", "label": "stakedAmounts", "offset": 0, @@ -499,7 +605,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 526, + "astId": 1079, "contract": "contracts/Rln.sol:RLN", "label": "members", "offset": 0, @@ -507,12 +613,28 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 531, + "astId": 1084, + "contract": "contracts/Rln.sol:RLN", + "label": "memberExists", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_bool)" + }, + { + "astId": 1089, "contract": "contracts/Rln.sol:RLN", "label": "withdrawalBalance", "offset": 0, - "slot": "3", + "slot": "4", "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 1104, + "contract": "contracts/Rln.sol:RLN", + "label": "imtData", + "offset": 0, + "slot": "5", + "type": "t_struct(BinaryIMTData)22_storage" } ], "types": { @@ -521,6 +643,17 @@ "label": "address", "numberOfBytes": "20" }, + "t_array(t_uint256)2_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[2]", + "numberOfBytes": "64" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", "key": "t_address", @@ -528,6 +661,20 @@ "numberOfBytes": "32", "value": "t_uint256" }, + "t_mapping(t_uint256,t_array(t_uint256)2_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => uint256[2])", + "numberOfBytes": "32", + "value": "t_array(t_uint256)2_storage" + }, + "t_mapping(t_uint256,t_bool)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, "t_mapping(t_uint256,t_uint256)": { "encoding": "mapping", "key": "t_uint256", @@ -535,6 +682,61 @@ "numberOfBytes": "32", "value": "t_uint256" }, + "t_struct(BinaryIMTData)22_storage": { + "encoding": "inplace", + "label": "struct BinaryIMTData", + "members": [ + { + "astId": 5, + "contract": "contracts/Rln.sol:RLN", + "label": "depth", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 7, + "contract": "contracts/Rln.sol:RLN", + "label": "root", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 9, + "contract": "contracts/Rln.sol:RLN", + "label": "numberOfLeaves", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 13, + "contract": "contracts/Rln.sol:RLN", + "label": "zeroes", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_uint256)" + }, + { + "astId": 19, + "contract": "contracts/Rln.sol:RLN", + "label": "lastSubtrees", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_uint256,t_array(t_uint256)2_storage)" + }, + { + "astId": 21, + "contract": "contracts/Rln.sol:RLN", + "label": "useDefaultZeroes", + "offset": 0, + "slot": "5", + "type": "t_bool" + } + ], + "numberOfBytes": "192" + }, "t_uint256": { "encoding": "inplace", "label": "uint256", diff --git a/deployments/sepolia/Verifier.json b/deployments/sepolia/Verifier.json index b5e4634..7053a8a 100644 --- a/deployments/sepolia/Verifier.json +++ b/deployments/sepolia/Verifier.json @@ -1,5 +1,5 @@ { - "address": "0xb81Faa6F0126dedB55A45eb63E8430B270A00303", + "address": "0xe36940B40aDe98F02a4829414F7e8d636CCf3663", "abi": [ { "inputs": [ @@ -36,28 +36,28 @@ "type": "function" } ], - "transactionHash": "0x2f4c4cfd0808f7127cee3725e398b3a486606b0fcffbf735730fcf9db7c30133", + "transactionHash": "0x280448aedc8db6088f35d7477aa682a387364950a80ddd609c3bebed8acae5aa", "receipt": { "to": null, "from": "0x3F47b2a1dF96DE2e198d646b598C37251CCC3b98", - "contractAddress": "0xb81Faa6F0126dedB55A45eb63E8430B270A00303", - "transactionIndex": 8, + "contractAddress": "0xe36940B40aDe98F02a4829414F7e8d636CCf3663", + "transactionIndex": 37, "gasUsed": "1117583", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x58d349c6c054e8a1a1621e57b1bb36a523787bea6f6131dd2b140742bb9b45c7", - "transactionHash": "0x2f4c4cfd0808f7127cee3725e398b3a486606b0fcffbf735730fcf9db7c30133", + "blockHash": "0x05a7ffe1dc0bdb3c1d727efcb03598feffa5220b5493e027eebe47f34b026170", + "transactionHash": "0x280448aedc8db6088f35d7477aa682a387364950a80ddd609c3bebed8acae5aa", "logs": [], - "blockNumber": 3594456, - "cumulativeGasUsed": "1500200", + "blockNumber": 4794983, + "cumulativeGasUsed": "8731883", "status": 1, "byzantium": true }, "args": [], "numDeployments": 1, - "solcInputHash": "96dd1aa02e55dc27e236e777882a31a7", - "metadata": "{\"compiler\":{\"version\":\"0.6.11+commit.5ef660b1\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"a\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2][2]\",\"name\":\"b\",\"type\":\"uint256[2][2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"c\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"input\",\"type\":\"uint256[2]\"}],\"name\":\"verifyProof\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"r\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"verifyProof(uint256[2],uint256[2][2],uint256[2],uint256[2])\":{\"returns\":{\"r\":\" bool true if proof is valid\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/RlnVerifier.sol\":\"Verifier\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\"]},\"sources\":{\"contracts/RlnVerifier.sol\":{\"content\":\"// File: https://github.com/Rate-Limiting-Nullifier/rln-contract-v1/blob/main/src/RLNVerifier.sol\\n// Copyright 2017 Christian Reitwiessner\\n// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \\\"Software\\\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\\n// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\\n//\\n// 2019 OKIMS\\n// ported to solidity 0.6\\n// fixed linter warnings\\n// added requiere error messages\\n//\\n//\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.6.11;\\n\\nlibrary Pairing {\\n struct G1Point {\\n uint256 X;\\n uint256 Y;\\n }\\n // Encoding of field elements is: X[0] * z + X[1]\\n\\n struct G2Point {\\n uint256[2] X;\\n uint256[2] Y;\\n }\\n /// @return the generator of G1\\n\\n function P1() internal pure returns (G1Point memory) {\\n return G1Point(1, 2);\\n }\\n /// @return the generator of G2\\n\\n function P2() internal pure returns (G2Point memory) {\\n // Original code point\\n return G2Point(\\n [\\n 11559732032986387107991004021392285783925812861821192530917403151452391805634,\\n 10857046999023057135944570762232829481370756359578518086990519993285655852781\\n ],\\n [\\n 4082367875863433681332203403145435568316851327593401208105741076214120093531,\\n 8495653923123431417604973247489272438418190587263600148770280649306958101930\\n ]\\n );\\n\\n /*\\n // Changed by Jordi point\\n return G2Point(\\n [10857046999023057135944570762232829481370756359578518086990519993285655852781,\\n 11559732032986387107991004021392285783925812861821192530917403151452391805634],\\n [8495653923123431417604973247489272438418190587263600148770280649306958101930,\\n 4082367875863433681332203403145435568316851327593401208105741076214120093531]\\n );*/\\n }\\n /// @return r the negation of p, i.e. p.addition(p.negate()) should be zero.\\n\\n function negate(G1Point memory p) internal pure returns (G1Point memory r) {\\n // The prime q in the base field F_q for G1\\n uint256 q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\\n if (p.X == 0 && p.Y == 0) {\\n return G1Point(0, 0);\\n }\\n return G1Point(p.X, q - (p.Y % q));\\n }\\n /// @return r the sum of two points of G1\\n\\n function addition(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) {\\n uint256[4] memory input;\\n input[0] = p1.X;\\n input[1] = p1.Y;\\n input[2] = p2.X;\\n input[3] = p2.Y;\\n bool success;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60)\\n // Use \\\"invalid\\\" to make gas estimation work\\n switch success\\n case 0 { invalid() }\\n }\\n require(success, \\\"pairing-add-failed\\\");\\n }\\n /// @return r the product of a point on G1 and a scalar, i.e.\\n /// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p.\\n\\n function scalar_mul(G1Point memory p, uint256 s) internal view returns (G1Point memory r) {\\n uint256[3] memory input;\\n input[0] = p.X;\\n input[1] = p.Y;\\n input[2] = s;\\n bool success;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60)\\n // Use \\\"invalid\\\" to make gas estimation work\\n switch success\\n case 0 { invalid() }\\n }\\n require(success, \\\"pairing-mul-failed\\\");\\n }\\n /// @return the result of computing the pairing check\\n /// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1\\n /// For example pairing([P1(), P1().negate()], [P2(), P2()]) should\\n /// return true.\\n\\n function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) {\\n require(p1.length == p2.length, \\\"pairing-lengths-failed\\\");\\n uint256 elements = p1.length;\\n uint256 inputSize = elements * 6;\\n uint256[] memory input = new uint[](inputSize);\\n for (uint256 i = 0; i < elements; i++) {\\n input[i * 6 + 0] = p1[i].X;\\n input[i * 6 + 1] = p1[i].Y;\\n input[i * 6 + 2] = p2[i].X[0];\\n input[i * 6 + 3] = p2[i].X[1];\\n input[i * 6 + 4] = p2[i].Y[0];\\n input[i * 6 + 5] = p2[i].Y[1];\\n }\\n uint256[1] memory out;\\n bool success;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)\\n // Use \\\"invalid\\\" to make gas estimation work\\n switch success\\n case 0 { invalid() }\\n }\\n require(success, \\\"pairing-opcode-failed\\\");\\n return out[0] != 0;\\n }\\n /// Convenience method for a pairing check for two pairs.\\n\\n function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2)\\n internal\\n view\\n returns (bool)\\n {\\n G1Point[] memory p1 = new G1Point[](2);\\n G2Point[] memory p2 = new G2Point[](2);\\n p1[0] = a1;\\n p1[1] = b1;\\n p2[0] = a2;\\n p2[1] = b2;\\n return pairing(p1, p2);\\n }\\n /// Convenience method for a pairing check for three pairs.\\n\\n function pairingProd3(\\n G1Point memory a1,\\n G2Point memory a2,\\n G1Point memory b1,\\n G2Point memory b2,\\n G1Point memory c1,\\n G2Point memory c2\\n ) internal view returns (bool) {\\n G1Point[] memory p1 = new G1Point[](3);\\n G2Point[] memory p2 = new G2Point[](3);\\n p1[0] = a1;\\n p1[1] = b1;\\n p1[2] = c1;\\n p2[0] = a2;\\n p2[1] = b2;\\n p2[2] = c2;\\n return pairing(p1, p2);\\n }\\n /// Convenience method for a pairing check for four pairs.\\n\\n function pairingProd4(\\n G1Point memory a1,\\n G2Point memory a2,\\n G1Point memory b1,\\n G2Point memory b2,\\n G1Point memory c1,\\n G2Point memory c2,\\n G1Point memory d1,\\n G2Point memory d2\\n ) internal view returns (bool) {\\n G1Point[] memory p1 = new G1Point[](4);\\n G2Point[] memory p2 = new G2Point[](4);\\n p1[0] = a1;\\n p1[1] = b1;\\n p1[2] = c1;\\n p1[3] = d1;\\n p2[0] = a2;\\n p2[1] = b2;\\n p2[2] = c2;\\n p2[3] = d2;\\n return pairing(p1, p2);\\n }\\n}\\n\\ncontract Verifier {\\n using Pairing for *;\\n\\n struct VerifyingKey {\\n Pairing.G1Point alfa1;\\n Pairing.G2Point beta2;\\n Pairing.G2Point gamma2;\\n Pairing.G2Point delta2;\\n Pairing.G1Point[] IC;\\n }\\n\\n struct Proof {\\n Pairing.G1Point A;\\n Pairing.G2Point B;\\n Pairing.G1Point C;\\n }\\n\\n function verifyingKey() internal pure returns (VerifyingKey memory vk) {\\n vk.alfa1 = Pairing.G1Point(\\n 20491192805390485299153009773594534940189261866228447918068658471970481763042,\\n 9383485363053290200918347156157836566562967994039712273449902621266178545958\\n );\\n\\n vk.beta2 = Pairing.G2Point(\\n [\\n 4252822878758300859123897981450591353533073413197771768651442665752259397132,\\n 6375614351688725206403948262868962793625744043794305715222011528459656738731\\n ],\\n [\\n 21847035105528745403288232691147584728191162732299865338377159692350059136679,\\n 10505242626370262277552901082094356697409835680220590971873171140371331206856\\n ]\\n );\\n vk.gamma2 = Pairing.G2Point(\\n [\\n 11559732032986387107991004021392285783925812861821192530917403151452391805634,\\n 10857046999023057135944570762232829481370756359578518086990519993285655852781\\n ],\\n [\\n 4082367875863433681332203403145435568316851327593401208105741076214120093531,\\n 8495653923123431417604973247489272438418190587263600148770280649306958101930\\n ]\\n );\\n vk.delta2 = Pairing.G2Point(\\n [\\n 12423666958566268737444308034237892912702648013927558883280319245968679130649,\\n 15986964528637281931410749976607406939789163617014270799373312764775965360012\\n ],\\n [\\n 8394023076056524902583796202128496802110914536948580183128578071394816660799,\\n 4964607673011101982600772762445991192038811950832626693345350322823626470007\\n ]\\n );\\n vk.IC = new Pairing.G1Point[](3);\\n\\n vk.IC[0] = Pairing.G1Point(\\n 1655549413518972190198478012616802994254462093161203201613599472264958303841,\\n 21742734017792296281216385119397138748114275727065024271646515586404591497876\\n );\\n\\n vk.IC[1] = Pairing.G1Point(\\n 16497930821522159474595176304955625435616718625609462506360632944366974274906,\\n 10404924572941018678793755094259635830045501866471999610240845041996101882275\\n );\\n\\n vk.IC[2] = Pairing.G1Point(\\n 9567910551099174794221497568036631681620409346997815381833929247558241020796,\\n 17282591858786007768931802126325866705896012606427630592145070155065868649172\\n );\\n }\\n\\n function verify(uint256[] memory input, Proof memory proof) internal view returns (uint256) {\\n uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\\n VerifyingKey memory vk = verifyingKey();\\n require(input.length + 1 == vk.IC.length, \\\"verifier-bad-input\\\");\\n // Compute the linear combination vk_x\\n Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0);\\n for (uint256 i = 0; i < input.length; i++) {\\n require(input[i] < snark_scalar_field, \\\"verifier-gte-snark-scalar-field\\\");\\n vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.IC[i + 1], input[i]));\\n }\\n vk_x = Pairing.addition(vk_x, vk.IC[0]);\\n if (\\n !Pairing.pairingProd4(\\n Pairing.negate(proof.A), proof.B, vk.alfa1, vk.beta2, vk_x, vk.gamma2, proof.C, vk.delta2\\n )\\n ) return 1;\\n return 0;\\n }\\n /// @return r bool true if proof is valid\\n\\n function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)\\n public\\n view\\n returns (bool r)\\n {\\n Proof memory proof;\\n proof.A = Pairing.G1Point(a[0], a[1]);\\n proof.B = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]);\\n proof.C = Pairing.G1Point(c[0], c[1]);\\n uint256[] memory inputValues = new uint[](input.length);\\n for (uint256 i = 0; i < input.length; i++) {\\n inputValues[i] = input[i];\\n }\\n if (verify(inputValues, proof) == 0) {\\n return true;\\n } else {\\n return false;\\n }\\n }\\n}\",\"keccak256\":\"0x0ec3e9d0de4a99eeedf3adee137b7422bdea221fffdbb9e5226aac5c063545a4\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061134a806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f5c9d69e14610030575b600080fd5b61018f600480360361014081101561004757600080fd5b8101908080604001906002806020026040519081016040528092919082600260200280828437600081840152601f19601f82011690508083019250505050505091929192908060800190600280602002604051908101604052809291906000905b828210156100fc578382604002016002806020026040519081016040528092919082600260200280828437600081840152601f19601f820116905080830192505050505050815260200190600101906100a8565b50505050919291929080604001906002806020026040519081016040528092919082600260200280828437600081840152601f19601f820116905080830192505050505050919291929080604001906002806020026040519081016040528092919082600260200280828437600081840152601f19601f82011690508083019250505050505091929192905050506101a9565b604051808215151515815260200191505060405180910390f35b60006101b36111d2565b6040518060400160405280876000600281106101cb57fe5b60200201518152602001876001600281106101e257fe5b60200201518152508160000181905250604051806040016040528060405180604001604052808860006002811061021557fe5b602002015160006002811061022657fe5b602002015181526020018860006002811061023d57fe5b602002015160016002811061024e57fe5b6020020151815250815260200160405180604001604052808860016002811061027357fe5b602002015160006002811061028457fe5b602002015181526020018860016002811061029b57fe5b60200201516001600281106102ac57fe5b602002015181525081525081602001819052506040518060400160405280856000600281106102d757fe5b60200201518152602001856001600281106102ee57fe5b602002015181525081604001819052506060600267ffffffffffffffff8111801561031857600080fd5b506040519080825280602002602001820160405280156103475781602001602082028036833780820191505090505b50905060008090505b600281101561038f5784816002811061036557fe5b602002015182828151811061037657fe5b6020026020010181815250508080600101915050610350565b50600061039c82846103bc565b14156103ad576001925050506103b4565b6000925050505b949350505050565b6000807f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000190506103ea611205565b6103f26105f0565b9050806080015151600186510114610472576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f76657269666965722d6261642d696e707574000000000000000000000000000081525060200191505060405180910390fd5b61047a61124c565b6040518060400160405280600081526020016000815250905060008090505b865181101561057957838782815181106104af57fe5b60200260200101511061052a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f76657269666965722d6774652d736e61726b2d7363616c61722d6669656c640081525060200191505060405180910390fd5b61056a826105658560800151600185018151811061054457fe5b60200260200101518a858151811061055857fe5b6020026020010151610a55565b610b50565b91508080600101915050610499565b5061059c81836080015160008151811061058f57fe5b6020026020010151610b50565b90506105d26105ae8660000151610c6a565b8660200151846000015185602001518587604001518b604001518960600151610d04565b6105e257600193505050506105ea565b600093505050505b92915050565b6105f8611205565b60405180604001604052807f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e281526020017f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d19268152508160000181905250604051806040016040528060405180604001604052807f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c81526020017f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab815250815260200160405180604001604052807f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a781526020017f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec88152508152508160200181905250604051806040016040528060405180604001604052807f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed815250815260200160405180604001604052807f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b81526020017f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa8152508152508160400181905250604051806040016040528060405180604001604052807f1b778bdaf7d2d76a141a64bf6d5983bfcf2040592634f45ab662dd189c58561981526020017f23584d1f9abbf32341679c4658b203b6fcf47ea6adc1d5548d2ebcf391bf7f8c815250815260200160405180604001604052807f128ed9443a2a711317e24319e0d4493caa1460605ab227b56333b91aa93c953f81526020017f0af9de4d2a3221e54094ef319d9499be2b04296747bfdf80116ca0ddf1dbb2778152508152508160600181905250600367ffffffffffffffff811180156108bc57600080fd5b506040519080825280602002602001820160405280156108f657816020015b6108e361124c565b8152602001906001900390816108db5790505b50816080018190525060405180604001604052807f03a901fcac85b5b11450b3c49766477fc01e5aff3a4b4ab323758526be9dde6181526020017f3011f38b83fb9e775234354ba1e0ff16490977bfb855cac99ed789c1426a7294815250816080015160008151811061096557fe5b602002602001018190525060405180604001604052807f24797f78c49f4d82fb02fbdf871928765135de74f2674c16912163f87ef60d5a81526020017f1700fa863be1dd74edb8e8a969a2795f8a0bd5dd94c98e11a937004de3f091a381525081608001516001815181106109d657fe5b602002602001018190525060405180604001604052807f15273ed6a7550a123c301f66798c2724218b80e7965ea13b8b1d2056b0deeb7c81526020017f263599b0396b575e21ee3248f704393e647c33d6e9580033eb8894da73ef82d48152508160800151600281518110610a4757fe5b602002602001018190525090565b610a5d61124c565b610a65611266565b836000015181600060038110610a7757fe5b602002018181525050836020015181600160038110610a9257fe5b6020020181815250508281600260038110610aa957fe5b602002018181525050600060608360808460076107d05a03fa90508060008114610ad257610ad4565bfe5b5080610b48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f70616972696e672d6d756c2d6661696c6564000000000000000000000000000081525060200191505060405180910390fd5b505092915050565b610b5861124c565b610b60611288565b836000015181600060048110610b7257fe5b602002018181525050836020015181600160048110610b8d57fe5b602002018181525050826000015181600260048110610ba857fe5b602002018181525050826020015181600360048110610bc357fe5b602002018181525050600060608360c08460066107d05a03fa90508060008114610bec57610bee565bfe5b5080610c62576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f70616972696e672d6164642d6661696c6564000000000000000000000000000081525060200191505060405180910390fd5b505092915050565b610c7261124c565b60007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47905060008360000151148015610caf575060008360200151145b15610cd3576040518060400160405280600081526020016000815250915050610cff565b60405180604001604052808460000151815260200182856020015181610cf557fe5b0683038152509150505b919050565b60006060600467ffffffffffffffff81118015610d2057600080fd5b50604051908082528060200260200182016040528015610d5a57816020015b610d4761124c565b815260200190600190039081610d3f5790505b5090506060600467ffffffffffffffff81118015610d7757600080fd5b50604051908082528060200260200182016040528015610db157816020015b610d9e6112aa565b815260200190600190039081610d965790505b5090508a82600081518110610dc257fe5b60200260200101819052508882600181518110610ddb57fe5b60200260200101819052508682600281518110610df457fe5b60200260200101819052508482600381518110610e0d57fe5b60200260200101819052508981600081518110610e2657fe5b60200260200101819052508781600181518110610e3f57fe5b60200260200101819052508581600281518110610e5857fe5b60200260200101819052508381600381518110610e7157fe5b6020026020010181905250610e868282610e96565b9250505098975050505050505050565b60008151835114610f0f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f70616972696e672d6c656e677468732d6661696c65640000000000000000000081525060200191505060405180910390fd5b600083519050600060068202905060608167ffffffffffffffff81118015610f3657600080fd5b50604051908082528060200260200182016040528015610f655781602001602082028036833780820191505090505b50905060008090505b8381101561110b57868181518110610f8257fe5b602002602001015160000151826000600684020181518110610fa057fe5b602002602001018181525050868181518110610fb857fe5b602002602001015160200151826001600684020181518110610fd657fe5b602002602001018181525050858181518110610fee57fe5b60200260200101516000015160006002811061100657fe5b602002015182600260068402018151811061101d57fe5b60200260200101818152505085818151811061103557fe5b60200260200101516000015160016002811061104d57fe5b602002015182600360068402018151811061106457fe5b60200260200101818152505085818151811061107c57fe5b60200260200101516020015160006002811061109457fe5b60200201518260046006840201815181106110ab57fe5b6020026020010181815250508581815181106110c357fe5b6020026020010151602001516001600281106110db57fe5b60200201518260056006840201815181106110f257fe5b6020026020010181815250508080600101915050610f6e565b506111146112d0565b6000602082602086026020860160086107d05a03fa905080600081146111395761113b565bfe5b50806111af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f70616972696e672d6f70636f64652d6661696c6564000000000000000000000081525060200191505060405180910390fd5b6000826000600181106111be57fe5b602002015114159550505050505092915050565b60405180606001604052806111e561124c565b81526020016111f26112aa565b81526020016111ff61124c565b81525090565b6040518060a0016040528061121861124c565b81526020016112256112aa565b81526020016112326112aa565b815260200161123f6112aa565b8152602001606081525090565b604051806040016040528060008152602001600081525090565b6040518060600160405280600390602082028036833780820191505090505090565b6040518060800160405280600490602082028036833780820191505090505090565b60405180604001604052806112bd6112f2565b81526020016112ca6112f2565b81525090565b6040518060200160405280600190602082028036833780820191505090505090565b604051806040016040528060029060208202803683378082019150509050509056fea26469706673582212205668c7cc51565b1c13a0d0ea7e9cfa28ac5b180f722bbd898b58273b1808ed7464736f6c634300060b0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f5c9d69e14610030575b600080fd5b61018f600480360361014081101561004757600080fd5b8101908080604001906002806020026040519081016040528092919082600260200280828437600081840152601f19601f82011690508083019250505050505091929192908060800190600280602002604051908101604052809291906000905b828210156100fc578382604002016002806020026040519081016040528092919082600260200280828437600081840152601f19601f820116905080830192505050505050815260200190600101906100a8565b50505050919291929080604001906002806020026040519081016040528092919082600260200280828437600081840152601f19601f820116905080830192505050505050919291929080604001906002806020026040519081016040528092919082600260200280828437600081840152601f19601f82011690508083019250505050505091929192905050506101a9565b604051808215151515815260200191505060405180910390f35b60006101b36111d2565b6040518060400160405280876000600281106101cb57fe5b60200201518152602001876001600281106101e257fe5b60200201518152508160000181905250604051806040016040528060405180604001604052808860006002811061021557fe5b602002015160006002811061022657fe5b602002015181526020018860006002811061023d57fe5b602002015160016002811061024e57fe5b6020020151815250815260200160405180604001604052808860016002811061027357fe5b602002015160006002811061028457fe5b602002015181526020018860016002811061029b57fe5b60200201516001600281106102ac57fe5b602002015181525081525081602001819052506040518060400160405280856000600281106102d757fe5b60200201518152602001856001600281106102ee57fe5b602002015181525081604001819052506060600267ffffffffffffffff8111801561031857600080fd5b506040519080825280602002602001820160405280156103475781602001602082028036833780820191505090505b50905060008090505b600281101561038f5784816002811061036557fe5b602002015182828151811061037657fe5b6020026020010181815250508080600101915050610350565b50600061039c82846103bc565b14156103ad576001925050506103b4565b6000925050505b949350505050565b6000807f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000190506103ea611205565b6103f26105f0565b9050806080015151600186510114610472576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f76657269666965722d6261642d696e707574000000000000000000000000000081525060200191505060405180910390fd5b61047a61124c565b6040518060400160405280600081526020016000815250905060008090505b865181101561057957838782815181106104af57fe5b60200260200101511061052a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f76657269666965722d6774652d736e61726b2d7363616c61722d6669656c640081525060200191505060405180910390fd5b61056a826105658560800151600185018151811061054457fe5b60200260200101518a858151811061055857fe5b6020026020010151610a55565b610b50565b91508080600101915050610499565b5061059c81836080015160008151811061058f57fe5b6020026020010151610b50565b90506105d26105ae8660000151610c6a565b8660200151846000015185602001518587604001518b604001518960600151610d04565b6105e257600193505050506105ea565b600093505050505b92915050565b6105f8611205565b60405180604001604052807f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e281526020017f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d19268152508160000181905250604051806040016040528060405180604001604052807f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c81526020017f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab815250815260200160405180604001604052807f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a781526020017f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec88152508152508160200181905250604051806040016040528060405180604001604052807f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed815250815260200160405180604001604052807f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b81526020017f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa8152508152508160400181905250604051806040016040528060405180604001604052807f1b778bdaf7d2d76a141a64bf6d5983bfcf2040592634f45ab662dd189c58561981526020017f23584d1f9abbf32341679c4658b203b6fcf47ea6adc1d5548d2ebcf391bf7f8c815250815260200160405180604001604052807f128ed9443a2a711317e24319e0d4493caa1460605ab227b56333b91aa93c953f81526020017f0af9de4d2a3221e54094ef319d9499be2b04296747bfdf80116ca0ddf1dbb2778152508152508160600181905250600367ffffffffffffffff811180156108bc57600080fd5b506040519080825280602002602001820160405280156108f657816020015b6108e361124c565b8152602001906001900390816108db5790505b50816080018190525060405180604001604052807f03a901fcac85b5b11450b3c49766477fc01e5aff3a4b4ab323758526be9dde6181526020017f3011f38b83fb9e775234354ba1e0ff16490977bfb855cac99ed789c1426a7294815250816080015160008151811061096557fe5b602002602001018190525060405180604001604052807f24797f78c49f4d82fb02fbdf871928765135de74f2674c16912163f87ef60d5a81526020017f1700fa863be1dd74edb8e8a969a2795f8a0bd5dd94c98e11a937004de3f091a381525081608001516001815181106109d657fe5b602002602001018190525060405180604001604052807f15273ed6a7550a123c301f66798c2724218b80e7965ea13b8b1d2056b0deeb7c81526020017f263599b0396b575e21ee3248f704393e647c33d6e9580033eb8894da73ef82d48152508160800151600281518110610a4757fe5b602002602001018190525090565b610a5d61124c565b610a65611266565b836000015181600060038110610a7757fe5b602002018181525050836020015181600160038110610a9257fe5b6020020181815250508281600260038110610aa957fe5b602002018181525050600060608360808460076107d05a03fa90508060008114610ad257610ad4565bfe5b5080610b48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f70616972696e672d6d756c2d6661696c6564000000000000000000000000000081525060200191505060405180910390fd5b505092915050565b610b5861124c565b610b60611288565b836000015181600060048110610b7257fe5b602002018181525050836020015181600160048110610b8d57fe5b602002018181525050826000015181600260048110610ba857fe5b602002018181525050826020015181600360048110610bc357fe5b602002018181525050600060608360c08460066107d05a03fa90508060008114610bec57610bee565bfe5b5080610c62576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f70616972696e672d6164642d6661696c6564000000000000000000000000000081525060200191505060405180910390fd5b505092915050565b610c7261124c565b60007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47905060008360000151148015610caf575060008360200151145b15610cd3576040518060400160405280600081526020016000815250915050610cff565b60405180604001604052808460000151815260200182856020015181610cf557fe5b0683038152509150505b919050565b60006060600467ffffffffffffffff81118015610d2057600080fd5b50604051908082528060200260200182016040528015610d5a57816020015b610d4761124c565b815260200190600190039081610d3f5790505b5090506060600467ffffffffffffffff81118015610d7757600080fd5b50604051908082528060200260200182016040528015610db157816020015b610d9e6112aa565b815260200190600190039081610d965790505b5090508a82600081518110610dc257fe5b60200260200101819052508882600181518110610ddb57fe5b60200260200101819052508682600281518110610df457fe5b60200260200101819052508482600381518110610e0d57fe5b60200260200101819052508981600081518110610e2657fe5b60200260200101819052508781600181518110610e3f57fe5b60200260200101819052508581600281518110610e5857fe5b60200260200101819052508381600381518110610e7157fe5b6020026020010181905250610e868282610e96565b9250505098975050505050505050565b60008151835114610f0f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f70616972696e672d6c656e677468732d6661696c65640000000000000000000081525060200191505060405180910390fd5b600083519050600060068202905060608167ffffffffffffffff81118015610f3657600080fd5b50604051908082528060200260200182016040528015610f655781602001602082028036833780820191505090505b50905060008090505b8381101561110b57868181518110610f8257fe5b602002602001015160000151826000600684020181518110610fa057fe5b602002602001018181525050868181518110610fb857fe5b602002602001015160200151826001600684020181518110610fd657fe5b602002602001018181525050858181518110610fee57fe5b60200260200101516000015160006002811061100657fe5b602002015182600260068402018151811061101d57fe5b60200260200101818152505085818151811061103557fe5b60200260200101516000015160016002811061104d57fe5b602002015182600360068402018151811061106457fe5b60200260200101818152505085818151811061107c57fe5b60200260200101516020015160006002811061109457fe5b60200201518260046006840201815181106110ab57fe5b6020026020010181815250508581815181106110c357fe5b6020026020010151602001516001600281106110db57fe5b60200201518260056006840201815181106110f257fe5b6020026020010181815250508080600101915050610f6e565b506111146112d0565b6000602082602086026020860160086107d05a03fa905080600081146111395761113b565bfe5b50806111af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f70616972696e672d6f70636f64652d6661696c6564000000000000000000000081525060200191505060405180910390fd5b6000826000600181106111be57fe5b602002015114159550505050505092915050565b60405180606001604052806111e561124c565b81526020016111f26112aa565b81526020016111ff61124c565b81525090565b6040518060a0016040528061121861124c565b81526020016112256112aa565b81526020016112326112aa565b815260200161123f6112aa565b8152602001606081525090565b604051806040016040528060008152602001600081525090565b6040518060600160405280600390602082028036833780820191505090505090565b6040518060800160405280600490602082028036833780820191505090505090565b60405180604001604052806112bd6112f2565b81526020016112ca6112f2565b81525090565b6040518060200160405280600190602082028036833780820191505090505090565b604051806040016040528060029060208202803683378082019150509050509056fea26469706673582212205668c7cc51565b1c13a0d0ea7e9cfa28ac5b180f722bbd898b58273b1808ed7464736f6c634300060b0033", + "solcInputHash": "8725b13328c7d7e2e008ae1d327b8955", + "metadata": "{\"compiler\":{\"version\":\"0.6.11+commit.5ef660b1\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"a\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2][2]\",\"name\":\"b\",\"type\":\"uint256[2][2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"c\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"input\",\"type\":\"uint256[2]\"}],\"name\":\"verifyProof\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"r\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"verifyProof(uint256[2],uint256[2][2],uint256[2],uint256[2])\":{\"returns\":{\"r\":\" bool true if proof is valid\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/RlnVerifier.sol\":\"Verifier\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\"]},\"sources\":{\"contracts/RlnVerifier.sol\":{\"content\":\"// File: https://github.com/Rate-Limiting-Nullifier/rln-contract-v1/blob/main/src/RLNVerifier.sol\\n// Copyright 2017 Christian Reitwiessner\\n// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \\\"Software\\\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\\n// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\\n//\\n// 2019 OKIMS\\n// ported to solidity 0.6\\n// fixed linter warnings\\n// added requiere error messages\\n//\\n//\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.6.11;\\n\\nlibrary Pairing {\\n struct G1Point {\\n uint256 X;\\n uint256 Y;\\n }\\n // Encoding of field elements is: X[0] * z + X[1]\\n\\n struct G2Point {\\n uint256[2] X;\\n uint256[2] Y;\\n }\\n /// @return the generator of G1\\n\\n function P1() internal pure returns (G1Point memory) {\\n return G1Point(1, 2);\\n }\\n /// @return the generator of G2\\n\\n function P2() internal pure returns (G2Point memory) {\\n // Original code point\\n return G2Point(\\n [\\n 11559732032986387107991004021392285783925812861821192530917403151452391805634,\\n 10857046999023057135944570762232829481370756359578518086990519993285655852781\\n ],\\n [\\n 4082367875863433681332203403145435568316851327593401208105741076214120093531,\\n 8495653923123431417604973247489272438418190587263600148770280649306958101930\\n ]\\n );\\n\\n /*\\n // Changed by Jordi point\\n return G2Point(\\n [10857046999023057135944570762232829481370756359578518086990519993285655852781,\\n 11559732032986387107991004021392285783925812861821192530917403151452391805634],\\n [8495653923123431417604973247489272438418190587263600148770280649306958101930,\\n 4082367875863433681332203403145435568316851327593401208105741076214120093531]\\n );*/\\n }\\n /// @return r the negation of p, i.e. p.addition(p.negate()) should be zero.\\n\\n function negate(G1Point memory p) internal pure returns (G1Point memory r) {\\n // The prime q in the base field F_q for G1\\n uint256 q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\\n if (p.X == 0 && p.Y == 0) {\\n return G1Point(0, 0);\\n }\\n return G1Point(p.X, q - (p.Y % q));\\n }\\n /// @return r the sum of two points of G1\\n\\n function addition(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) {\\n uint256[4] memory input;\\n input[0] = p1.X;\\n input[1] = p1.Y;\\n input[2] = p2.X;\\n input[3] = p2.Y;\\n bool success;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60)\\n // Use \\\"invalid\\\" to make gas estimation work\\n switch success\\n case 0 { invalid() }\\n }\\n require(success, \\\"pairing-add-failed\\\");\\n }\\n /// @return r the product of a point on G1 and a scalar, i.e.\\n /// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p.\\n\\n function scalar_mul(G1Point memory p, uint256 s) internal view returns (G1Point memory r) {\\n uint256[3] memory input;\\n input[0] = p.X;\\n input[1] = p.Y;\\n input[2] = s;\\n bool success;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60)\\n // Use \\\"invalid\\\" to make gas estimation work\\n switch success\\n case 0 { invalid() }\\n }\\n require(success, \\\"pairing-mul-failed\\\");\\n }\\n /// @return the result of computing the pairing check\\n /// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1\\n /// For example pairing([P1(), P1().negate()], [P2(), P2()]) should\\n /// return true.\\n\\n function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) {\\n require(p1.length == p2.length, \\\"pairing-lengths-failed\\\");\\n uint256 elements = p1.length;\\n uint256 inputSize = elements * 6;\\n uint256[] memory input = new uint[](inputSize);\\n for (uint256 i = 0; i < elements; i++) {\\n input[i * 6 + 0] = p1[i].X;\\n input[i * 6 + 1] = p1[i].Y;\\n input[i * 6 + 2] = p2[i].X[0];\\n input[i * 6 + 3] = p2[i].X[1];\\n input[i * 6 + 4] = p2[i].Y[0];\\n input[i * 6 + 5] = p2[i].Y[1];\\n }\\n uint256[1] memory out;\\n bool success;\\n // solium-disable-next-line security/no-inline-assembly\\n assembly {\\n success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)\\n // Use \\\"invalid\\\" to make gas estimation work\\n switch success\\n case 0 { invalid() }\\n }\\n require(success, \\\"pairing-opcode-failed\\\");\\n return out[0] != 0;\\n }\\n /// Convenience method for a pairing check for two pairs.\\n\\n function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2)\\n internal\\n view\\n returns (bool)\\n {\\n G1Point[] memory p1 = new G1Point[](2);\\n G2Point[] memory p2 = new G2Point[](2);\\n p1[0] = a1;\\n p1[1] = b1;\\n p2[0] = a2;\\n p2[1] = b2;\\n return pairing(p1, p2);\\n }\\n /// Convenience method for a pairing check for three pairs.\\n\\n function pairingProd3(\\n G1Point memory a1,\\n G2Point memory a2,\\n G1Point memory b1,\\n G2Point memory b2,\\n G1Point memory c1,\\n G2Point memory c2\\n ) internal view returns (bool) {\\n G1Point[] memory p1 = new G1Point[](3);\\n G2Point[] memory p2 = new G2Point[](3);\\n p1[0] = a1;\\n p1[1] = b1;\\n p1[2] = c1;\\n p2[0] = a2;\\n p2[1] = b2;\\n p2[2] = c2;\\n return pairing(p1, p2);\\n }\\n /// Convenience method for a pairing check for four pairs.\\n\\n function pairingProd4(\\n G1Point memory a1,\\n G2Point memory a2,\\n G1Point memory b1,\\n G2Point memory b2,\\n G1Point memory c1,\\n G2Point memory c2,\\n G1Point memory d1,\\n G2Point memory d2\\n ) internal view returns (bool) {\\n G1Point[] memory p1 = new G1Point[](4);\\n G2Point[] memory p2 = new G2Point[](4);\\n p1[0] = a1;\\n p1[1] = b1;\\n p1[2] = c1;\\n p1[3] = d1;\\n p2[0] = a2;\\n p2[1] = b2;\\n p2[2] = c2;\\n p2[3] = d2;\\n return pairing(p1, p2);\\n }\\n}\\n\\ncontract Verifier {\\n using Pairing for *;\\n\\n struct VerifyingKey {\\n Pairing.G1Point alfa1;\\n Pairing.G2Point beta2;\\n Pairing.G2Point gamma2;\\n Pairing.G2Point delta2;\\n Pairing.G1Point[] IC;\\n }\\n\\n struct Proof {\\n Pairing.G1Point A;\\n Pairing.G2Point B;\\n Pairing.G1Point C;\\n }\\n\\n function verifyingKey() internal pure returns (VerifyingKey memory vk) {\\n vk.alfa1 = Pairing.G1Point(\\n 20491192805390485299153009773594534940189261866228447918068658471970481763042,\\n 9383485363053290200918347156157836566562967994039712273449902621266178545958\\n );\\n\\n vk.beta2 = Pairing.G2Point(\\n [\\n 4252822878758300859123897981450591353533073413197771768651442665752259397132,\\n 6375614351688725206403948262868962793625744043794305715222011528459656738731\\n ],\\n [\\n 21847035105528745403288232691147584728191162732299865338377159692350059136679,\\n 10505242626370262277552901082094356697409835680220590971873171140371331206856\\n ]\\n );\\n vk.gamma2 = Pairing.G2Point(\\n [\\n 11559732032986387107991004021392285783925812861821192530917403151452391805634,\\n 10857046999023057135944570762232829481370756359578518086990519993285655852781\\n ],\\n [\\n 4082367875863433681332203403145435568316851327593401208105741076214120093531,\\n 8495653923123431417604973247489272438418190587263600148770280649306958101930\\n ]\\n );\\n vk.delta2 = Pairing.G2Point(\\n [\\n 12423666958566268737444308034237892912702648013927558883280319245968679130649,\\n 15986964528637281931410749976607406939789163617014270799373312764775965360012\\n ],\\n [\\n 8394023076056524902583796202128496802110914536948580183128578071394816660799,\\n 4964607673011101982600772762445991192038811950832626693345350322823626470007\\n ]\\n );\\n vk.IC = new Pairing.G1Point[](3);\\n\\n vk.IC[0] = Pairing.G1Point(\\n 1655549413518972190198478012616802994254462093161203201613599472264958303841,\\n 21742734017792296281216385119397138748114275727065024271646515586404591497876\\n );\\n\\n vk.IC[1] = Pairing.G1Point(\\n 16497930821522159474595176304955625435616718625609462506360632944366974274906,\\n 10404924572941018678793755094259635830045501866471999610240845041996101882275\\n );\\n\\n vk.IC[2] = Pairing.G1Point(\\n 9567910551099174794221497568036631681620409346997815381833929247558241020796,\\n 17282591858786007768931802126325866705896012606427630592145070155065868649172\\n );\\n }\\n\\n function verify(uint256[] memory input, Proof memory proof) internal view returns (uint256) {\\n uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\\n VerifyingKey memory vk = verifyingKey();\\n require(input.length + 1 == vk.IC.length, \\\"verifier-bad-input\\\");\\n // Compute the linear combination vk_x\\n Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0);\\n for (uint256 i = 0; i < input.length; i++) {\\n require(input[i] < snark_scalar_field, \\\"verifier-gte-snark-scalar-field\\\");\\n vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.IC[i + 1], input[i]));\\n }\\n vk_x = Pairing.addition(vk_x, vk.IC[0]);\\n if (\\n !Pairing.pairingProd4(\\n Pairing.negate(proof.A), proof.B, vk.alfa1, vk.beta2, vk_x, vk.gamma2, proof.C, vk.delta2\\n )\\n ) return 1;\\n return 0;\\n }\\n /// @return r bool true if proof is valid\\n\\n function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)\\n public\\n view\\n returns (bool r)\\n {\\n Proof memory proof;\\n proof.A = Pairing.G1Point(a[0], a[1]);\\n proof.B = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]);\\n proof.C = Pairing.G1Point(c[0], c[1]);\\n uint256[] memory inputValues = new uint[](input.length);\\n for (uint256 i = 0; i < input.length; i++) {\\n inputValues[i] = input[i];\\n }\\n if (verify(inputValues, proof) == 0) {\\n return true;\\n } else {\\n return false;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2d33f718e0654cdcf35a46f90eff56d9883dc98900a2937012890814e6c3c6ec\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061134a806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f5c9d69e14610030575b600080fd5b61018f600480360361014081101561004757600080fd5b8101908080604001906002806020026040519081016040528092919082600260200280828437600081840152601f19601f82011690508083019250505050505091929192908060800190600280602002604051908101604052809291906000905b828210156100fc578382604002016002806020026040519081016040528092919082600260200280828437600081840152601f19601f820116905080830192505050505050815260200190600101906100a8565b50505050919291929080604001906002806020026040519081016040528092919082600260200280828437600081840152601f19601f820116905080830192505050505050919291929080604001906002806020026040519081016040528092919082600260200280828437600081840152601f19601f82011690508083019250505050505091929192905050506101a9565b604051808215151515815260200191505060405180910390f35b60006101b36111d2565b6040518060400160405280876000600281106101cb57fe5b60200201518152602001876001600281106101e257fe5b60200201518152508160000181905250604051806040016040528060405180604001604052808860006002811061021557fe5b602002015160006002811061022657fe5b602002015181526020018860006002811061023d57fe5b602002015160016002811061024e57fe5b6020020151815250815260200160405180604001604052808860016002811061027357fe5b602002015160006002811061028457fe5b602002015181526020018860016002811061029b57fe5b60200201516001600281106102ac57fe5b602002015181525081525081602001819052506040518060400160405280856000600281106102d757fe5b60200201518152602001856001600281106102ee57fe5b602002015181525081604001819052506060600267ffffffffffffffff8111801561031857600080fd5b506040519080825280602002602001820160405280156103475781602001602082028036833780820191505090505b50905060008090505b600281101561038f5784816002811061036557fe5b602002015182828151811061037657fe5b6020026020010181815250508080600101915050610350565b50600061039c82846103bc565b14156103ad576001925050506103b4565b6000925050505b949350505050565b6000807f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000190506103ea611205565b6103f26105f0565b9050806080015151600186510114610472576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f76657269666965722d6261642d696e707574000000000000000000000000000081525060200191505060405180910390fd5b61047a61124c565b6040518060400160405280600081526020016000815250905060008090505b865181101561057957838782815181106104af57fe5b60200260200101511061052a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f76657269666965722d6774652d736e61726b2d7363616c61722d6669656c640081525060200191505060405180910390fd5b61056a826105658560800151600185018151811061054457fe5b60200260200101518a858151811061055857fe5b6020026020010151610a55565b610b50565b91508080600101915050610499565b5061059c81836080015160008151811061058f57fe5b6020026020010151610b50565b90506105d26105ae8660000151610c6a565b8660200151846000015185602001518587604001518b604001518960600151610d04565b6105e257600193505050506105ea565b600093505050505b92915050565b6105f8611205565b60405180604001604052807f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e281526020017f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d19268152508160000181905250604051806040016040528060405180604001604052807f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c81526020017f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab815250815260200160405180604001604052807f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a781526020017f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec88152508152508160200181905250604051806040016040528060405180604001604052807f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed815250815260200160405180604001604052807f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b81526020017f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa8152508152508160400181905250604051806040016040528060405180604001604052807f1b778bdaf7d2d76a141a64bf6d5983bfcf2040592634f45ab662dd189c58561981526020017f23584d1f9abbf32341679c4658b203b6fcf47ea6adc1d5548d2ebcf391bf7f8c815250815260200160405180604001604052807f128ed9443a2a711317e24319e0d4493caa1460605ab227b56333b91aa93c953f81526020017f0af9de4d2a3221e54094ef319d9499be2b04296747bfdf80116ca0ddf1dbb2778152508152508160600181905250600367ffffffffffffffff811180156108bc57600080fd5b506040519080825280602002602001820160405280156108f657816020015b6108e361124c565b8152602001906001900390816108db5790505b50816080018190525060405180604001604052807f03a901fcac85b5b11450b3c49766477fc01e5aff3a4b4ab323758526be9dde6181526020017f3011f38b83fb9e775234354ba1e0ff16490977bfb855cac99ed789c1426a7294815250816080015160008151811061096557fe5b602002602001018190525060405180604001604052807f24797f78c49f4d82fb02fbdf871928765135de74f2674c16912163f87ef60d5a81526020017f1700fa863be1dd74edb8e8a969a2795f8a0bd5dd94c98e11a937004de3f091a381525081608001516001815181106109d657fe5b602002602001018190525060405180604001604052807f15273ed6a7550a123c301f66798c2724218b80e7965ea13b8b1d2056b0deeb7c81526020017f263599b0396b575e21ee3248f704393e647c33d6e9580033eb8894da73ef82d48152508160800151600281518110610a4757fe5b602002602001018190525090565b610a5d61124c565b610a65611266565b836000015181600060038110610a7757fe5b602002018181525050836020015181600160038110610a9257fe5b6020020181815250508281600260038110610aa957fe5b602002018181525050600060608360808460076107d05a03fa90508060008114610ad257610ad4565bfe5b5080610b48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f70616972696e672d6d756c2d6661696c6564000000000000000000000000000081525060200191505060405180910390fd5b505092915050565b610b5861124c565b610b60611288565b836000015181600060048110610b7257fe5b602002018181525050836020015181600160048110610b8d57fe5b602002018181525050826000015181600260048110610ba857fe5b602002018181525050826020015181600360048110610bc357fe5b602002018181525050600060608360c08460066107d05a03fa90508060008114610bec57610bee565bfe5b5080610c62576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f70616972696e672d6164642d6661696c6564000000000000000000000000000081525060200191505060405180910390fd5b505092915050565b610c7261124c565b60007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47905060008360000151148015610caf575060008360200151145b15610cd3576040518060400160405280600081526020016000815250915050610cff565b60405180604001604052808460000151815260200182856020015181610cf557fe5b0683038152509150505b919050565b60006060600467ffffffffffffffff81118015610d2057600080fd5b50604051908082528060200260200182016040528015610d5a57816020015b610d4761124c565b815260200190600190039081610d3f5790505b5090506060600467ffffffffffffffff81118015610d7757600080fd5b50604051908082528060200260200182016040528015610db157816020015b610d9e6112aa565b815260200190600190039081610d965790505b5090508a82600081518110610dc257fe5b60200260200101819052508882600181518110610ddb57fe5b60200260200101819052508682600281518110610df457fe5b60200260200101819052508482600381518110610e0d57fe5b60200260200101819052508981600081518110610e2657fe5b60200260200101819052508781600181518110610e3f57fe5b60200260200101819052508581600281518110610e5857fe5b60200260200101819052508381600381518110610e7157fe5b6020026020010181905250610e868282610e96565b9250505098975050505050505050565b60008151835114610f0f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f70616972696e672d6c656e677468732d6661696c65640000000000000000000081525060200191505060405180910390fd5b600083519050600060068202905060608167ffffffffffffffff81118015610f3657600080fd5b50604051908082528060200260200182016040528015610f655781602001602082028036833780820191505090505b50905060008090505b8381101561110b57868181518110610f8257fe5b602002602001015160000151826000600684020181518110610fa057fe5b602002602001018181525050868181518110610fb857fe5b602002602001015160200151826001600684020181518110610fd657fe5b602002602001018181525050858181518110610fee57fe5b60200260200101516000015160006002811061100657fe5b602002015182600260068402018151811061101d57fe5b60200260200101818152505085818151811061103557fe5b60200260200101516000015160016002811061104d57fe5b602002015182600360068402018151811061106457fe5b60200260200101818152505085818151811061107c57fe5b60200260200101516020015160006002811061109457fe5b60200201518260046006840201815181106110ab57fe5b6020026020010181815250508581815181106110c357fe5b6020026020010151602001516001600281106110db57fe5b60200201518260056006840201815181106110f257fe5b6020026020010181815250508080600101915050610f6e565b506111146112d0565b6000602082602086026020860160086107d05a03fa905080600081146111395761113b565bfe5b50806111af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f70616972696e672d6f70636f64652d6661696c6564000000000000000000000081525060200191505060405180910390fd5b6000826000600181106111be57fe5b602002015114159550505050505092915050565b60405180606001604052806111e561124c565b81526020016111f26112aa565b81526020016111ff61124c565b81525090565b6040518060a0016040528061121861124c565b81526020016112256112aa565b81526020016112326112aa565b815260200161123f6112aa565b8152602001606081525090565b604051806040016040528060008152602001600081525090565b6040518060600160405280600390602082028036833780820191505090505090565b6040518060800160405280600490602082028036833780820191505090505090565b60405180604001604052806112bd6112f2565b81526020016112ca6112f2565b81525090565b6040518060200160405280600190602082028036833780820191505090505090565b604051806040016040528060029060208202803683378082019150509050509056fea2646970667358221220e679578dc17d83d5f5875790dcd4ba128a6c05ba751b3d2b63a46d4b5f96e49364736f6c634300060b0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f5c9d69e14610030575b600080fd5b61018f600480360361014081101561004757600080fd5b8101908080604001906002806020026040519081016040528092919082600260200280828437600081840152601f19601f82011690508083019250505050505091929192908060800190600280602002604051908101604052809291906000905b828210156100fc578382604002016002806020026040519081016040528092919082600260200280828437600081840152601f19601f820116905080830192505050505050815260200190600101906100a8565b50505050919291929080604001906002806020026040519081016040528092919082600260200280828437600081840152601f19601f820116905080830192505050505050919291929080604001906002806020026040519081016040528092919082600260200280828437600081840152601f19601f82011690508083019250505050505091929192905050506101a9565b604051808215151515815260200191505060405180910390f35b60006101b36111d2565b6040518060400160405280876000600281106101cb57fe5b60200201518152602001876001600281106101e257fe5b60200201518152508160000181905250604051806040016040528060405180604001604052808860006002811061021557fe5b602002015160006002811061022657fe5b602002015181526020018860006002811061023d57fe5b602002015160016002811061024e57fe5b6020020151815250815260200160405180604001604052808860016002811061027357fe5b602002015160006002811061028457fe5b602002015181526020018860016002811061029b57fe5b60200201516001600281106102ac57fe5b602002015181525081525081602001819052506040518060400160405280856000600281106102d757fe5b60200201518152602001856001600281106102ee57fe5b602002015181525081604001819052506060600267ffffffffffffffff8111801561031857600080fd5b506040519080825280602002602001820160405280156103475781602001602082028036833780820191505090505b50905060008090505b600281101561038f5784816002811061036557fe5b602002015182828151811061037657fe5b6020026020010181815250508080600101915050610350565b50600061039c82846103bc565b14156103ad576001925050506103b4565b6000925050505b949350505050565b6000807f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000190506103ea611205565b6103f26105f0565b9050806080015151600186510114610472576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f76657269666965722d6261642d696e707574000000000000000000000000000081525060200191505060405180910390fd5b61047a61124c565b6040518060400160405280600081526020016000815250905060008090505b865181101561057957838782815181106104af57fe5b60200260200101511061052a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f76657269666965722d6774652d736e61726b2d7363616c61722d6669656c640081525060200191505060405180910390fd5b61056a826105658560800151600185018151811061054457fe5b60200260200101518a858151811061055857fe5b6020026020010151610a55565b610b50565b91508080600101915050610499565b5061059c81836080015160008151811061058f57fe5b6020026020010151610b50565b90506105d26105ae8660000151610c6a565b8660200151846000015185602001518587604001518b604001518960600151610d04565b6105e257600193505050506105ea565b600093505050505b92915050565b6105f8611205565b60405180604001604052807f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e281526020017f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d19268152508160000181905250604051806040016040528060405180604001604052807f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c81526020017f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab815250815260200160405180604001604052807f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a781526020017f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec88152508152508160200181905250604051806040016040528060405180604001604052807f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed815250815260200160405180604001604052807f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b81526020017f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa8152508152508160400181905250604051806040016040528060405180604001604052807f1b778bdaf7d2d76a141a64bf6d5983bfcf2040592634f45ab662dd189c58561981526020017f23584d1f9abbf32341679c4658b203b6fcf47ea6adc1d5548d2ebcf391bf7f8c815250815260200160405180604001604052807f128ed9443a2a711317e24319e0d4493caa1460605ab227b56333b91aa93c953f81526020017f0af9de4d2a3221e54094ef319d9499be2b04296747bfdf80116ca0ddf1dbb2778152508152508160600181905250600367ffffffffffffffff811180156108bc57600080fd5b506040519080825280602002602001820160405280156108f657816020015b6108e361124c565b8152602001906001900390816108db5790505b50816080018190525060405180604001604052807f03a901fcac85b5b11450b3c49766477fc01e5aff3a4b4ab323758526be9dde6181526020017f3011f38b83fb9e775234354ba1e0ff16490977bfb855cac99ed789c1426a7294815250816080015160008151811061096557fe5b602002602001018190525060405180604001604052807f24797f78c49f4d82fb02fbdf871928765135de74f2674c16912163f87ef60d5a81526020017f1700fa863be1dd74edb8e8a969a2795f8a0bd5dd94c98e11a937004de3f091a381525081608001516001815181106109d657fe5b602002602001018190525060405180604001604052807f15273ed6a7550a123c301f66798c2724218b80e7965ea13b8b1d2056b0deeb7c81526020017f263599b0396b575e21ee3248f704393e647c33d6e9580033eb8894da73ef82d48152508160800151600281518110610a4757fe5b602002602001018190525090565b610a5d61124c565b610a65611266565b836000015181600060038110610a7757fe5b602002018181525050836020015181600160038110610a9257fe5b6020020181815250508281600260038110610aa957fe5b602002018181525050600060608360808460076107d05a03fa90508060008114610ad257610ad4565bfe5b5080610b48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f70616972696e672d6d756c2d6661696c6564000000000000000000000000000081525060200191505060405180910390fd5b505092915050565b610b5861124c565b610b60611288565b836000015181600060048110610b7257fe5b602002018181525050836020015181600160048110610b8d57fe5b602002018181525050826000015181600260048110610ba857fe5b602002018181525050826020015181600360048110610bc357fe5b602002018181525050600060608360c08460066107d05a03fa90508060008114610bec57610bee565bfe5b5080610c62576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f70616972696e672d6164642d6661696c6564000000000000000000000000000081525060200191505060405180910390fd5b505092915050565b610c7261124c565b60007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47905060008360000151148015610caf575060008360200151145b15610cd3576040518060400160405280600081526020016000815250915050610cff565b60405180604001604052808460000151815260200182856020015181610cf557fe5b0683038152509150505b919050565b60006060600467ffffffffffffffff81118015610d2057600080fd5b50604051908082528060200260200182016040528015610d5a57816020015b610d4761124c565b815260200190600190039081610d3f5790505b5090506060600467ffffffffffffffff81118015610d7757600080fd5b50604051908082528060200260200182016040528015610db157816020015b610d9e6112aa565b815260200190600190039081610d965790505b5090508a82600081518110610dc257fe5b60200260200101819052508882600181518110610ddb57fe5b60200260200101819052508682600281518110610df457fe5b60200260200101819052508482600381518110610e0d57fe5b60200260200101819052508981600081518110610e2657fe5b60200260200101819052508781600181518110610e3f57fe5b60200260200101819052508581600281518110610e5857fe5b60200260200101819052508381600381518110610e7157fe5b6020026020010181905250610e868282610e96565b9250505098975050505050505050565b60008151835114610f0f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f70616972696e672d6c656e677468732d6661696c65640000000000000000000081525060200191505060405180910390fd5b600083519050600060068202905060608167ffffffffffffffff81118015610f3657600080fd5b50604051908082528060200260200182016040528015610f655781602001602082028036833780820191505090505b50905060008090505b8381101561110b57868181518110610f8257fe5b602002602001015160000151826000600684020181518110610fa057fe5b602002602001018181525050868181518110610fb857fe5b602002602001015160200151826001600684020181518110610fd657fe5b602002602001018181525050858181518110610fee57fe5b60200260200101516000015160006002811061100657fe5b602002015182600260068402018151811061101d57fe5b60200260200101818152505085818151811061103557fe5b60200260200101516000015160016002811061104d57fe5b602002015182600360068402018151811061106457fe5b60200260200101818152505085818151811061107c57fe5b60200260200101516020015160006002811061109457fe5b60200201518260046006840201815181106110ab57fe5b6020026020010181815250508581815181106110c357fe5b6020026020010151602001516001600281106110db57fe5b60200201518260056006840201815181106110f257fe5b6020026020010181815250508080600101915050610f6e565b506111146112d0565b6000602082602086026020860160086107d05a03fa905080600081146111395761113b565bfe5b50806111af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f70616972696e672d6f70636f64652d6661696c6564000000000000000000000081525060200191505060405180910390fd5b6000826000600181106111be57fe5b602002015114159550505050505092915050565b60405180606001604052806111e561124c565b81526020016111f26112aa565b81526020016111ff61124c565b81525090565b6040518060a0016040528061121861124c565b81526020016112256112aa565b81526020016112326112aa565b815260200161123f6112aa565b8152602001606081525090565b604051806040016040528060008152602001600081525090565b6040518060600160405280600390602082028036833780820191505090505090565b6040518060800160405280600490602082028036833780820191505090505090565b60405180604001604052806112bd6112f2565b81526020016112ca6112f2565b81525090565b6040518060200160405280600190602082028036833780820191505090505090565b604051806040016040528060029060208202803683378082019150509050509056fea2646970667358221220e679578dc17d83d5f5875790dcd4ba128a6c05ba751b3d2b63a46d4b5f96e49364736f6c634300060b0033", "devdoc": { "kind": "dev", "methods": { diff --git a/deployments/sepolia/solcInputs/0e0cac683e804dc76f2f24c8a5b4012c.json b/deployments/sepolia/solcInputs/0e0cac683e804dc76f2f24c8a5b4012c.json deleted file mode 100644 index d1cdbb6..0000000 --- a/deployments/sepolia/solcInputs/0e0cac683e804dc76f2f24c8a5b4012c.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/IVerifier.sol": { - "content": "// SPDX-License-Identifier: Apache-2.0 OR MIT\npragma solidity 0.8.15;\n\ninterface IVerifier {\n function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)\n external\n view\n returns (bool);\n}\n" - }, - "contracts/PoseidonHasher.sol": { - "content": "// SPDX-License-Identifier: MIT\n\n// Forked from https://github.com/kilic/rlnapp/\n\npragma solidity 0.8.15;\n\ninterface IPoseidonHasher {\n /// @notice Hashes the input using the Poseidon hash function, n = 2, second input is the constant 0\n /// @param input The input to hash\n function hash(uint256 input) external pure returns (uint256 result);\n}\n\ncontract PoseidonHasher is IPoseidonHasher {\n uint256 constant Q =\n 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n uint256 constant C0 =\n 4417881134626180770308697923359573201005643519861877412381846989312604493735;\n uint256 constant C1 =\n 5433650512959517612316327474713065966758808864213826738576266661723522780033;\n uint256 constant C2 =\n 13641176377184356099764086973022553863760045607496549923679278773208775739952;\n uint256 constant C3 =\n 17949713444224994136330421782109149544629237834775211751417461773584374506783;\n uint256 constant C4 =\n 13765628375339178273710281891027109699578766420463125835325926111705201856003;\n uint256 constant C5 =\n 19179513468172002314585757290678967643352171735526887944518845346318719730387;\n uint256 constant C6 =\n 5157412437176756884543472904098424903141745259452875378101256928559722612176;\n uint256 constant C7 =\n 535160875740282236955320458485730000677124519901643397458212725410971557409;\n uint256 constant C8 =\n 1050793453380762984940163090920066886770841063557081906093018330633089036729;\n uint256 constant C9 =\n 10665495010329663932664894101216428400933984666065399374198502106997623173873;\n uint256 constant C10 =\n 19965634623406616956648724894636666805991993496469370618546874926025059150737;\n uint256 constant C11 =\n 13007250030070838431593222885902415182312449212965120303174723305710127422213;\n uint256 constant C12 =\n 16877538715074991604507979123743768693428157847423939051086744213162455276374;\n uint256 constant C13 =\n 18211747749504876135588847560312685184956239426147543810126553367063157141465;\n uint256 constant C14 =\n 18151553319826126919739798892854572062191241985315767086020821632812331245635;\n uint256 constant C15 =\n 19957033149976712666746140949846950406660099037474791840946955175819555930825;\n uint256 constant C16 =\n 3469514863538261843186854830917934449567467100548474599735384052339577040841;\n uint256 constant C17 =\n 989698510043911779243192466312362856042600749099921773896924315611668507708;\n uint256 constant C18 =\n 12568377015646290945235387813564567111330046038050864455358059568128000172201;\n uint256 constant C19 =\n 20856104135605479600325529349246932565148587186338606236677138505306779314172;\n uint256 constant C20 =\n 8206918720503535523121349917159924938835810381723474192155637697065780938424;\n uint256 constant C21 =\n 1309058477013932989380617265069188723120054926187607548493110334522527703566;\n uint256 constant C22 =\n 14076116939332667074621703729512195584105250395163383769419390236426287710606;\n uint256 constant C23 =\n 10153498892749751942204288991871286290442690932856658983589258153608012428674;\n uint256 constant C24 =\n 18202499207234128286137597834010475797175973146805180988367589376893530181575;\n uint256 constant C25 =\n 12739388830157083522877690211447248168864006284243907142044329113461613743052;\n uint256 constant C26 =\n 15123358710467780770838026754240340042441262572309759635224051333176022613949;\n uint256 constant C27 =\n 19925004701844594370904593774447343836015483888496504201331110250494635362184;\n uint256 constant C28 =\n 10352416606816998476681131583320899030072315953910679608943150613208329645891;\n uint256 constant C29 =\n 10567371822366244361703342347428230537114808440249611395507235283708966113221;\n uint256 constant C30 =\n 5635498582763880627392290206431559361272660937399944184533035305989295959602;\n uint256 constant C31 =\n 11866432933224219174041051738704352719163271639958083608224676028593315904909;\n uint256 constant C32 =\n 5795020705294401441272215064554385591292330721703923167136157291459784140431;\n uint256 constant C33 =\n 9482202378699252817564375087302794636287866584767523335624368774856230692758;\n uint256 constant C34 =\n 4245237636894546151746468406560945873445548423466753843402086544922216329298;\n uint256 constant C35 =\n 12000500941313982757584712677991730019124834399479314697467598397927435905133;\n uint256 constant C36 =\n 7596790274058425558167520209857956363736666939016807569082239187494363541787;\n uint256 constant C37 =\n 2484867918246116343205467273440098378820186751202461278013576281097918148877;\n uint256 constant C38 =\n 18312645949449997391810445935615409295369169383463185688973803378104013950190;\n uint256 constant C39 =\n 15320686572748723004980855263301182130424010735782762814513954166519592552733;\n uint256 constant C40 =\n 12618438900597948888520621062416758747872180395546164387827245287017031303859;\n uint256 constant C41 =\n 17438141672027706116733201008397064011774368832458707512367404736905021019585;\n uint256 constant C42 =\n 6374197807230665998865688675365359100400438034755781666913068586172586548950;\n uint256 constant C43 =\n 2189398913433273865510950346186699930188746169476472274335177556702504595264;\n uint256 constant C44 =\n 6268495580028970231803791523870131137294646402347399003576649137450213034606;\n uint256 constant C45 =\n 17896250365994900261202920044129628104272791547990619503076839618914047059275;\n uint256 constant C46 =\n 13692156312448722528008862371944543449350293305158722920787736248435893008873;\n uint256 constant C47 =\n 15234446864368744483209945022439268713300180233589581910497691316744177619376;\n uint256 constant C48 =\n 1572426502623310766593681563281600503979671244997798691029595521622402217227;\n uint256 constant C49 =\n 80103447810215150918585162168214870083573048458555897999822831203653996617;\n uint256 constant C50 =\n 8228820324013669567851850635126713973797711779951230446503353812192849106342;\n uint256 constant C51 =\n 5375851433746509614045812476958526065449377558695752132494533666370449415873;\n uint256 constant C52 =\n 12115998939203497346386774317892338270561208357481805380546938146796257365018;\n uint256 constant C53 =\n 9764067909645821279940531410531154041386008396840887338272986634350423466622;\n uint256 constant C54 =\n 8538708244538850542384936174629541085495830544298260335345008245230827876882;\n uint256 constant C55 =\n 7140127896620013355910287215441004676619168261422440177712039790284719613114;\n uint256 constant C56 =\n 14297402962228458726038826185823085337698917275385741292940049024977027409762;\n uint256 constant C57 =\n 6667115556431351074165934212337261254608231545257434281887966406956835140819;\n uint256 constant C58 =\n 20226761165244293291042617464655196752671169026542832236139342122602741090001;\n uint256 constant C59 =\n 12038289506489256655759141386763477208196694421666339040483042079632134429119;\n uint256 constant C60 =\n 19027757334170818571203982241812412991528769934917288000224335655934473717551;\n uint256 constant C61 =\n 16272152964456553579565580463468069884359929612321610357528838696790370074720;\n uint256 constant C62 =\n 2500392889689246014710135696485946334448570271481948765283016105301740284071;\n uint256 constant C63 =\n 8595254970528530312401637448610398388203855633951264114100575485022581946023;\n uint256 constant C64 =\n 11635945688914011450976408058407206367914559009113158286982919675551688078198;\n uint256 constant C65 =\n 614739068603482619581328040478536306925147663946742687395148680260956671871;\n uint256 constant C66 =\n 18692271780377861570175282183255720350972693125537599213951106550953176268753;\n uint256 constant C67 =\n 4987059230784976306647166378298632695585915319042844495357753339378260807164;\n uint256 constant C68 =\n 21851403978498723616722415377430107676258664746210815234490134600998983955497;\n uint256 constant C69 =\n 9830635451186415300891533983087800047564037813328875992115573428596207326204;\n uint256 constant C70 =\n 4842706106434537116860242620706030229206345167233200482994958847436425185478;\n uint256 constant C71 =\n 6422235064906823218421386871122109085799298052314922856340127798647926126490;\n uint256 constant C72 =\n 4564364104986856861943331689105797031330091877115997069096365671501473357846;\n uint256 constant C73 =\n 1944043894089780613038197112872830569538541856657037469098448708685350671343;\n uint256 constant C74 =\n 21179865974855950600518216085229498748425990426231530451599322283119880194955;\n uint256 constant C75 =\n 14296697761894107574369608843560006996183955751502547883167824879840894933162;\n uint256 constant C76 =\n 12274619649702218570450581712439138337725246879938860735460378251639845671898;\n uint256 constant C77 =\n 16371396450276899401411886674029075408418848209575273031725505038938314070356;\n uint256 constant C78 =\n 3702561221750983937578095019779188631407216522704543451228773892695044653565;\n uint256 constant C79 =\n 19721616877735564664624984774636557499099875603996426215495516594530838681980;\n uint256 constant C80 =\n 6383350109027696789969911008057747025018308755462287526819231672217685282429;\n uint256 constant C81 =\n 20860583956177367265984596617324237471765572961978977333122281041544719622905;\n uint256 constant C82 =\n 5766390934595026947545001478457407504285452477687752470140790011329357286275;\n uint256 constant C83 =\n 4043175758319898049344746138515323336207420888499903387536875603879441092484;\n uint256 constant C84 =\n 15579382179133608217098622223834161692266188678101563820988612253342538956534;\n uint256 constant C85 =\n 1864640783252634743892105383926602930909039567065240010338908865509831749824;\n uint256 constant C86 =\n 15943719865023133586707144161652035291705809358178262514871056013754142625673;\n uint256 constant C87 =\n 2326415993032390211558498780803238091925402878871059708106213703504162832999;\n uint256 constant C88 =\n 19995326402773833553207196590622808505547443523750970375738981396588337910289;\n uint256 constant C89 =\n 5143583711361588952673350526320181330406047695593201009385718506918735286622;\n uint256 constant C90 =\n 15436006486881920976813738625999473183944244531070780793506388892313517319583;\n uint256 constant C91 =\n 16660446760173633166698660166238066533278664023818938868110282615200613695857;\n uint256 constant C92 =\n 4966065365695755376133119391352131079892396024584848298231004326013366253934;\n uint256 constant C93 =\n 20683781957411705574951987677641476019618457561419278856689645563561076926702;\n uint256 constant C94 =\n 17280836839165902792086432296371645107551519324565649849400948918605456875699;\n uint256 constant C95 =\n 17045635513701208892073056357048619435743564064921155892004135325530808465371;\n uint256 constant C96 =\n 17055032967194400710390142791334572297458033582458169295920670679093585707295;\n uint256 constant C97 =\n 15727174639569115300068198908071514334002742825679221638729902577962862163505;\n uint256 constant C98 =\n 1001755657610446661315902885492677747789366510875120894840818704741370398633;\n uint256 constant C99 =\n 18638547332826171619311285502376343504539399518545103511265465604926625041234;\n uint256 constant C100 =\n 6751954224763196429755298529194402870632445298969935050224267844020826420799;\n uint256 constant C101 =\n 3526747115904224771452549517614107688674036840088422555827581348280834879405;\n uint256 constant C102 =\n 15705897908180497062880001271426561999724005008972544196300715293701537574122;\n uint256 constant C103 =\n 574386695213920937259007343820417029802510752426579750428758189312416867750;\n uint256 constant C104 =\n 15973040855000600860816974646787367136127946402908768408978806375685439868553;\n uint256 constant C105 =\n 20934130413948796333037139460875996342810005558806621330680156931816867321122;\n uint256 constant C106 =\n 6918585327145564636398173845411579411526758237572034236476079610890705810764;\n uint256 constant C107 =\n 14158163500813182062258176233162498241310167509137716527054939926126453647182;\n uint256 constant C108 =\n 4164602626597695668474100217150111342272610479949122406544277384862187287433;\n uint256 constant C109 =\n 12146526846507496913615390662823936206892812880963914267275606265272996025304;\n uint256 constant C110 =\n 10153527926900017763244212043512822363696541810586522108597162891799345289938;\n uint256 constant C111 =\n 13564663485965299104296214940873270349072051793008946663855767889066202733588;\n uint256 constant C112 =\n 5612449256997576125867742696783020582952387615430650198777254717398552960096;\n uint256 constant C113 =\n 12151885480032032868507892738683067544172874895736290365318623681886999930120;\n uint256 constant C114 =\n 380452237704664384810613424095477896605414037288009963200982915188629772177;\n uint256 constant C115 =\n 9067557551252570188533509616805287919563636482030947363841198066124642069518;\n uint256 constant C116 =\n 21280306817619711661335268484199763923870315733198162896599997188206277056900;\n uint256 constant C117 =\n 5567165819557297006750252582140767993422097822227408837378089569369734876257;\n uint256 constant C118 =\n 10411936321072105429908396649383171465939606386380071222095155850987201580137;\n uint256 constant C119 =\n 21338390051413922944780864872652000187403217966653363270851298678606449622266;\n uint256 constant C120 =\n 12156296560457833712186127325312904760045212412680904475497938949653569234473;\n uint256 constant C121 =\n 4271647814574748734312113971565139132510281260328947438246615707172526380757;\n uint256 constant C122 =\n 9061738206062369647211128232833114177054715885442782773131292534862178874950;\n uint256 constant C123 =\n 10134551893627587797380445583959894183158393780166496661696555422178052339133;\n uint256 constant C124 =\n 8932270237664043612366044102088319242789325050842783721780970129656616386103;\n uint256 constant C125 =\n 3339412934966886386194449782756711637636784424032779155216609410591712750636;\n uint256 constant C126 =\n 9704903972004596791086522314847373103670545861209569267884026709445485704400;\n uint256 constant C127 =\n 17467570179597572575614276429760169990940929887711661192333523245667228809456;\n uint256 constant M00 =\n 2910766817845651019878574839501801340070030115151021261302834310722729507541;\n uint256 constant M01 =\n 19727366863391167538122140361473584127147630672623100827934084310230022599144;\n uint256 constant M10 =\n 5776684794125549462448597414050232243778680302179439492664047328281728356345;\n uint256 constant M11 =\n 8348174920934122550483593999453880006756108121341067172388445916328941978568;\n\n function hash(\n uint256 input\n ) external pure override returns (uint256 result) {\n return _hash(input);\n }\n\n function _hash(uint256 input) internal pure returns (uint256 result) {\n assembly {\n // Poseidon parameters should be t = 2, RF = 8, RP = 56\n\n // We load the characteristic\n let q := Q\n\n // In zerokit implementation, if we pass inp = [a0,a1,..,an] to Poseidon what is effectively hashed is [0,a0,a1,..,an]\n // Note that a sequence of MIX-ARK involves 3 Bn254 field additions before the mulmod happens. Worst case we have a value corresponding to 2*(p-1) which is less than 2^256 and hence doesn't overflow\n //ROUND 0 - FULL\n let s0 := C0\n let s1 := add(input, C1)\n // SBOX\n let t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 1 - FULL\n s0 := add(s0, C2)\n s1 := add(s1, C3)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 2 - FULL\n s0 := add(s0, C4)\n s1 := add(s1, C5)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 3 - FULL\n s0 := add(s0, C6)\n s1 := add(s1, C7)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 4 - PARTIAL\n s0 := add(s0, C8)\n s1 := add(s1, C9)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 5 - PARTIAL\n s0 := add(s0, C10)\n s1 := add(s1, C11)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 6 - PARTIAL\n s0 := add(s0, C12)\n s1 := add(s1, C13)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 7 - PARTIAL\n s0 := add(s0, C14)\n s1 := add(s1, C15)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 8 - PARTIAL\n s0 := add(s0, C16)\n s1 := add(s1, C17)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 9 - PARTIAL\n s0 := add(s0, C18)\n s1 := add(s1, C19)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 10 - PARTIAL\n s0 := add(s0, C20)\n s1 := add(s1, C21)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 11 - PARTIAL\n s0 := add(s0, C22)\n s1 := add(s1, C23)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 12 - PARTIAL\n s0 := add(s0, C24)\n s1 := add(s1, C25)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 13 - PARTIAL\n s0 := add(s0, C26)\n s1 := add(s1, C27)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 14 - PARTIAL\n s0 := add(s0, C28)\n s1 := add(s1, C29)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 15 - PARTIAL\n s0 := add(s0, C30)\n s1 := add(s1, C31)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 16 - PARTIAL\n s0 := add(s0, C32)\n s1 := add(s1, C33)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 17 - PARTIAL\n s0 := add(s0, C34)\n s1 := add(s1, C35)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 18 - PARTIAL\n s0 := add(s0, C36)\n s1 := add(s1, C37)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 19 - PARTIAL\n s0 := add(s0, C38)\n s1 := add(s1, C39)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 20 - PARTIAL\n s0 := add(s0, C40)\n s1 := add(s1, C41)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 21 - PARTIAL\n s0 := add(s0, C42)\n s1 := add(s1, C43)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 22 - PARTIAL\n s0 := add(s0, C44)\n s1 := add(s1, C45)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 23 - PARTIAL\n s0 := add(s0, C46)\n s1 := add(s1, C47)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 24 - PARTIAL\n s0 := add(s0, C48)\n s1 := add(s1, C49)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 25 - PARTIAL\n s0 := add(s0, C50)\n s1 := add(s1, C51)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 26 - PARTIAL\n s0 := add(s0, C52)\n s1 := add(s1, C53)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 27 - PARTIAL\n s0 := add(s0, C54)\n s1 := add(s1, C55)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 28 - PARTIAL\n s0 := add(s0, C56)\n s1 := add(s1, C57)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 29 - PARTIAL\n s0 := add(s0, C58)\n s1 := add(s1, C59)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 30 - PARTIAL\n s0 := add(s0, C60)\n s1 := add(s1, C61)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 31 - PARTIAL\n s0 := add(s0, C62)\n s1 := add(s1, C63)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 32 - PARTIAL\n s0 := add(s0, C64)\n s1 := add(s1, C65)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 33 - PARTIAL\n s0 := add(s0, C66)\n s1 := add(s1, C67)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 34 - PARTIAL\n s0 := add(s0, C68)\n s1 := add(s1, C69)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 35 - PARTIAL\n s0 := add(s0, C70)\n s1 := add(s1, C71)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 36 - PARTIAL\n s0 := add(s0, C72)\n s1 := add(s1, C73)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 37 - PARTIAL\n s0 := add(s0, C74)\n s1 := add(s1, C75)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 38 - PARTIAL\n s0 := add(s0, C76)\n s1 := add(s1, C77)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 39 - PARTIAL\n s0 := add(s0, C78)\n s1 := add(s1, C79)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 40 - PARTIAL\n s0 := add(s0, C80)\n s1 := add(s1, C81)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 41 - PARTIAL\n s0 := add(s0, C82)\n s1 := add(s1, C83)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 42 - PARTIAL\n s0 := add(s0, C84)\n s1 := add(s1, C85)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 43 - PARTIAL\n s0 := add(s0, C86)\n s1 := add(s1, C87)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 44 - PARTIAL\n s0 := add(s0, C88)\n s1 := add(s1, C89)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 45 - PARTIAL\n s0 := add(s0, C90)\n s1 := add(s1, C91)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 46 - PARTIAL\n s0 := add(s0, C92)\n s1 := add(s1, C93)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 47 - PARTIAL\n s0 := add(s0, C94)\n s1 := add(s1, C95)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 48 - PARTIAL\n s0 := add(s0, C96)\n s1 := add(s1, C97)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 49 - PARTIAL\n s0 := add(s0, C98)\n s1 := add(s1, C99)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 50 - PARTIAL\n s0 := add(s0, C100)\n s1 := add(s1, C101)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 51 - PARTIAL\n s0 := add(s0, C102)\n s1 := add(s1, C103)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 52 - PARTIAL\n s0 := add(s0, C104)\n s1 := add(s1, C105)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 53 - PARTIAL\n s0 := add(s0, C106)\n s1 := add(s1, C107)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 54 - PARTIAL\n s0 := add(s0, C108)\n s1 := add(s1, C109)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 55 - PARTIAL\n s0 := add(s0, C110)\n s1 := add(s1, C111)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 56 - PARTIAL\n s0 := add(s0, C112)\n s1 := add(s1, C113)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 57 - PARTIAL\n s0 := add(s0, C114)\n s1 := add(s1, C115)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 58 - PARTIAL\n s0 := add(s0, C116)\n s1 := add(s1, C117)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 59 - PARTIAL\n s0 := add(s0, C118)\n s1 := add(s1, C119)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 60 - FULL\n s0 := add(s0, C120)\n s1 := add(s1, C121)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 61 - FULL\n s0 := add(s0, C122)\n s1 := add(s1, C123)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 62 - FULL\n s0 := add(s0, C124)\n s1 := add(s1, C125)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 63 - FULL\n s0 := add(s0, C126)\n s1 := add(s1, C127)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n s0 := mod(add(mulmod(s0, M00, q), mulmod(s1, M01, q)), q)\n\n result := s0\n }\n }\n}\n" - }, - "contracts/Rln.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.15;\n\nimport {IPoseidonHasher} from \"./PoseidonHasher.sol\";\nimport {IVerifier} from \"./IVerifier.sol\";\n\n/// The tree is full\nerror FullTree();\n\n/// Invalid deposit amount\n/// @param required The required deposit amount\n/// @param provided The provided deposit amount\nerror InsufficientDeposit(uint256 required, uint256 provided);\n\n/// Member is already registered\nerror DuplicateIdCommitment();\n\n/// Invalid receiver address, when the receiver is the contract itself or 0x0\nerror InvalidReceiverAddress(address to);\n\n/// Member is not registered\nerror MemberNotRegistered(uint256 idCommitment);\n\n/// Member has no stake\nerror MemberHasNoStake(uint256 idCommitment);\n\n/// User has insufficient balance to withdraw\nerror InsufficientWithdrawalBalance();\n\n/// Contract has insufficient balance to return\nerror InsufficientContractBalance();\n\n/// Invalid proof\nerror InvalidProof();\n\ncontract RLN {\n /// @notice The deposit amount required to register as a member\n uint256 public immutable MEMBERSHIP_DEPOSIT;\n\n /// @notice The depth of the merkle tree\n uint256 public immutable DEPTH;\n\n /// @notice The size of the merkle tree, i.e 2^depth\n uint256 public immutable SET_SIZE;\n\n /// @notice The index of the next member to be registered\n uint256 public idCommitmentIndex = 1;\n\n /// @notice The amount of eth staked by each member\n /// maps from idCommitment to the amount staked\n mapping(uint256 => uint256) public stakedAmounts;\n\n /// @notice The membership status of each member\n /// maps from idCommitment to their index in the set\n mapping(uint256 => uint256) public members;\n\n /// @notice The balance of each user that can be withdrawn\n mapping(address => uint256) public withdrawalBalance;\n\n /// @notice The Poseidon hasher contract\n IPoseidonHasher public immutable poseidonHasher;\n\n /// @notice The groth16 verifier contract\n IVerifier public immutable verifier;\n\n /// Emitted when a new member is added to the set\n /// @param idCommitment The idCommitment of the member\n /// @param index The index of the member in the set\n event MemberRegistered(uint256 idCommitment, uint256 index);\n\n /// Emitted when a member is removed from the set\n /// @param idCommitment The idCommitment of the member\n /// @param index The index of the member in the set\n event MemberWithdrawn(uint256 idCommitment, uint256 index);\n\n constructor(uint256 membershipDeposit, uint256 depth, address _poseidonHasher, address _verifier) {\n MEMBERSHIP_DEPOSIT = membershipDeposit;\n DEPTH = depth;\n SET_SIZE = 1 << depth;\n poseidonHasher = IPoseidonHasher(_poseidonHasher);\n verifier = IVerifier(_verifier);\n }\n\n /// Allows a user to register as a member\n /// @param idCommitment The idCommitment of the member\n function register(uint256 idCommitment) external payable {\n if (msg.value != MEMBERSHIP_DEPOSIT) {\n revert InsufficientDeposit(MEMBERSHIP_DEPOSIT, msg.value);\n }\n _register(idCommitment, msg.value);\n }\n\n /// Registers a member\n /// @param idCommitment The idCommitment of the member\n /// @param stake The amount of eth staked by the member\n function _register(uint256 idCommitment, uint256 stake) internal {\n if (members[idCommitment] != 0) revert DuplicateIdCommitment();\n if (idCommitmentIndex >= SET_SIZE) revert FullTree();\n\n members[idCommitment] = idCommitmentIndex;\n stakedAmounts[idCommitment] = stake;\n\n emit MemberRegistered(idCommitment, idCommitmentIndex);\n idCommitmentIndex += 1;\n }\n\n /// @dev Allows a user to slash a member\n /// @param idCommitment The idCommitment of the member\n function slash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof) external {\n _slash(idCommitment, receiver, proof);\n }\n\n /// @dev Slashes a member by removing them from the set, and adding their\n /// stake to the receiver's available withdrawal balance\n /// @param idCommitment The idCommitment of the member\n /// @param receiver The address to receive the funds\n function _slash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof) internal {\n if (receiver == address(this) || receiver == address(0)) {\n revert InvalidReceiverAddress(receiver);\n }\n\n if (members[idCommitment] == 0) revert MemberNotRegistered(idCommitment);\n // check if member is registered\n if (stakedAmounts[idCommitment] == 0) {\n revert MemberHasNoStake(idCommitment);\n }\n\n if (!_verifyProof(idCommitment, receiver, proof)) {\n revert InvalidProof();\n }\n\n uint256 amountToTransfer = stakedAmounts[idCommitment];\n\n // delete member\n uint256 index = members[idCommitment];\n members[idCommitment] = 0;\n stakedAmounts[idCommitment] = 0;\n\n // refund deposit\n withdrawalBalance[receiver] += amountToTransfer;\n\n emit MemberWithdrawn(idCommitment, index);\n }\n\n /// Allows a user to withdraw funds allocated to them upon slashing a member\n function withdraw() external {\n uint256 amount = withdrawalBalance[msg.sender];\n\n if (amount == 0) revert InsufficientWithdrawalBalance();\n if (amount > address(this).balance) {\n revert InsufficientContractBalance();\n }\n\n withdrawalBalance[msg.sender] = 0;\n\n payable(msg.sender).transfer(amount);\n }\n\n /// Hashes a value using the Poseidon hasher\n /// NOTE: The variant of Poseidon we use accepts only 1 input, assume n=2, and the second input is 0\n /// @param input The value to hash\n function hash(uint256 input) internal view returns (uint256) {\n return poseidonHasher.hash(input);\n }\n\n /// @dev Groth16 proof verification\n function _verifyProof(uint256 idCommitment, address receiver, uint256[8] calldata proof)\n internal\n view\n returns (bool)\n {\n return verifier.verifyProof(\n [proof[0], proof[1]],\n [[proof[2], proof[3]], [proof[4], proof[5]]],\n [proof[6], proof[7]],\n [idCommitment, uint256(uint160(receiver))]\n );\n }\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": false, - "runs": 200 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "devdoc", - "userdoc", - "storageLayout", - "evm.gasEstimates" - ], - "": ["ast"] - } - }, - "metadata": { - "useLiteralContent": true - }, - "remappings": [ - "ds-test/=lib/forge-std/lib/ds-test/src/", - "forge-std/=lib/forge-std/src/" - ] - } -} diff --git a/deployments/sepolia/solcInputs/3d22925ef26b2c95bb2dc86b2f9e06ed.json b/deployments/sepolia/solcInputs/3d22925ef26b2c95bb2dc86b2f9e06ed.json deleted file mode 100644 index 68781d3..0000000 --- a/deployments/sepolia/solcInputs/3d22925ef26b2c95bb2dc86b2f9e06ed.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/PoseidonHasher.sol": { - "content": "// SPDX-License-Identifier: MIT\n\n// Forked from https://github.com/kilic/rlnapp/\n\npragma solidity 0.8.15;\n\ninterface IPoseidonHasher {\n function hash(uint256 input) external pure returns (uint256 result);\n\n function identity() external pure returns (uint256);\n}\n\ncontract PoseidonHasher is IPoseidonHasher {\n uint256 constant Q =\n 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n uint256 constant C0 =\n 4417881134626180770308697923359573201005643519861877412381846989312604493735;\n uint256 constant C1 =\n 5433650512959517612316327474713065966758808864213826738576266661723522780033;\n uint256 constant C2 =\n 13641176377184356099764086973022553863760045607496549923679278773208775739952;\n uint256 constant C3 =\n 17949713444224994136330421782109149544629237834775211751417461773584374506783;\n uint256 constant C4 =\n 13765628375339178273710281891027109699578766420463125835325926111705201856003;\n uint256 constant C5 =\n 19179513468172002314585757290678967643352171735526887944518845346318719730387;\n uint256 constant C6 =\n 5157412437176756884543472904098424903141745259452875378101256928559722612176;\n uint256 constant C7 =\n 535160875740282236955320458485730000677124519901643397458212725410971557409;\n uint256 constant C8 =\n 1050793453380762984940163090920066886770841063557081906093018330633089036729;\n uint256 constant C9 =\n 10665495010329663932664894101216428400933984666065399374198502106997623173873;\n uint256 constant C10 =\n 19965634623406616956648724894636666805991993496469370618546874926025059150737;\n uint256 constant C11 =\n 13007250030070838431593222885902415182312449212965120303174723305710127422213;\n uint256 constant C12 =\n 16877538715074991604507979123743768693428157847423939051086744213162455276374;\n uint256 constant C13 =\n 18211747749504876135588847560312685184956239426147543810126553367063157141465;\n uint256 constant C14 =\n 18151553319826126919739798892854572062191241985315767086020821632812331245635;\n uint256 constant C15 =\n 19957033149976712666746140949846950406660099037474791840946955175819555930825;\n uint256 constant C16 =\n 3469514863538261843186854830917934449567467100548474599735384052339577040841;\n uint256 constant C17 =\n 989698510043911779243192466312362856042600749099921773896924315611668507708;\n uint256 constant C18 =\n 12568377015646290945235387813564567111330046038050864455358059568128000172201;\n uint256 constant C19 =\n 20856104135605479600325529349246932565148587186338606236677138505306779314172;\n uint256 constant C20 =\n 8206918720503535523121349917159924938835810381723474192155637697065780938424;\n uint256 constant C21 =\n 1309058477013932989380617265069188723120054926187607548493110334522527703566;\n uint256 constant C22 =\n 14076116939332667074621703729512195584105250395163383769419390236426287710606;\n uint256 constant C23 =\n 10153498892749751942204288991871286290442690932856658983589258153608012428674;\n uint256 constant C24 =\n 18202499207234128286137597834010475797175973146805180988367589376893530181575;\n uint256 constant C25 =\n 12739388830157083522877690211447248168864006284243907142044329113461613743052;\n uint256 constant C26 =\n 15123358710467780770838026754240340042441262572309759635224051333176022613949;\n uint256 constant C27 =\n 19925004701844594370904593774447343836015483888496504201331110250494635362184;\n uint256 constant C28 =\n 10352416606816998476681131583320899030072315953910679608943150613208329645891;\n uint256 constant C29 =\n 10567371822366244361703342347428230537114808440249611395507235283708966113221;\n uint256 constant C30 =\n 5635498582763880627392290206431559361272660937399944184533035305989295959602;\n uint256 constant C31 =\n 11866432933224219174041051738704352719163271639958083608224676028593315904909;\n uint256 constant C32 =\n 5795020705294401441272215064554385591292330721703923167136157291459784140431;\n uint256 constant C33 =\n 9482202378699252817564375087302794636287866584767523335624368774856230692758;\n uint256 constant C34 =\n 4245237636894546151746468406560945873445548423466753843402086544922216329298;\n uint256 constant C35 =\n 12000500941313982757584712677991730019124834399479314697467598397927435905133;\n uint256 constant C36 =\n 7596790274058425558167520209857956363736666939016807569082239187494363541787;\n uint256 constant C37 =\n 2484867918246116343205467273440098378820186751202461278013576281097918148877;\n uint256 constant C38 =\n 18312645949449997391810445935615409295369169383463185688973803378104013950190;\n uint256 constant C39 =\n 15320686572748723004980855263301182130424010735782762814513954166519592552733;\n uint256 constant C40 =\n 12618438900597948888520621062416758747872180395546164387827245287017031303859;\n uint256 constant C41 =\n 17438141672027706116733201008397064011774368832458707512367404736905021019585;\n uint256 constant C42 =\n 6374197807230665998865688675365359100400438034755781666913068586172586548950;\n uint256 constant C43 =\n 2189398913433273865510950346186699930188746169476472274335177556702504595264;\n uint256 constant C44 =\n 6268495580028970231803791523870131137294646402347399003576649137450213034606;\n uint256 constant C45 =\n 17896250365994900261202920044129628104272791547990619503076839618914047059275;\n uint256 constant C46 =\n 13692156312448722528008862371944543449350293305158722920787736248435893008873;\n uint256 constant C47 =\n 15234446864368744483209945022439268713300180233589581910497691316744177619376;\n uint256 constant C48 =\n 1572426502623310766593681563281600503979671244997798691029595521622402217227;\n uint256 constant C49 =\n 80103447810215150918585162168214870083573048458555897999822831203653996617;\n uint256 constant C50 =\n 8228820324013669567851850635126713973797711779951230446503353812192849106342;\n uint256 constant C51 =\n 5375851433746509614045812476958526065449377558695752132494533666370449415873;\n uint256 constant C52 =\n 12115998939203497346386774317892338270561208357481805380546938146796257365018;\n uint256 constant C53 =\n 9764067909645821279940531410531154041386008396840887338272986634350423466622;\n uint256 constant C54 =\n 8538708244538850542384936174629541085495830544298260335345008245230827876882;\n uint256 constant C55 =\n 7140127896620013355910287215441004676619168261422440177712039790284719613114;\n uint256 constant C56 =\n 14297402962228458726038826185823085337698917275385741292940049024977027409762;\n uint256 constant C57 =\n 6667115556431351074165934212337261254608231545257434281887966406956835140819;\n uint256 constant C58 =\n 20226761165244293291042617464655196752671169026542832236139342122602741090001;\n uint256 constant C59 =\n 12038289506489256655759141386763477208196694421666339040483042079632134429119;\n uint256 constant C60 =\n 19027757334170818571203982241812412991528769934917288000224335655934473717551;\n uint256 constant C61 =\n 16272152964456553579565580463468069884359929612321610357528838696790370074720;\n uint256 constant C62 =\n 2500392889689246014710135696485946334448570271481948765283016105301740284071;\n uint256 constant C63 =\n 8595254970528530312401637448610398388203855633951264114100575485022581946023;\n uint256 constant C64 =\n 11635945688914011450976408058407206367914559009113158286982919675551688078198;\n uint256 constant C65 =\n 614739068603482619581328040478536306925147663946742687395148680260956671871;\n uint256 constant C66 =\n 18692271780377861570175282183255720350972693125537599213951106550953176268753;\n uint256 constant C67 =\n 4987059230784976306647166378298632695585915319042844495357753339378260807164;\n uint256 constant C68 =\n 21851403978498723616722415377430107676258664746210815234490134600998983955497;\n uint256 constant C69 =\n 9830635451186415300891533983087800047564037813328875992115573428596207326204;\n uint256 constant C70 =\n 4842706106434537116860242620706030229206345167233200482994958847436425185478;\n uint256 constant C71 =\n 6422235064906823218421386871122109085799298052314922856340127798647926126490;\n uint256 constant C72 =\n 4564364104986856861943331689105797031330091877115997069096365671501473357846;\n uint256 constant C73 =\n 1944043894089780613038197112872830569538541856657037469098448708685350671343;\n uint256 constant C74 =\n 21179865974855950600518216085229498748425990426231530451599322283119880194955;\n uint256 constant C75 =\n 14296697761894107574369608843560006996183955751502547883167824879840894933162;\n uint256 constant C76 =\n 12274619649702218570450581712439138337725246879938860735460378251639845671898;\n uint256 constant C77 =\n 16371396450276899401411886674029075408418848209575273031725505038938314070356;\n uint256 constant C78 =\n 3702561221750983937578095019779188631407216522704543451228773892695044653565;\n uint256 constant C79 =\n 19721616877735564664624984774636557499099875603996426215495516594530838681980;\n uint256 constant C80 =\n 6383350109027696789969911008057747025018308755462287526819231672217685282429;\n uint256 constant C81 =\n 20860583956177367265984596617324237471765572961978977333122281041544719622905;\n uint256 constant C82 =\n 5766390934595026947545001478457407504285452477687752470140790011329357286275;\n uint256 constant C83 =\n 4043175758319898049344746138515323336207420888499903387536875603879441092484;\n uint256 constant C84 =\n 15579382179133608217098622223834161692266188678101563820988612253342538956534;\n uint256 constant C85 =\n 1864640783252634743892105383926602930909039567065240010338908865509831749824;\n uint256 constant C86 =\n 15943719865023133586707144161652035291705809358178262514871056013754142625673;\n uint256 constant C87 =\n 2326415993032390211558498780803238091925402878871059708106213703504162832999;\n uint256 constant C88 =\n 19995326402773833553207196590622808505547443523750970375738981396588337910289;\n uint256 constant C89 =\n 5143583711361588952673350526320181330406047695593201009385718506918735286622;\n uint256 constant C90 =\n 15436006486881920976813738625999473183944244531070780793506388892313517319583;\n uint256 constant C91 =\n 16660446760173633166698660166238066533278664023818938868110282615200613695857;\n uint256 constant C92 =\n 4966065365695755376133119391352131079892396024584848298231004326013366253934;\n uint256 constant C93 =\n 20683781957411705574951987677641476019618457561419278856689645563561076926702;\n uint256 constant C94 =\n 17280836839165902792086432296371645107551519324565649849400948918605456875699;\n uint256 constant C95 =\n 17045635513701208892073056357048619435743564064921155892004135325530808465371;\n uint256 constant C96 =\n 17055032967194400710390142791334572297458033582458169295920670679093585707295;\n uint256 constant C97 =\n 15727174639569115300068198908071514334002742825679221638729902577962862163505;\n uint256 constant C98 =\n 1001755657610446661315902885492677747789366510875120894840818704741370398633;\n uint256 constant C99 =\n 18638547332826171619311285502376343504539399518545103511265465604926625041234;\n uint256 constant C100 =\n 6751954224763196429755298529194402870632445298969935050224267844020826420799;\n uint256 constant C101 =\n 3526747115904224771452549517614107688674036840088422555827581348280834879405;\n uint256 constant C102 =\n 15705897908180497062880001271426561999724005008972544196300715293701537574122;\n uint256 constant C103 =\n 574386695213920937259007343820417029802510752426579750428758189312416867750;\n uint256 constant C104 =\n 15973040855000600860816974646787367136127946402908768408978806375685439868553;\n uint256 constant C105 =\n 20934130413948796333037139460875996342810005558806621330680156931816867321122;\n uint256 constant C106 =\n 6918585327145564636398173845411579411526758237572034236476079610890705810764;\n uint256 constant C107 =\n 14158163500813182062258176233162498241310167509137716527054939926126453647182;\n uint256 constant C108 =\n 4164602626597695668474100217150111342272610479949122406544277384862187287433;\n uint256 constant C109 =\n 12146526846507496913615390662823936206892812880963914267275606265272996025304;\n uint256 constant C110 =\n 10153527926900017763244212043512822363696541810586522108597162891799345289938;\n uint256 constant C111 =\n 13564663485965299104296214940873270349072051793008946663855767889066202733588;\n uint256 constant C112 =\n 5612449256997576125867742696783020582952387615430650198777254717398552960096;\n uint256 constant C113 =\n 12151885480032032868507892738683067544172874895736290365318623681886999930120;\n uint256 constant C114 =\n 380452237704664384810613424095477896605414037288009963200982915188629772177;\n uint256 constant C115 =\n 9067557551252570188533509616805287919563636482030947363841198066124642069518;\n uint256 constant C116 =\n 21280306817619711661335268484199763923870315733198162896599997188206277056900;\n uint256 constant C117 =\n 5567165819557297006750252582140767993422097822227408837378089569369734876257;\n uint256 constant C118 =\n 10411936321072105429908396649383171465939606386380071222095155850987201580137;\n uint256 constant C119 =\n 21338390051413922944780864872652000187403217966653363270851298678606449622266;\n uint256 constant C120 =\n 12156296560457833712186127325312904760045212412680904475497938949653569234473;\n uint256 constant C121 =\n 4271647814574748734312113971565139132510281260328947438246615707172526380757;\n uint256 constant C122 =\n 9061738206062369647211128232833114177054715885442782773131292534862178874950;\n uint256 constant C123 =\n 10134551893627587797380445583959894183158393780166496661696555422178052339133;\n uint256 constant C124 =\n 8932270237664043612366044102088319242789325050842783721780970129656616386103;\n uint256 constant C125 =\n 3339412934966886386194449782756711637636784424032779155216609410591712750636;\n uint256 constant C126 =\n 9704903972004596791086522314847373103670545861209569267884026709445485704400;\n uint256 constant C127 =\n 17467570179597572575614276429760169990940929887711661192333523245667228809456;\n uint256 constant M00 =\n 2910766817845651019878574839501801340070030115151021261302834310722729507541;\n uint256 constant M01 =\n 19727366863391167538122140361473584127147630672623100827934084310230022599144;\n uint256 constant M10 =\n 5776684794125549462448597414050232243778680302179439492664047328281728356345;\n uint256 constant M11 =\n 8348174920934122550483593999453880006756108121341067172388445916328941978568;\n\n function hash(\n uint256 input\n ) external pure override returns (uint256 result) {\n return _hash(input);\n }\n\n function _hash(uint256 input) internal pure returns (uint256 result) {\n assembly {\n // Poseidon parameters should be t = 2, RF = 8, RP = 56\n\n // We load the characteristic\n let q := Q\n\n // In zerokit implementation, if we pass inp = [a0,a1,..,an] to Poseidon what is effectively hashed is [0,a0,a1,..,an]\n // Note that a sequence of MIX-ARK involves 3 Bn254 field additions before the mulmod happens. Worst case we have a value corresponding to 2*(p-1) which is less than 2^256 and hence doesn't overflow\n //ROUND 0 - FULL\n let s0 := C0\n let s1 := add(input, C1)\n // SBOX\n let t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 1 - FULL\n s0 := add(s0, C2)\n s1 := add(s1, C3)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 2 - FULL\n s0 := add(s0, C4)\n s1 := add(s1, C5)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 3 - FULL\n s0 := add(s0, C6)\n s1 := add(s1, C7)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 4 - PARTIAL\n s0 := add(s0, C8)\n s1 := add(s1, C9)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 5 - PARTIAL\n s0 := add(s0, C10)\n s1 := add(s1, C11)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 6 - PARTIAL\n s0 := add(s0, C12)\n s1 := add(s1, C13)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 7 - PARTIAL\n s0 := add(s0, C14)\n s1 := add(s1, C15)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 8 - PARTIAL\n s0 := add(s0, C16)\n s1 := add(s1, C17)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 9 - PARTIAL\n s0 := add(s0, C18)\n s1 := add(s1, C19)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 10 - PARTIAL\n s0 := add(s0, C20)\n s1 := add(s1, C21)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 11 - PARTIAL\n s0 := add(s0, C22)\n s1 := add(s1, C23)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 12 - PARTIAL\n s0 := add(s0, C24)\n s1 := add(s1, C25)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 13 - PARTIAL\n s0 := add(s0, C26)\n s1 := add(s1, C27)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 14 - PARTIAL\n s0 := add(s0, C28)\n s1 := add(s1, C29)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 15 - PARTIAL\n s0 := add(s0, C30)\n s1 := add(s1, C31)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 16 - PARTIAL\n s0 := add(s0, C32)\n s1 := add(s1, C33)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 17 - PARTIAL\n s0 := add(s0, C34)\n s1 := add(s1, C35)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 18 - PARTIAL\n s0 := add(s0, C36)\n s1 := add(s1, C37)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 19 - PARTIAL\n s0 := add(s0, C38)\n s1 := add(s1, C39)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 20 - PARTIAL\n s0 := add(s0, C40)\n s1 := add(s1, C41)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 21 - PARTIAL\n s0 := add(s0, C42)\n s1 := add(s1, C43)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 22 - PARTIAL\n s0 := add(s0, C44)\n s1 := add(s1, C45)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 23 - PARTIAL\n s0 := add(s0, C46)\n s1 := add(s1, C47)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 24 - PARTIAL\n s0 := add(s0, C48)\n s1 := add(s1, C49)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 25 - PARTIAL\n s0 := add(s0, C50)\n s1 := add(s1, C51)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 26 - PARTIAL\n s0 := add(s0, C52)\n s1 := add(s1, C53)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 27 - PARTIAL\n s0 := add(s0, C54)\n s1 := add(s1, C55)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 28 - PARTIAL\n s0 := add(s0, C56)\n s1 := add(s1, C57)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 29 - PARTIAL\n s0 := add(s0, C58)\n s1 := add(s1, C59)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 30 - PARTIAL\n s0 := add(s0, C60)\n s1 := add(s1, C61)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 31 - PARTIAL\n s0 := add(s0, C62)\n s1 := add(s1, C63)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 32 - PARTIAL\n s0 := add(s0, C64)\n s1 := add(s1, C65)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 33 - PARTIAL\n s0 := add(s0, C66)\n s1 := add(s1, C67)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 34 - PARTIAL\n s0 := add(s0, C68)\n s1 := add(s1, C69)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 35 - PARTIAL\n s0 := add(s0, C70)\n s1 := add(s1, C71)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 36 - PARTIAL\n s0 := add(s0, C72)\n s1 := add(s1, C73)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 37 - PARTIAL\n s0 := add(s0, C74)\n s1 := add(s1, C75)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 38 - PARTIAL\n s0 := add(s0, C76)\n s1 := add(s1, C77)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 39 - PARTIAL\n s0 := add(s0, C78)\n s1 := add(s1, C79)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 40 - PARTIAL\n s0 := add(s0, C80)\n s1 := add(s1, C81)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 41 - PARTIAL\n s0 := add(s0, C82)\n s1 := add(s1, C83)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 42 - PARTIAL\n s0 := add(s0, C84)\n s1 := add(s1, C85)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 43 - PARTIAL\n s0 := add(s0, C86)\n s1 := add(s1, C87)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 44 - PARTIAL\n s0 := add(s0, C88)\n s1 := add(s1, C89)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 45 - PARTIAL\n s0 := add(s0, C90)\n s1 := add(s1, C91)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 46 - PARTIAL\n s0 := add(s0, C92)\n s1 := add(s1, C93)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 47 - PARTIAL\n s0 := add(s0, C94)\n s1 := add(s1, C95)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 48 - PARTIAL\n s0 := add(s0, C96)\n s1 := add(s1, C97)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 49 - PARTIAL\n s0 := add(s0, C98)\n s1 := add(s1, C99)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 50 - PARTIAL\n s0 := add(s0, C100)\n s1 := add(s1, C101)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 51 - PARTIAL\n s0 := add(s0, C102)\n s1 := add(s1, C103)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 52 - PARTIAL\n s0 := add(s0, C104)\n s1 := add(s1, C105)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 53 - PARTIAL\n s0 := add(s0, C106)\n s1 := add(s1, C107)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 54 - PARTIAL\n s0 := add(s0, C108)\n s1 := add(s1, C109)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 55 - PARTIAL\n s0 := add(s0, C110)\n s1 := add(s1, C111)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 56 - PARTIAL\n s0 := add(s0, C112)\n s1 := add(s1, C113)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 57 - PARTIAL\n s0 := add(s0, C114)\n s1 := add(s1, C115)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 58 - PARTIAL\n s0 := add(s0, C116)\n s1 := add(s1, C117)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 59 - PARTIAL\n s0 := add(s0, C118)\n s1 := add(s1, C119)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 60 - FULL\n s0 := add(s0, C120)\n s1 := add(s1, C121)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 61 - FULL\n s0 := add(s0, C122)\n s1 := add(s1, C123)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 62 - FULL\n s0 := add(s0, C124)\n s1 := add(s1, C125)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 63 - FULL\n s0 := add(s0, C126)\n s1 := add(s1, C127)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n s0 := mod(add(mulmod(s0, M00, q), mulmod(s1, M01, q)), q)\n\n result := s0\n }\n }\n\n function identity() external pure override returns (uint256) {\n return _identity();\n }\n\n // The hash of 0\n function _identity() internal pure returns (uint256) {\n return\n 0x2a09a9fd93c590c26b91effbb2499f07e8f7aa12e2b4940a3aed2411cb65e11c;\n }\n}\n" - }, - "contracts/Rln.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.15;\n\nimport {IPoseidonHasher} from \"./PoseidonHasher.sol\";\n\ncontract RLN {\n uint256 public immutable MEMBERSHIP_DEPOSIT;\n uint256 public immutable DEPTH;\n uint256 public immutable SET_SIZE;\n\n uint256 public idCommitmentIndex;\n mapping(uint256 => uint256) public stakedAmounts;\n mapping(uint256 => bool) public members;\n\n IPoseidonHasher public poseidonHasher;\n\n event MemberRegistered(uint256 idCommitment, uint256 index);\n event MemberWithdrawn(uint256 idCommitment);\n\n constructor(\n uint256 membershipDeposit,\n uint256 depth,\n address _poseidonHasher\n ) {\n MEMBERSHIP_DEPOSIT = membershipDeposit;\n DEPTH = depth;\n SET_SIZE = 1 << depth;\n poseidonHasher = IPoseidonHasher(_poseidonHasher);\n }\n\n function register(uint256 idCommitment) external payable {\n require(\n msg.value == MEMBERSHIP_DEPOSIT,\n \"RLN, register: membership deposit is not satisfied\"\n );\n _register(idCommitment, msg.value);\n }\n\n function registerBatch(uint256[] calldata idCommitments) external payable {\n uint256 idCommitmentlen = idCommitments.length;\n require(\n idCommitmentIndex + idCommitmentlen <= SET_SIZE,\n \"RLN, registerBatch: set is full\"\n );\n require(\n msg.value == MEMBERSHIP_DEPOSIT * idCommitmentlen,\n \"RLN, registerBatch: membership deposit is not satisfied\"\n );\n for (uint256 i = 0; i < idCommitmentlen; i++) {\n _register(idCommitments[i], msg.value / idCommitmentlen);\n }\n }\n\n function _register(uint256 idCommitment, uint256 stake) internal {\n require(\n !members[idCommitment],\n \"RLN, _register: member already registered\"\n );\n require(idCommitmentIndex < SET_SIZE, \"RLN, register: set is full\");\n if (stake != 0) {\n members[idCommitment] = true;\n stakedAmounts[idCommitment] = stake;\n } else {\n members[idCommitment] = true;\n stakedAmounts[idCommitment] = 0;\n }\n emit MemberRegistered(idCommitment, idCommitmentIndex);\n idCommitmentIndex += 1;\n }\n\n function withdrawBatch(\n uint256[] calldata secrets,\n address payable[] calldata receivers\n ) external {\n uint256 batchSize = secrets.length;\n require(batchSize != 0, \"RLN, withdrawBatch: batch size zero\");\n require(\n batchSize == secrets.length,\n \"RLN, withdrawBatch: batch size mismatch secrets\"\n );\n require(\n batchSize == receivers.length,\n \"RLN, withdrawBatch: batch size mismatch receivers\"\n );\n for (uint256 i = 0; i < batchSize; i++) {\n _withdraw(secrets[i], receivers[i]);\n }\n }\n\n function withdraw(uint256 secret, address payable receiver) external {\n _withdraw(secret, receiver);\n }\n\n function withdraw(uint256 secret) external {\n _withdraw(secret);\n }\n\n function _withdraw(uint256 secret, address payable receiver) internal {\n // derive idCommitment\n uint256 idCommitment = hash(secret);\n\n // check if member is registered\n require(members[idCommitment], \"RLN, _withdraw: member not registered\");\n\n // check if member has stake\n require(\n stakedAmounts[idCommitment] != 0,\n \"RLN, _withdraw: member has no stake\"\n );\n\n require(\n receiver != address(0),\n \"RLN, _withdraw: empty receiver address\"\n );\n\n // delete member\n members[idCommitment] = false;\n stakedAmounts[idCommitment] = 0;\n\n // refund deposit\n (bool sent, ) = receiver.call{value: stakedAmounts[idCommitment]}(\"\");\n require(sent, \"transfer failed\");\n\n emit MemberWithdrawn(idCommitment);\n }\n\n function _withdraw(uint256 secret) internal {\n // derive idCommitment\n uint256 idCommitment = hash(secret);\n\n // check if member is registered\n require(members[idCommitment], \"RLN, _withdraw: member not registered\");\n\n require(stakedAmounts[idCommitment] == 0, \"RLN, _withdraw: staked\");\n\n // delete member\n members[idCommitment] = false;\n\n emit MemberWithdrawn(idCommitment);\n }\n\n function hash(uint256 input) internal view returns (uint256) {\n return poseidonHasher.hash(input);\n }\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": false, - "runs": 200 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "devdoc", - "userdoc", - "storageLayout", - "evm.gasEstimates" - ], - "": ["ast"] - } - }, - "metadata": { - "useLiteralContent": true - }, - "remappings": [ - "ds-test/=lib/forge-std/lib/ds-test/src/", - "forge-std/=lib/forge-std/src/" - ] - } -} diff --git a/deployments/sepolia/solcInputs/3f87313134e2217cb187bd594084789f.json b/deployments/sepolia/solcInputs/3f87313134e2217cb187bd594084789f.json new file mode 100644 index 0000000..ad32495 --- /dev/null +++ b/deployments/sepolia/solcInputs/3f87313134e2217cb187bd594084789f.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "@zk-kit/imt.sol/BinaryIMT.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {PoseidonT3} from \"poseidon-solidity/PoseidonT3.sol\";\n\n// Each incremental tree has certain properties and data that will\n// be used to add new leaves.\nstruct BinaryIMTData {\n uint256 depth; // Depth of the tree (levels - 1).\n uint256 root; // Root hash of the tree.\n uint256 numberOfLeaves; // Number of leaves of the tree.\n mapping(uint256 => uint256) zeroes; // Zero hashes used for empty nodes (level -> zero hash).\n // The nodes of the subtrees used in the last addition of a leaf (level -> [left node, right node]).\n mapping(uint256 => uint256[2]) lastSubtrees; // Caching these values is essential to efficient appends.\n bool useDefaultZeroes;\n}\n\n/// @title Incremental binary Merkle tree.\n/// @dev The incremental tree allows to calculate the root hash each time a leaf is added, ensuring\n/// the integrity of the tree.\nlibrary BinaryIMT {\n uint8 public constant MAX_DEPTH = 32;\n uint256 public constant SNARK_SCALAR_FIELD =\n 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n\n uint256 public constant Z_0 = 0;\n uint256 public constant Z_1 = 14744269619966411208579211824598458697587494354926760081771325075741142829156;\n uint256 public constant Z_2 = 7423237065226347324353380772367382631490014989348495481811164164159255474657;\n uint256 public constant Z_3 = 11286972368698509976183087595462810875513684078608517520839298933882497716792;\n uint256 public constant Z_4 = 3607627140608796879659380071776844901612302623152076817094415224584923813162;\n uint256 public constant Z_5 = 19712377064642672829441595136074946683621277828620209496774504837737984048981;\n uint256 public constant Z_6 = 20775607673010627194014556968476266066927294572720319469184847051418138353016;\n uint256 public constant Z_7 = 3396914609616007258851405644437304192397291162432396347162513310381425243293;\n uint256 public constant Z_8 = 21551820661461729022865262380882070649935529853313286572328683688269863701601;\n uint256 public constant Z_9 = 6573136701248752079028194407151022595060682063033565181951145966236778420039;\n uint256 public constant Z_10 = 12413880268183407374852357075976609371175688755676981206018884971008854919922;\n uint256 public constant Z_11 = 14271763308400718165336499097156975241954733520325982997864342600795471836726;\n uint256 public constant Z_12 = 20066985985293572387227381049700832219069292839614107140851619262827735677018;\n uint256 public constant Z_13 = 9394776414966240069580838672673694685292165040808226440647796406499139370960;\n uint256 public constant Z_14 = 11331146992410411304059858900317123658895005918277453009197229807340014528524;\n uint256 public constant Z_15 = 15819538789928229930262697811477882737253464456578333862691129291651619515538;\n uint256 public constant Z_16 = 19217088683336594659449020493828377907203207941212636669271704950158751593251;\n uint256 public constant Z_17 = 21035245323335827719745544373081896983162834604456827698288649288827293579666;\n uint256 public constant Z_18 = 6939770416153240137322503476966641397417391950902474480970945462551409848591;\n uint256 public constant Z_19 = 10941962436777715901943463195175331263348098796018438960955633645115732864202;\n uint256 public constant Z_20 = 15019797232609675441998260052101280400536945603062888308240081994073687793470;\n uint256 public constant Z_21 = 11702828337982203149177882813338547876343922920234831094975924378932809409969;\n uint256 public constant Z_22 = 11217067736778784455593535811108456786943573747466706329920902520905755780395;\n uint256 public constant Z_23 = 16072238744996205792852194127671441602062027943016727953216607508365787157389;\n uint256 public constant Z_24 = 17681057402012993898104192736393849603097507831571622013521167331642182653248;\n uint256 public constant Z_25 = 21694045479371014653083846597424257852691458318143380497809004364947786214945;\n uint256 public constant Z_26 = 8163447297445169709687354538480474434591144168767135863541048304198280615192;\n uint256 public constant Z_27 = 14081762237856300239452543304351251708585712948734528663957353575674639038357;\n uint256 public constant Z_28 = 16619959921569409661790279042024627172199214148318086837362003702249041851090;\n uint256 public constant Z_29 = 7022159125197495734384997711896547675021391130223237843255817587255104160365;\n uint256 public constant Z_30 = 4114686047564160449611603615418567457008101555090703535405891656262658644463;\n uint256 public constant Z_31 = 12549363297364877722388257367377629555213421373705596078299904496781819142130;\n uint256 public constant Z_32 = 21443572485391568159800782191812935835534334817699172242223315142338162256601;\n\n function defaultZero(uint256 index) public pure returns (uint256) {\n if (index == 0) return Z_0;\n if (index == 1) return Z_1;\n if (index == 2) return Z_2;\n if (index == 3) return Z_3;\n if (index == 4) return Z_4;\n if (index == 5) return Z_5;\n if (index == 6) return Z_6;\n if (index == 7) return Z_7;\n if (index == 8) return Z_8;\n if (index == 9) return Z_9;\n if (index == 10) return Z_10;\n if (index == 11) return Z_11;\n if (index == 12) return Z_12;\n if (index == 13) return Z_13;\n if (index == 14) return Z_14;\n if (index == 15) return Z_15;\n if (index == 16) return Z_16;\n if (index == 17) return Z_17;\n if (index == 18) return Z_18;\n if (index == 19) return Z_19;\n if (index == 20) return Z_20;\n if (index == 21) return Z_21;\n if (index == 22) return Z_22;\n if (index == 23) return Z_23;\n if (index == 24) return Z_24;\n if (index == 25) return Z_25;\n if (index == 26) return Z_26;\n if (index == 27) return Z_27;\n if (index == 28) return Z_28;\n if (index == 29) return Z_29;\n if (index == 30) return Z_30;\n if (index == 31) return Z_31;\n if (index == 32) return Z_32;\n revert(\"IncrementalBinaryTree: defaultZero bad index\");\n }\n\n /// @dev Initializes a tree.\n /// @param self: Tree data.\n /// @param depth: Depth of the tree.\n /// @param zero: Zero value to be used.\n function init(BinaryIMTData storage self, uint256 depth, uint256 zero) public {\n require(zero < SNARK_SCALAR_FIELD, \"BinaryIMT: leaf must be < SNARK_SCALAR_FIELD\");\n require(depth > 0 && depth <= MAX_DEPTH, \"BinaryIMT: tree depth must be between 1 and 32\");\n\n self.depth = depth;\n\n for (uint8 i = 0; i < depth; ) {\n self.zeroes[i] = zero;\n zero = PoseidonT3.hash([zero, zero]);\n\n unchecked {\n ++i;\n }\n }\n\n self.root = zero;\n }\n\n function initWithDefaultZeroes(BinaryIMTData storage self, uint256 depth) public {\n require(depth > 0 && depth <= MAX_DEPTH, \"BinaryIMT: tree depth must be between 1 and 32\");\n\n self.depth = depth;\n self.useDefaultZeroes = true;\n\n self.root = defaultZero(depth);\n }\n\n /// @dev Inserts a leaf in the tree.\n /// @param self: Tree data.\n /// @param leaf: Leaf to be inserted.\n function insert(BinaryIMTData storage self, uint256 leaf) public returns (uint256) {\n uint256 depth = self.depth;\n\n require(leaf < SNARK_SCALAR_FIELD, \"BinaryIMT: leaf must be < SNARK_SCALAR_FIELD\");\n require(self.numberOfLeaves < 2 ** depth, \"BinaryIMT: tree is full\");\n\n uint256 index = self.numberOfLeaves;\n uint256 hash = leaf;\n bool useDefaultZeroes = self.useDefaultZeroes;\n\n for (uint8 i = 0; i < depth; ) {\n if (index & 1 == 0) {\n self.lastSubtrees[i] = [hash, useDefaultZeroes ? defaultZero(i) : self.zeroes[i]];\n } else {\n self.lastSubtrees[i][1] = hash;\n }\n\n hash = PoseidonT3.hash(self.lastSubtrees[i]);\n index >>= 1;\n\n unchecked {\n ++i;\n }\n }\n\n self.root = hash;\n self.numberOfLeaves += 1;\n return hash;\n }\n\n /// @dev Updates a leaf in the tree.\n /// @param self: Tree data.\n /// @param leaf: Leaf to be updated.\n /// @param newLeaf: New leaf.\n /// @param proofSiblings: Array of the sibling nodes of the proof of membership.\n /// @param proofPathIndices: Path of the proof of membership.\n function update(\n BinaryIMTData storage self,\n uint256 leaf,\n uint256 newLeaf,\n uint256[] calldata proofSiblings,\n uint8[] calldata proofPathIndices\n ) public {\n require(newLeaf != leaf, \"BinaryIMT: new leaf cannot be the same as the old one\");\n require(newLeaf < SNARK_SCALAR_FIELD, \"BinaryIMT: new leaf must be < SNARK_SCALAR_FIELD\");\n require(verify(self, leaf, proofSiblings, proofPathIndices), \"BinaryIMT: leaf is not part of the tree\");\n\n uint256 depth = self.depth;\n uint256 hash = newLeaf;\n uint256 updateIndex;\n\n for (uint8 i = 0; i < depth; ) {\n updateIndex |= uint256(proofPathIndices[i]) << uint256(i);\n\n if (proofPathIndices[i] == 0) {\n if (proofSiblings[i] == self.lastSubtrees[i][1]) {\n self.lastSubtrees[i][0] = hash;\n }\n\n hash = PoseidonT3.hash([hash, proofSiblings[i]]);\n } else {\n if (proofSiblings[i] == self.lastSubtrees[i][0]) {\n self.lastSubtrees[i][1] = hash;\n }\n\n hash = PoseidonT3.hash([proofSiblings[i], hash]);\n }\n\n unchecked {\n ++i;\n }\n }\n require(updateIndex < self.numberOfLeaves, \"BinaryIMT: leaf index out of range\");\n\n self.root = hash;\n }\n\n /// @dev Removes a leaf from the tree.\n /// @param self: Tree data.\n /// @param leaf: Leaf to be removed.\n /// @param proofSiblings: Array of the sibling nodes of the proof of membership.\n /// @param proofPathIndices: Path of the proof of membership.\n function remove(\n BinaryIMTData storage self,\n uint256 leaf,\n uint256[] calldata proofSiblings,\n uint8[] calldata proofPathIndices\n ) public {\n update(self, leaf, self.useDefaultZeroes ? Z_0 : self.zeroes[0], proofSiblings, proofPathIndices);\n }\n\n /// @dev Verify if the path is correct and the leaf is part of the tree.\n /// @param self: Tree data.\n /// @param leaf: Leaf to be removed.\n /// @param proofSiblings: Array of the sibling nodes of the proof of membership.\n /// @param proofPathIndices: Path of the proof of membership.\n /// @return True or false.\n function verify(\n BinaryIMTData storage self,\n uint256 leaf,\n uint256[] calldata proofSiblings,\n uint8[] calldata proofPathIndices\n ) private view returns (bool) {\n require(leaf < SNARK_SCALAR_FIELD, \"BinaryIMT: leaf must be < SNARK_SCALAR_FIELD\");\n uint256 depth = self.depth;\n require(\n proofPathIndices.length == depth && proofSiblings.length == depth,\n \"BinaryIMT: length of path is not correct\"\n );\n\n uint256 hash = leaf;\n\n for (uint8 i = 0; i < depth; ) {\n require(proofSiblings[i] < SNARK_SCALAR_FIELD, \"BinaryIMT: sibling node must be < SNARK_SCALAR_FIELD\");\n\n require(proofPathIndices[i] == 1 || proofPathIndices[i] == 0, \"BinaryIMT: path index is neither 0 nor 1\");\n\n if (proofPathIndices[i] == 0) {\n hash = PoseidonT3.hash([hash, proofSiblings[i]]);\n } else {\n hash = PoseidonT3.hash([proofSiblings[i], hash]);\n }\n\n unchecked {\n ++i;\n }\n }\n\n return hash == self.root;\n }\n}\n" + }, + "contracts/IVerifier.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0 OR MIT\npragma solidity 0.8.15;\n\ninterface IVerifier {\n function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)\n external\n view\n returns (bool);\n}\n" + }, + "contracts/PoseidonHasher.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.15;\n\nimport {PoseidonT3} from \"poseidon-solidity/PoseidonT3.sol\";\n\ninterface IPoseidonHasher {\n /// @notice Hashes the input using the Poseidon hash function, n = 2\n /// @param inputs The input to hash\n function hash(uint256[2] memory inputs) external pure returns (uint256 result);\n}\n\ncontract PoseidonHasher is IPoseidonHasher {\n uint256 public constant Q = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n\n function hash(uint256[2] memory inputs) external pure override returns (uint256 result) {\n return PoseidonT3.hash(inputs);\n }\n}\n" + }, + "contracts/Rln.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport \"./RlnBase.sol\";\n\ncontract RLN is RlnBase {\n constructor(uint256 membershipDeposit, uint256 depth, address _poseidonHasher, address _verifier)\n RlnBase(membershipDeposit, depth, _poseidonHasher, _verifier)\n {}\n\n function _validateRegistration(uint256 idCommitment) internal pure override {}\n\n function _validateSlash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)\n internal\n pure\n override\n {}\n}\n" + }, + "contracts/RlnBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.15;\n\nimport {PoseidonHasher} from \"./PoseidonHasher.sol\";\nimport {IVerifier} from \"./IVerifier.sol\";\nimport {BinaryIMT, BinaryIMTData} from \"@zk-kit/imt.sol/BinaryIMT.sol\";\n\n/// The tree is full\nerror FullTree();\n\n/// Invalid deposit amount\n/// @param required The required deposit amount\n/// @param provided The provided deposit amount\nerror InsufficientDeposit(uint256 required, uint256 provided);\n\n/// Member is already registered\nerror DuplicateIdCommitment();\n\n/// Failed validation on registration/slashing\nerror FailedValidation();\n\n/// Invalid idCommitment\nerror InvalidIdCommitment(uint256 idCommitment);\n\n/// Invalid receiver address, when the receiver is the contract itself or 0x0\nerror InvalidReceiverAddress(address to);\n\n/// Member is not registered\nerror MemberNotRegistered(uint256 idCommitment);\n\n/// Member has no stake\nerror MemberHasNoStake(uint256 idCommitment);\n\n/// User has insufficient balance to withdraw\nerror InsufficientWithdrawalBalance();\n\n/// Contract has insufficient balance to return\nerror InsufficientContractBalance();\n\n/// Invalid proof\nerror InvalidProof();\n\nabstract contract RlnBase {\n /// @notice The deposit amount required to register as a member\n uint256 public immutable MEMBERSHIP_DEPOSIT;\n\n /// @notice The depth of the merkle tree\n uint256 public immutable DEPTH;\n\n /// @notice The size of the merkle tree, i.e 2^depth\n uint256 public immutable SET_SIZE;\n\n /// @notice The index of the next member to be registered\n uint256 public idCommitmentIndex = 0;\n\n /// @notice The amount of eth staked by each member\n /// maps from idCommitment to the amount staked\n mapping(uint256 => uint256) public stakedAmounts;\n\n /// @notice The membership status of each member\n /// maps from idCommitment to their index in the set\n mapping(uint256 => uint256) public members;\n\n /// @notice The membership status of each member\n mapping(uint256 => bool) public memberExists;\n\n /// @notice The balance of each user that can be withdrawn\n mapping(address => uint256) public withdrawalBalance;\n\n /// @notice The Poseidon hasher contract\n PoseidonHasher public immutable poseidonHasher;\n\n /// @notice The groth16 verifier contract\n IVerifier public immutable verifier;\n\n /// @notice the deployed block number\n uint32 public immutable deployedBlockNumber;\n\n /// @notice the Incremental Merkle Tree\n BinaryIMTData public imtData;\n\n /// Emitted when a new member is added to the set\n /// @param idCommitment The idCommitment of the member\n /// @param index The index of the member in the set\n event MemberRegistered(uint256 idCommitment, uint256 index);\n\n /// Emitted when a member is removed from the set\n /// @param idCommitment The idCommitment of the member\n /// @param index The index of the member in the set\n event MemberWithdrawn(uint256 idCommitment, uint256 index);\n\n modifier onlyValidIdCommitment(uint256 idCommitment) {\n if (!isValidCommitment(idCommitment)) revert InvalidIdCommitment(idCommitment);\n _;\n }\n\n constructor(uint256 membershipDeposit, uint256 depth, address _poseidonHasher, address _verifier) {\n MEMBERSHIP_DEPOSIT = membershipDeposit;\n DEPTH = depth;\n SET_SIZE = 1 << depth;\n poseidonHasher = PoseidonHasher(_poseidonHasher);\n verifier = IVerifier(_verifier);\n deployedBlockNumber = uint32(block.number);\n BinaryIMT.initWithDefaultZeroes(imtData, 20);\n }\n\n /// Allows a user to register as a member\n /// @param idCommitment The idCommitment of the member\n function register(uint256 idCommitment) external payable virtual onlyValidIdCommitment(idCommitment) {\n if (msg.value != MEMBERSHIP_DEPOSIT) {\n revert InsufficientDeposit(MEMBERSHIP_DEPOSIT, msg.value);\n }\n _validateRegistration(idCommitment);\n _register(idCommitment, msg.value);\n }\n\n /// Registers a member\n /// @param idCommitment The idCommitment of the member\n /// @param stake The amount of eth staked by the member\n function _register(uint256 idCommitment, uint256 stake) internal virtual {\n if (memberExists[idCommitment]) revert DuplicateIdCommitment();\n if (idCommitmentIndex >= SET_SIZE) revert FullTree();\n\n members[idCommitment] = idCommitmentIndex;\n memberExists[idCommitment] = true;\n BinaryIMT.insert(imtData, idCommitment);\n stakedAmounts[idCommitment] = stake;\n\n emit MemberRegistered(idCommitment, idCommitmentIndex);\n idCommitmentIndex += 1;\n }\n\n /// @dev Inheriting contracts MUST override this function\n function _validateRegistration(uint256 idCommitment) internal view virtual;\n\n /// @dev Allows a user to slash a member\n /// @param idCommitment The idCommitment of the member\n function slash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)\n external\n virtual\n onlyValidIdCommitment(idCommitment)\n {\n _validateSlash(idCommitment, receiver, proof);\n _slash(idCommitment, receiver, proof);\n }\n\n /// @dev Slashes a member by removing them from the set, and adding their\n /// stake to the receiver's available withdrawal balance\n /// @param idCommitment The idCommitment of the member\n /// @param receiver The address to receive the funds\n function _slash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof) internal virtual {\n if (receiver == address(this) || receiver == address(0)) {\n revert InvalidReceiverAddress(receiver);\n }\n\n if (memberExists[idCommitment] == false) revert MemberNotRegistered(idCommitment);\n // check if member is registered\n if (stakedAmounts[idCommitment] == 0) {\n revert MemberHasNoStake(idCommitment);\n }\n\n if (!_verifyProof(idCommitment, receiver, proof)) {\n revert InvalidProof();\n }\n\n uint256 amountToTransfer = stakedAmounts[idCommitment];\n\n // delete member\n uint256 index = members[idCommitment];\n members[idCommitment] = 0;\n memberExists[idCommitment] = false;\n stakedAmounts[idCommitment] = 0;\n // TODO: remove from IMT\n\n // refund deposit\n withdrawalBalance[receiver] += amountToTransfer;\n\n emit MemberWithdrawn(idCommitment, index);\n }\n\n function _validateSlash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)\n internal\n view\n virtual;\n\n /// Allows a user to withdraw funds allocated to them upon slashing a member\n function withdraw() external virtual {\n uint256 amount = withdrawalBalance[msg.sender];\n\n if (amount == 0) revert InsufficientWithdrawalBalance();\n if (amount > address(this).balance) {\n revert InsufficientContractBalance();\n }\n\n withdrawalBalance[msg.sender] = 0;\n\n payable(msg.sender).transfer(amount);\n }\n\n /// Hashes a value using the Poseidon hasher\n /// NOTE: The variant of Poseidon we use accepts only 1 input, assume n=2\n /// @param inputs The values to hash\n function hash(uint256[2] memory inputs) internal view returns (uint256) {\n return poseidonHasher.hash(inputs);\n }\n\n function isValidCommitment(uint256 idCommitment) public view returns (bool) {\n return idCommitment != 0 && idCommitment < poseidonHasher.Q();\n }\n\n /// @dev Groth16 proof verification\n function _verifyProof(uint256 idCommitment, address receiver, uint256[8] calldata proof)\n internal\n view\n virtual\n returns (bool)\n {\n return verifier.verifyProof(\n [proof[0], proof[1]],\n [[proof[2], proof[3]], [proof[4], proof[5]]],\n [proof[6], proof[7]],\n [idCommitment, uint256(uint160(receiver))]\n );\n }\n\n function computeRoot() external view returns (uint256) {\n return imtData.root;\n }\n}\n" + }, + "poseidon-solidity/PoseidonT3.sol": { + "content": "/// SPDX-License-Identifier: MIT\npragma solidity >=0.7.0;\n\nlibrary PoseidonT3 {\n uint constant M00 = 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b;\n uint constant M01 = 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771;\n uint constant M02 = 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7;\n uint constant M10 = 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0;\n uint constant M11 = 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23;\n uint constant M12 = 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911;\n\n // See here for a simplified implementation: https://github.com/vimwitch/poseidon-solidity/blob/e57becdabb65d99fdc586fe1e1e09e7108202d53/contracts/Poseidon.sol#L40\n // Inspired by: https://github.com/iden3/circomlibjs/blob/v0.0.8/src/poseidon_slow.js\n function hash(uint[2] memory) public pure returns (uint) {\n assembly {\n let F := 21888242871839275222246405745257275088548364400416034343698204186575808495617\n let M20 := 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d\n let M21 := 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa\n let M22 := 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0\n\n // load the inputs from memory\n let state1 := add(mod(mload(0x80), F), 0x00f1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864)\n let state2 := add(mod(mload(0xa0), F), 0x08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5)\n let scratch0 := mulmod(state1, state1, F)\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\n scratch0 := mulmod(state2, state2, F)\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\n scratch0 := add(\n 0x2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d0,\n add(add(15452833169820924772166449970675545095234312153403844297388521437673434406763, mulmod(state1, M10, F)), mulmod(state2, M20, F))\n )\n let scratch1 := add(\n 0x2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf2,\n add(add(18674271267752038776579386132900109523609358935013267566297499497165104279117, mulmod(state1, M11, F)), mulmod(state2, M21, F))\n )\n let scratch2 := add(\n 0x0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa,\n add(add(14817777843080276494683266178512808687156649753153012854386334860566696099579, mulmod(state1, M12, F)), mulmod(state2, M22, F))\n )\n let state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := mulmod(scratch1, scratch1, F)\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\n state0 := mulmod(scratch2, scratch2, F)\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\n state0 := add(0x28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc632, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := mulmod(state1, state1, F)\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\n scratch0 := mulmod(state2, state2, F)\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\n scratch0 := add(0x15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := mulmod(scratch1, scratch1, F)\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\n state0 := mulmod(scratch2, scratch2, F)\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\n state0 := add(0x10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c8705, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd1, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x005032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c887, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da53, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x0081c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb38, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c502, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x00ef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba89, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c5, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e4, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e13, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e9, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a90035, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db69, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b8, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c77, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x002e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x00b9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c3512, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x00248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a808, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f09, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e8284, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd800, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f178, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e504233, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc0, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d59, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f88948, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d142, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c0, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a58, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d01, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc792, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea6111, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa336, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d6, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f451, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf77, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc630, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := add(0x2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := add(0x054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := mulmod(scratch1, scratch1, F)\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\n state0 := mulmod(scratch2, scratch2, F)\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\n state0 := add(0x1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c2320, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := mulmod(state1, state1, F)\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\n scratch0 := mulmod(state2, state2, F)\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\n scratch0 := add(0x0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870, add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)))\n scratch1 := add(0x193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba, add(add(mulmod(state0, M01, F), mulmod(state1, M11, F)), mulmod(state2, M21, F)))\n scratch2 := add(0x102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f8, add(add(mulmod(state0, M02, F), mulmod(state1, M12, F)), mulmod(state2, M22, F)))\n state0 := mulmod(scratch0, scratch0, F)\n scratch0 := mulmod(mulmod(state0, state0, F), scratch0, F)\n state0 := mulmod(scratch1, scratch1, F)\n scratch1 := mulmod(mulmod(state0, state0, F), scratch1, F)\n state0 := mulmod(scratch2, scratch2, F)\n scratch2 := mulmod(mulmod(state0, state0, F), scratch2, F)\n state0 := add(0x0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1, add(add(mulmod(scratch0, M00, F), mulmod(scratch1, M10, F)), mulmod(scratch2, M20, F)))\n state1 := add(0x216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22, add(add(mulmod(scratch0, M01, F), mulmod(scratch1, M11, F)), mulmod(scratch2, M21, F)))\n state2 := add(0x1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e4228325161, add(add(mulmod(scratch0, M02, F), mulmod(scratch1, M12, F)), mulmod(scratch2, M22, F)))\n scratch0 := mulmod(state0, state0, F)\n state0 := mulmod(mulmod(scratch0, scratch0, F), state0, F)\n scratch0 := mulmod(state1, state1, F)\n state1 := mulmod(mulmod(scratch0, scratch0, F), state1, F)\n scratch0 := mulmod(state2, state2, F)\n state2 := mulmod(mulmod(scratch0, scratch0, F), state2, F)\n\n mstore(0x0, mod(add(add(mulmod(state0, M00, F), mulmod(state1, M10, F)), mulmod(state2, M20, F)), F))\n\n return(0, 0x20)\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + }, + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/" + ] + } +} diff --git a/deployments/sepolia/solcInputs/96dd1aa02e55dc27e236e777882a31a7.json b/deployments/sepolia/solcInputs/8725b13328c7d7e2e008ae1d327b8955.json similarity index 99% rename from deployments/sepolia/solcInputs/96dd1aa02e55dc27e236e777882a31a7.json rename to deployments/sepolia/solcInputs/8725b13328c7d7e2e008ae1d327b8955.json index f72151f..23a2877 100644 --- a/deployments/sepolia/solcInputs/96dd1aa02e55dc27e236e777882a31a7.json +++ b/deployments/sepolia/solcInputs/8725b13328c7d7e2e008ae1d327b8955.json @@ -2,7 +2,7 @@ "language": "Solidity", "sources": { "contracts/RlnVerifier.sol": { - "content": "// File: https://github.com/Rate-Limiting-Nullifier/rln-contract-v1/blob/main/src/RLNVerifier.sol\n// Copyright 2017 Christian Reitwiessner\n// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n// 2019 OKIMS\n// ported to solidity 0.6\n// fixed linter warnings\n// added requiere error messages\n//\n//\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.6.11;\n\nlibrary Pairing {\n struct G1Point {\n uint256 X;\n uint256 Y;\n }\n // Encoding of field elements is: X[0] * z + X[1]\n\n struct G2Point {\n uint256[2] X;\n uint256[2] Y;\n }\n /// @return the generator of G1\n\n function P1() internal pure returns (G1Point memory) {\n return G1Point(1, 2);\n }\n /// @return the generator of G2\n\n function P2() internal pure returns (G2Point memory) {\n // Original code point\n return G2Point(\n [\n 11559732032986387107991004021392285783925812861821192530917403151452391805634,\n 10857046999023057135944570762232829481370756359578518086990519993285655852781\n ],\n [\n 4082367875863433681332203403145435568316851327593401208105741076214120093531,\n 8495653923123431417604973247489272438418190587263600148770280649306958101930\n ]\n );\n\n /*\n // Changed by Jordi point\n return G2Point(\n [10857046999023057135944570762232829481370756359578518086990519993285655852781,\n 11559732032986387107991004021392285783925812861821192530917403151452391805634],\n [8495653923123431417604973247489272438418190587263600148770280649306958101930,\n 4082367875863433681332203403145435568316851327593401208105741076214120093531]\n );*/\n }\n /// @return r the negation of p, i.e. p.addition(p.negate()) should be zero.\n\n function negate(G1Point memory p) internal pure returns (G1Point memory r) {\n // The prime q in the base field F_q for G1\n uint256 q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n if (p.X == 0 && p.Y == 0) {\n return G1Point(0, 0);\n }\n return G1Point(p.X, q - (p.Y % q));\n }\n /// @return r the sum of two points of G1\n\n function addition(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) {\n uint256[4] memory input;\n input[0] = p1.X;\n input[1] = p1.Y;\n input[2] = p2.X;\n input[3] = p2.Y;\n bool success;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60)\n // Use \"invalid\" to make gas estimation work\n switch success\n case 0 { invalid() }\n }\n require(success, \"pairing-add-failed\");\n }\n /// @return r the product of a point on G1 and a scalar, i.e.\n /// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p.\n\n function scalar_mul(G1Point memory p, uint256 s) internal view returns (G1Point memory r) {\n uint256[3] memory input;\n input[0] = p.X;\n input[1] = p.Y;\n input[2] = s;\n bool success;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60)\n // Use \"invalid\" to make gas estimation work\n switch success\n case 0 { invalid() }\n }\n require(success, \"pairing-mul-failed\");\n }\n /// @return the result of computing the pairing check\n /// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1\n /// For example pairing([P1(), P1().negate()], [P2(), P2()]) should\n /// return true.\n\n function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) {\n require(p1.length == p2.length, \"pairing-lengths-failed\");\n uint256 elements = p1.length;\n uint256 inputSize = elements * 6;\n uint256[] memory input = new uint[](inputSize);\n for (uint256 i = 0; i < elements; i++) {\n input[i * 6 + 0] = p1[i].X;\n input[i * 6 + 1] = p1[i].Y;\n input[i * 6 + 2] = p2[i].X[0];\n input[i * 6 + 3] = p2[i].X[1];\n input[i * 6 + 4] = p2[i].Y[0];\n input[i * 6 + 5] = p2[i].Y[1];\n }\n uint256[1] memory out;\n bool success;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)\n // Use \"invalid\" to make gas estimation work\n switch success\n case 0 { invalid() }\n }\n require(success, \"pairing-opcode-failed\");\n return out[0] != 0;\n }\n /// Convenience method for a pairing check for two pairs.\n\n function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2)\n internal\n view\n returns (bool)\n {\n G1Point[] memory p1 = new G1Point[](2);\n G2Point[] memory p2 = new G2Point[](2);\n p1[0] = a1;\n p1[1] = b1;\n p2[0] = a2;\n p2[1] = b2;\n return pairing(p1, p2);\n }\n /// Convenience method for a pairing check for three pairs.\n\n function pairingProd3(\n G1Point memory a1,\n G2Point memory a2,\n G1Point memory b1,\n G2Point memory b2,\n G1Point memory c1,\n G2Point memory c2\n ) internal view returns (bool) {\n G1Point[] memory p1 = new G1Point[](3);\n G2Point[] memory p2 = new G2Point[](3);\n p1[0] = a1;\n p1[1] = b1;\n p1[2] = c1;\n p2[0] = a2;\n p2[1] = b2;\n p2[2] = c2;\n return pairing(p1, p2);\n }\n /// Convenience method for a pairing check for four pairs.\n\n function pairingProd4(\n G1Point memory a1,\n G2Point memory a2,\n G1Point memory b1,\n G2Point memory b2,\n G1Point memory c1,\n G2Point memory c2,\n G1Point memory d1,\n G2Point memory d2\n ) internal view returns (bool) {\n G1Point[] memory p1 = new G1Point[](4);\n G2Point[] memory p2 = new G2Point[](4);\n p1[0] = a1;\n p1[1] = b1;\n p1[2] = c1;\n p1[3] = d1;\n p2[0] = a2;\n p2[1] = b2;\n p2[2] = c2;\n p2[3] = d2;\n return pairing(p1, p2);\n }\n}\n\ncontract Verifier {\n using Pairing for *;\n\n struct VerifyingKey {\n Pairing.G1Point alfa1;\n Pairing.G2Point beta2;\n Pairing.G2Point gamma2;\n Pairing.G2Point delta2;\n Pairing.G1Point[] IC;\n }\n\n struct Proof {\n Pairing.G1Point A;\n Pairing.G2Point B;\n Pairing.G1Point C;\n }\n\n function verifyingKey() internal pure returns (VerifyingKey memory vk) {\n vk.alfa1 = Pairing.G1Point(\n 20491192805390485299153009773594534940189261866228447918068658471970481763042,\n 9383485363053290200918347156157836566562967994039712273449902621266178545958\n );\n\n vk.beta2 = Pairing.G2Point(\n [\n 4252822878758300859123897981450591353533073413197771768651442665752259397132,\n 6375614351688725206403948262868962793625744043794305715222011528459656738731\n ],\n [\n 21847035105528745403288232691147584728191162732299865338377159692350059136679,\n 10505242626370262277552901082094356697409835680220590971873171140371331206856\n ]\n );\n vk.gamma2 = Pairing.G2Point(\n [\n 11559732032986387107991004021392285783925812861821192530917403151452391805634,\n 10857046999023057135944570762232829481370756359578518086990519993285655852781\n ],\n [\n 4082367875863433681332203403145435568316851327593401208105741076214120093531,\n 8495653923123431417604973247489272438418190587263600148770280649306958101930\n ]\n );\n vk.delta2 = Pairing.G2Point(\n [\n 12423666958566268737444308034237892912702648013927558883280319245968679130649,\n 15986964528637281931410749976607406939789163617014270799373312764775965360012\n ],\n [\n 8394023076056524902583796202128496802110914536948580183128578071394816660799,\n 4964607673011101982600772762445991192038811950832626693345350322823626470007\n ]\n );\n vk.IC = new Pairing.G1Point[](3);\n\n vk.IC[0] = Pairing.G1Point(\n 1655549413518972190198478012616802994254462093161203201613599472264958303841,\n 21742734017792296281216385119397138748114275727065024271646515586404591497876\n );\n\n vk.IC[1] = Pairing.G1Point(\n 16497930821522159474595176304955625435616718625609462506360632944366974274906,\n 10404924572941018678793755094259635830045501866471999610240845041996101882275\n );\n\n vk.IC[2] = Pairing.G1Point(\n 9567910551099174794221497568036631681620409346997815381833929247558241020796,\n 17282591858786007768931802126325866705896012606427630592145070155065868649172\n );\n }\n\n function verify(uint256[] memory input, Proof memory proof) internal view returns (uint256) {\n uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n VerifyingKey memory vk = verifyingKey();\n require(input.length + 1 == vk.IC.length, \"verifier-bad-input\");\n // Compute the linear combination vk_x\n Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0);\n for (uint256 i = 0; i < input.length; i++) {\n require(input[i] < snark_scalar_field, \"verifier-gte-snark-scalar-field\");\n vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.IC[i + 1], input[i]));\n }\n vk_x = Pairing.addition(vk_x, vk.IC[0]);\n if (\n !Pairing.pairingProd4(\n Pairing.negate(proof.A), proof.B, vk.alfa1, vk.beta2, vk_x, vk.gamma2, proof.C, vk.delta2\n )\n ) return 1;\n return 0;\n }\n /// @return r bool true if proof is valid\n\n function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)\n public\n view\n returns (bool r)\n {\n Proof memory proof;\n proof.A = Pairing.G1Point(a[0], a[1]);\n proof.B = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]);\n proof.C = Pairing.G1Point(c[0], c[1]);\n uint256[] memory inputValues = new uint[](input.length);\n for (uint256 i = 0; i < input.length; i++) {\n inputValues[i] = input[i];\n }\n if (verify(inputValues, proof) == 0) {\n return true;\n } else {\n return false;\n }\n }\n}" + "content": "// File: https://github.com/Rate-Limiting-Nullifier/rln-contract-v1/blob/main/src/RLNVerifier.sol\n// Copyright 2017 Christian Reitwiessner\n// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n// 2019 OKIMS\n// ported to solidity 0.6\n// fixed linter warnings\n// added requiere error messages\n//\n//\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.6.11;\n\nlibrary Pairing {\n struct G1Point {\n uint256 X;\n uint256 Y;\n }\n // Encoding of field elements is: X[0] * z + X[1]\n\n struct G2Point {\n uint256[2] X;\n uint256[2] Y;\n }\n /// @return the generator of G1\n\n function P1() internal pure returns (G1Point memory) {\n return G1Point(1, 2);\n }\n /// @return the generator of G2\n\n function P2() internal pure returns (G2Point memory) {\n // Original code point\n return G2Point(\n [\n 11559732032986387107991004021392285783925812861821192530917403151452391805634,\n 10857046999023057135944570762232829481370756359578518086990519993285655852781\n ],\n [\n 4082367875863433681332203403145435568316851327593401208105741076214120093531,\n 8495653923123431417604973247489272438418190587263600148770280649306958101930\n ]\n );\n\n /*\n // Changed by Jordi point\n return G2Point(\n [10857046999023057135944570762232829481370756359578518086990519993285655852781,\n 11559732032986387107991004021392285783925812861821192530917403151452391805634],\n [8495653923123431417604973247489272438418190587263600148770280649306958101930,\n 4082367875863433681332203403145435568316851327593401208105741076214120093531]\n );*/\n }\n /// @return r the negation of p, i.e. p.addition(p.negate()) should be zero.\n\n function negate(G1Point memory p) internal pure returns (G1Point memory r) {\n // The prime q in the base field F_q for G1\n uint256 q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n if (p.X == 0 && p.Y == 0) {\n return G1Point(0, 0);\n }\n return G1Point(p.X, q - (p.Y % q));\n }\n /// @return r the sum of two points of G1\n\n function addition(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) {\n uint256[4] memory input;\n input[0] = p1.X;\n input[1] = p1.Y;\n input[2] = p2.X;\n input[3] = p2.Y;\n bool success;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60)\n // Use \"invalid\" to make gas estimation work\n switch success\n case 0 { invalid() }\n }\n require(success, \"pairing-add-failed\");\n }\n /// @return r the product of a point on G1 and a scalar, i.e.\n /// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p.\n\n function scalar_mul(G1Point memory p, uint256 s) internal view returns (G1Point memory r) {\n uint256[3] memory input;\n input[0] = p.X;\n input[1] = p.Y;\n input[2] = s;\n bool success;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60)\n // Use \"invalid\" to make gas estimation work\n switch success\n case 0 { invalid() }\n }\n require(success, \"pairing-mul-failed\");\n }\n /// @return the result of computing the pairing check\n /// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1\n /// For example pairing([P1(), P1().negate()], [P2(), P2()]) should\n /// return true.\n\n function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) {\n require(p1.length == p2.length, \"pairing-lengths-failed\");\n uint256 elements = p1.length;\n uint256 inputSize = elements * 6;\n uint256[] memory input = new uint[](inputSize);\n for (uint256 i = 0; i < elements; i++) {\n input[i * 6 + 0] = p1[i].X;\n input[i * 6 + 1] = p1[i].Y;\n input[i * 6 + 2] = p2[i].X[0];\n input[i * 6 + 3] = p2[i].X[1];\n input[i * 6 + 4] = p2[i].Y[0];\n input[i * 6 + 5] = p2[i].Y[1];\n }\n uint256[1] memory out;\n bool success;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)\n // Use \"invalid\" to make gas estimation work\n switch success\n case 0 { invalid() }\n }\n require(success, \"pairing-opcode-failed\");\n return out[0] != 0;\n }\n /// Convenience method for a pairing check for two pairs.\n\n function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2)\n internal\n view\n returns (bool)\n {\n G1Point[] memory p1 = new G1Point[](2);\n G2Point[] memory p2 = new G2Point[](2);\n p1[0] = a1;\n p1[1] = b1;\n p2[0] = a2;\n p2[1] = b2;\n return pairing(p1, p2);\n }\n /// Convenience method for a pairing check for three pairs.\n\n function pairingProd3(\n G1Point memory a1,\n G2Point memory a2,\n G1Point memory b1,\n G2Point memory b2,\n G1Point memory c1,\n G2Point memory c2\n ) internal view returns (bool) {\n G1Point[] memory p1 = new G1Point[](3);\n G2Point[] memory p2 = new G2Point[](3);\n p1[0] = a1;\n p1[1] = b1;\n p1[2] = c1;\n p2[0] = a2;\n p2[1] = b2;\n p2[2] = c2;\n return pairing(p1, p2);\n }\n /// Convenience method for a pairing check for four pairs.\n\n function pairingProd4(\n G1Point memory a1,\n G2Point memory a2,\n G1Point memory b1,\n G2Point memory b2,\n G1Point memory c1,\n G2Point memory c2,\n G1Point memory d1,\n G2Point memory d2\n ) internal view returns (bool) {\n G1Point[] memory p1 = new G1Point[](4);\n G2Point[] memory p2 = new G2Point[](4);\n p1[0] = a1;\n p1[1] = b1;\n p1[2] = c1;\n p1[3] = d1;\n p2[0] = a2;\n p2[1] = b2;\n p2[2] = c2;\n p2[3] = d2;\n return pairing(p1, p2);\n }\n}\n\ncontract Verifier {\n using Pairing for *;\n\n struct VerifyingKey {\n Pairing.G1Point alfa1;\n Pairing.G2Point beta2;\n Pairing.G2Point gamma2;\n Pairing.G2Point delta2;\n Pairing.G1Point[] IC;\n }\n\n struct Proof {\n Pairing.G1Point A;\n Pairing.G2Point B;\n Pairing.G1Point C;\n }\n\n function verifyingKey() internal pure returns (VerifyingKey memory vk) {\n vk.alfa1 = Pairing.G1Point(\n 20491192805390485299153009773594534940189261866228447918068658471970481763042,\n 9383485363053290200918347156157836566562967994039712273449902621266178545958\n );\n\n vk.beta2 = Pairing.G2Point(\n [\n 4252822878758300859123897981450591353533073413197771768651442665752259397132,\n 6375614351688725206403948262868962793625744043794305715222011528459656738731\n ],\n [\n 21847035105528745403288232691147584728191162732299865338377159692350059136679,\n 10505242626370262277552901082094356697409835680220590971873171140371331206856\n ]\n );\n vk.gamma2 = Pairing.G2Point(\n [\n 11559732032986387107991004021392285783925812861821192530917403151452391805634,\n 10857046999023057135944570762232829481370756359578518086990519993285655852781\n ],\n [\n 4082367875863433681332203403145435568316851327593401208105741076214120093531,\n 8495653923123431417604973247489272438418190587263600148770280649306958101930\n ]\n );\n vk.delta2 = Pairing.G2Point(\n [\n 12423666958566268737444308034237892912702648013927558883280319245968679130649,\n 15986964528637281931410749976607406939789163617014270799373312764775965360012\n ],\n [\n 8394023076056524902583796202128496802110914536948580183128578071394816660799,\n 4964607673011101982600772762445991192038811950832626693345350322823626470007\n ]\n );\n vk.IC = new Pairing.G1Point[](3);\n\n vk.IC[0] = Pairing.G1Point(\n 1655549413518972190198478012616802994254462093161203201613599472264958303841,\n 21742734017792296281216385119397138748114275727065024271646515586404591497876\n );\n\n vk.IC[1] = Pairing.G1Point(\n 16497930821522159474595176304955625435616718625609462506360632944366974274906,\n 10404924572941018678793755094259635830045501866471999610240845041996101882275\n );\n\n vk.IC[2] = Pairing.G1Point(\n 9567910551099174794221497568036631681620409346997815381833929247558241020796,\n 17282591858786007768931802126325866705896012606427630592145070155065868649172\n );\n }\n\n function verify(uint256[] memory input, Proof memory proof) internal view returns (uint256) {\n uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n VerifyingKey memory vk = verifyingKey();\n require(input.length + 1 == vk.IC.length, \"verifier-bad-input\");\n // Compute the linear combination vk_x\n Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0);\n for (uint256 i = 0; i < input.length; i++) {\n require(input[i] < snark_scalar_field, \"verifier-gte-snark-scalar-field\");\n vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.IC[i + 1], input[i]));\n }\n vk_x = Pairing.addition(vk_x, vk.IC[0]);\n if (\n !Pairing.pairingProd4(\n Pairing.negate(proof.A), proof.B, vk.alfa1, vk.beta2, vk_x, vk.gamma2, proof.C, vk.delta2\n )\n ) return 1;\n return 0;\n }\n /// @return r bool true if proof is valid\n\n function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)\n public\n view\n returns (bool r)\n {\n Proof memory proof;\n proof.A = Pairing.G1Point(a[0], a[1]);\n proof.B = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]);\n proof.C = Pairing.G1Point(c[0], c[1]);\n uint256[] memory inputValues = new uint[](input.length);\n for (uint256 i = 0; i < input.length; i++) {\n inputValues[i] = input[i];\n }\n if (verify(inputValues, proof) == 0) {\n return true;\n } else {\n return false;\n }\n }\n}\n" } }, "settings": { diff --git a/deployments/sepolia/solcInputs/b1509b5db56df56b3944fa20992a2034.json b/deployments/sepolia/solcInputs/b1509b5db56df56b3944fa20992a2034.json deleted file mode 100644 index 8ca6cb7..0000000 --- a/deployments/sepolia/solcInputs/b1509b5db56df56b3944fa20992a2034.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/PoseidonHasher.sol": { - "content": "// SPDX-License-Identifier: MIT\n\n// Forked from https://github.com/kilic/rlnapp/\n\npragma solidity 0.8.15;\n\ninterface IPoseidonHasher {\n /// @notice Hashes the input using the Poseidon hash function, n = 2, second input is the constant 0\n /// @param input The input to hash\n function hash(uint256 input) external pure returns (uint256 result);\n}\n\ncontract PoseidonHasher is IPoseidonHasher {\n uint256 constant Q =\n 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n uint256 constant C0 =\n 4417881134626180770308697923359573201005643519861877412381846989312604493735;\n uint256 constant C1 =\n 5433650512959517612316327474713065966758808864213826738576266661723522780033;\n uint256 constant C2 =\n 13641176377184356099764086973022553863760045607496549923679278773208775739952;\n uint256 constant C3 =\n 17949713444224994136330421782109149544629237834775211751417461773584374506783;\n uint256 constant C4 =\n 13765628375339178273710281891027109699578766420463125835325926111705201856003;\n uint256 constant C5 =\n 19179513468172002314585757290678967643352171735526887944518845346318719730387;\n uint256 constant C6 =\n 5157412437176756884543472904098424903141745259452875378101256928559722612176;\n uint256 constant C7 =\n 535160875740282236955320458485730000677124519901643397458212725410971557409;\n uint256 constant C8 =\n 1050793453380762984940163090920066886770841063557081906093018330633089036729;\n uint256 constant C9 =\n 10665495010329663932664894101216428400933984666065399374198502106997623173873;\n uint256 constant C10 =\n 19965634623406616956648724894636666805991993496469370618546874926025059150737;\n uint256 constant C11 =\n 13007250030070838431593222885902415182312449212965120303174723305710127422213;\n uint256 constant C12 =\n 16877538715074991604507979123743768693428157847423939051086744213162455276374;\n uint256 constant C13 =\n 18211747749504876135588847560312685184956239426147543810126553367063157141465;\n uint256 constant C14 =\n 18151553319826126919739798892854572062191241985315767086020821632812331245635;\n uint256 constant C15 =\n 19957033149976712666746140949846950406660099037474791840946955175819555930825;\n uint256 constant C16 =\n 3469514863538261843186854830917934449567467100548474599735384052339577040841;\n uint256 constant C17 =\n 989698510043911779243192466312362856042600749099921773896924315611668507708;\n uint256 constant C18 =\n 12568377015646290945235387813564567111330046038050864455358059568128000172201;\n uint256 constant C19 =\n 20856104135605479600325529349246932565148587186338606236677138505306779314172;\n uint256 constant C20 =\n 8206918720503535523121349917159924938835810381723474192155637697065780938424;\n uint256 constant C21 =\n 1309058477013932989380617265069188723120054926187607548493110334522527703566;\n uint256 constant C22 =\n 14076116939332667074621703729512195584105250395163383769419390236426287710606;\n uint256 constant C23 =\n 10153498892749751942204288991871286290442690932856658983589258153608012428674;\n uint256 constant C24 =\n 18202499207234128286137597834010475797175973146805180988367589376893530181575;\n uint256 constant C25 =\n 12739388830157083522877690211447248168864006284243907142044329113461613743052;\n uint256 constant C26 =\n 15123358710467780770838026754240340042441262572309759635224051333176022613949;\n uint256 constant C27 =\n 19925004701844594370904593774447343836015483888496504201331110250494635362184;\n uint256 constant C28 =\n 10352416606816998476681131583320899030072315953910679608943150613208329645891;\n uint256 constant C29 =\n 10567371822366244361703342347428230537114808440249611395507235283708966113221;\n uint256 constant C30 =\n 5635498582763880627392290206431559361272660937399944184533035305989295959602;\n uint256 constant C31 =\n 11866432933224219174041051738704352719163271639958083608224676028593315904909;\n uint256 constant C32 =\n 5795020705294401441272215064554385591292330721703923167136157291459784140431;\n uint256 constant C33 =\n 9482202378699252817564375087302794636287866584767523335624368774856230692758;\n uint256 constant C34 =\n 4245237636894546151746468406560945873445548423466753843402086544922216329298;\n uint256 constant C35 =\n 12000500941313982757584712677991730019124834399479314697467598397927435905133;\n uint256 constant C36 =\n 7596790274058425558167520209857956363736666939016807569082239187494363541787;\n uint256 constant C37 =\n 2484867918246116343205467273440098378820186751202461278013576281097918148877;\n uint256 constant C38 =\n 18312645949449997391810445935615409295369169383463185688973803378104013950190;\n uint256 constant C39 =\n 15320686572748723004980855263301182130424010735782762814513954166519592552733;\n uint256 constant C40 =\n 12618438900597948888520621062416758747872180395546164387827245287017031303859;\n uint256 constant C41 =\n 17438141672027706116733201008397064011774368832458707512367404736905021019585;\n uint256 constant C42 =\n 6374197807230665998865688675365359100400438034755781666913068586172586548950;\n uint256 constant C43 =\n 2189398913433273865510950346186699930188746169476472274335177556702504595264;\n uint256 constant C44 =\n 6268495580028970231803791523870131137294646402347399003576649137450213034606;\n uint256 constant C45 =\n 17896250365994900261202920044129628104272791547990619503076839618914047059275;\n uint256 constant C46 =\n 13692156312448722528008862371944543449350293305158722920787736248435893008873;\n uint256 constant C47 =\n 15234446864368744483209945022439268713300180233589581910497691316744177619376;\n uint256 constant C48 =\n 1572426502623310766593681563281600503979671244997798691029595521622402217227;\n uint256 constant C49 =\n 80103447810215150918585162168214870083573048458555897999822831203653996617;\n uint256 constant C50 =\n 8228820324013669567851850635126713973797711779951230446503353812192849106342;\n uint256 constant C51 =\n 5375851433746509614045812476958526065449377558695752132494533666370449415873;\n uint256 constant C52 =\n 12115998939203497346386774317892338270561208357481805380546938146796257365018;\n uint256 constant C53 =\n 9764067909645821279940531410531154041386008396840887338272986634350423466622;\n uint256 constant C54 =\n 8538708244538850542384936174629541085495830544298260335345008245230827876882;\n uint256 constant C55 =\n 7140127896620013355910287215441004676619168261422440177712039790284719613114;\n uint256 constant C56 =\n 14297402962228458726038826185823085337698917275385741292940049024977027409762;\n uint256 constant C57 =\n 6667115556431351074165934212337261254608231545257434281887966406956835140819;\n uint256 constant C58 =\n 20226761165244293291042617464655196752671169026542832236139342122602741090001;\n uint256 constant C59 =\n 12038289506489256655759141386763477208196694421666339040483042079632134429119;\n uint256 constant C60 =\n 19027757334170818571203982241812412991528769934917288000224335655934473717551;\n uint256 constant C61 =\n 16272152964456553579565580463468069884359929612321610357528838696790370074720;\n uint256 constant C62 =\n 2500392889689246014710135696485946334448570271481948765283016105301740284071;\n uint256 constant C63 =\n 8595254970528530312401637448610398388203855633951264114100575485022581946023;\n uint256 constant C64 =\n 11635945688914011450976408058407206367914559009113158286982919675551688078198;\n uint256 constant C65 =\n 614739068603482619581328040478536306925147663946742687395148680260956671871;\n uint256 constant C66 =\n 18692271780377861570175282183255720350972693125537599213951106550953176268753;\n uint256 constant C67 =\n 4987059230784976306647166378298632695585915319042844495357753339378260807164;\n uint256 constant C68 =\n 21851403978498723616722415377430107676258664746210815234490134600998983955497;\n uint256 constant C69 =\n 9830635451186415300891533983087800047564037813328875992115573428596207326204;\n uint256 constant C70 =\n 4842706106434537116860242620706030229206345167233200482994958847436425185478;\n uint256 constant C71 =\n 6422235064906823218421386871122109085799298052314922856340127798647926126490;\n uint256 constant C72 =\n 4564364104986856861943331689105797031330091877115997069096365671501473357846;\n uint256 constant C73 =\n 1944043894089780613038197112872830569538541856657037469098448708685350671343;\n uint256 constant C74 =\n 21179865974855950600518216085229498748425990426231530451599322283119880194955;\n uint256 constant C75 =\n 14296697761894107574369608843560006996183955751502547883167824879840894933162;\n uint256 constant C76 =\n 12274619649702218570450581712439138337725246879938860735460378251639845671898;\n uint256 constant C77 =\n 16371396450276899401411886674029075408418848209575273031725505038938314070356;\n uint256 constant C78 =\n 3702561221750983937578095019779188631407216522704543451228773892695044653565;\n uint256 constant C79 =\n 19721616877735564664624984774636557499099875603996426215495516594530838681980;\n uint256 constant C80 =\n 6383350109027696789969911008057747025018308755462287526819231672217685282429;\n uint256 constant C81 =\n 20860583956177367265984596617324237471765572961978977333122281041544719622905;\n uint256 constant C82 =\n 5766390934595026947545001478457407504285452477687752470140790011329357286275;\n uint256 constant C83 =\n 4043175758319898049344746138515323336207420888499903387536875603879441092484;\n uint256 constant C84 =\n 15579382179133608217098622223834161692266188678101563820988612253342538956534;\n uint256 constant C85 =\n 1864640783252634743892105383926602930909039567065240010338908865509831749824;\n uint256 constant C86 =\n 15943719865023133586707144161652035291705809358178262514871056013754142625673;\n uint256 constant C87 =\n 2326415993032390211558498780803238091925402878871059708106213703504162832999;\n uint256 constant C88 =\n 19995326402773833553207196590622808505547443523750970375738981396588337910289;\n uint256 constant C89 =\n 5143583711361588952673350526320181330406047695593201009385718506918735286622;\n uint256 constant C90 =\n 15436006486881920976813738625999473183944244531070780793506388892313517319583;\n uint256 constant C91 =\n 16660446760173633166698660166238066533278664023818938868110282615200613695857;\n uint256 constant C92 =\n 4966065365695755376133119391352131079892396024584848298231004326013366253934;\n uint256 constant C93 =\n 20683781957411705574951987677641476019618457561419278856689645563561076926702;\n uint256 constant C94 =\n 17280836839165902792086432296371645107551519324565649849400948918605456875699;\n uint256 constant C95 =\n 17045635513701208892073056357048619435743564064921155892004135325530808465371;\n uint256 constant C96 =\n 17055032967194400710390142791334572297458033582458169295920670679093585707295;\n uint256 constant C97 =\n 15727174639569115300068198908071514334002742825679221638729902577962862163505;\n uint256 constant C98 =\n 1001755657610446661315902885492677747789366510875120894840818704741370398633;\n uint256 constant C99 =\n 18638547332826171619311285502376343504539399518545103511265465604926625041234;\n uint256 constant C100 =\n 6751954224763196429755298529194402870632445298969935050224267844020826420799;\n uint256 constant C101 =\n 3526747115904224771452549517614107688674036840088422555827581348280834879405;\n uint256 constant C102 =\n 15705897908180497062880001271426561999724005008972544196300715293701537574122;\n uint256 constant C103 =\n 574386695213920937259007343820417029802510752426579750428758189312416867750;\n uint256 constant C104 =\n 15973040855000600860816974646787367136127946402908768408978806375685439868553;\n uint256 constant C105 =\n 20934130413948796333037139460875996342810005558806621330680156931816867321122;\n uint256 constant C106 =\n 6918585327145564636398173845411579411526758237572034236476079610890705810764;\n uint256 constant C107 =\n 14158163500813182062258176233162498241310167509137716527054939926126453647182;\n uint256 constant C108 =\n 4164602626597695668474100217150111342272610479949122406544277384862187287433;\n uint256 constant C109 =\n 12146526846507496913615390662823936206892812880963914267275606265272996025304;\n uint256 constant C110 =\n 10153527926900017763244212043512822363696541810586522108597162891799345289938;\n uint256 constant C111 =\n 13564663485965299104296214940873270349072051793008946663855767889066202733588;\n uint256 constant C112 =\n 5612449256997576125867742696783020582952387615430650198777254717398552960096;\n uint256 constant C113 =\n 12151885480032032868507892738683067544172874895736290365318623681886999930120;\n uint256 constant C114 =\n 380452237704664384810613424095477896605414037288009963200982915188629772177;\n uint256 constant C115 =\n 9067557551252570188533509616805287919563636482030947363841198066124642069518;\n uint256 constant C116 =\n 21280306817619711661335268484199763923870315733198162896599997188206277056900;\n uint256 constant C117 =\n 5567165819557297006750252582140767993422097822227408837378089569369734876257;\n uint256 constant C118 =\n 10411936321072105429908396649383171465939606386380071222095155850987201580137;\n uint256 constant C119 =\n 21338390051413922944780864872652000187403217966653363270851298678606449622266;\n uint256 constant C120 =\n 12156296560457833712186127325312904760045212412680904475497938949653569234473;\n uint256 constant C121 =\n 4271647814574748734312113971565139132510281260328947438246615707172526380757;\n uint256 constant C122 =\n 9061738206062369647211128232833114177054715885442782773131292534862178874950;\n uint256 constant C123 =\n 10134551893627587797380445583959894183158393780166496661696555422178052339133;\n uint256 constant C124 =\n 8932270237664043612366044102088319242789325050842783721780970129656616386103;\n uint256 constant C125 =\n 3339412934966886386194449782756711637636784424032779155216609410591712750636;\n uint256 constant C126 =\n 9704903972004596791086522314847373103670545861209569267884026709445485704400;\n uint256 constant C127 =\n 17467570179597572575614276429760169990940929887711661192333523245667228809456;\n uint256 constant M00 =\n 2910766817845651019878574839501801340070030115151021261302834310722729507541;\n uint256 constant M01 =\n 19727366863391167538122140361473584127147630672623100827934084310230022599144;\n uint256 constant M10 =\n 5776684794125549462448597414050232243778680302179439492664047328281728356345;\n uint256 constant M11 =\n 8348174920934122550483593999453880006756108121341067172388445916328941978568;\n\n function hash(\n uint256 input\n ) external pure override returns (uint256 result) {\n return _hash(input);\n }\n\n function _hash(uint256 input) internal pure returns (uint256 result) {\n assembly {\n // Poseidon parameters should be t = 2, RF = 8, RP = 56\n\n // We load the characteristic\n let q := Q\n\n // In zerokit implementation, if we pass inp = [a0,a1,..,an] to Poseidon what is effectively hashed is [0,a0,a1,..,an]\n // Note that a sequence of MIX-ARK involves 3 Bn254 field additions before the mulmod happens. Worst case we have a value corresponding to 2*(p-1) which is less than 2^256 and hence doesn't overflow\n //ROUND 0 - FULL\n let s0 := C0\n let s1 := add(input, C1)\n // SBOX\n let t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 1 - FULL\n s0 := add(s0, C2)\n s1 := add(s1, C3)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 2 - FULL\n s0 := add(s0, C4)\n s1 := add(s1, C5)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 3 - FULL\n s0 := add(s0, C6)\n s1 := add(s1, C7)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 4 - PARTIAL\n s0 := add(s0, C8)\n s1 := add(s1, C9)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 5 - PARTIAL\n s0 := add(s0, C10)\n s1 := add(s1, C11)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 6 - PARTIAL\n s0 := add(s0, C12)\n s1 := add(s1, C13)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 7 - PARTIAL\n s0 := add(s0, C14)\n s1 := add(s1, C15)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 8 - PARTIAL\n s0 := add(s0, C16)\n s1 := add(s1, C17)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 9 - PARTIAL\n s0 := add(s0, C18)\n s1 := add(s1, C19)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 10 - PARTIAL\n s0 := add(s0, C20)\n s1 := add(s1, C21)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 11 - PARTIAL\n s0 := add(s0, C22)\n s1 := add(s1, C23)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 12 - PARTIAL\n s0 := add(s0, C24)\n s1 := add(s1, C25)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 13 - PARTIAL\n s0 := add(s0, C26)\n s1 := add(s1, C27)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 14 - PARTIAL\n s0 := add(s0, C28)\n s1 := add(s1, C29)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 15 - PARTIAL\n s0 := add(s0, C30)\n s1 := add(s1, C31)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 16 - PARTIAL\n s0 := add(s0, C32)\n s1 := add(s1, C33)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 17 - PARTIAL\n s0 := add(s0, C34)\n s1 := add(s1, C35)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 18 - PARTIAL\n s0 := add(s0, C36)\n s1 := add(s1, C37)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 19 - PARTIAL\n s0 := add(s0, C38)\n s1 := add(s1, C39)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 20 - PARTIAL\n s0 := add(s0, C40)\n s1 := add(s1, C41)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 21 - PARTIAL\n s0 := add(s0, C42)\n s1 := add(s1, C43)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 22 - PARTIAL\n s0 := add(s0, C44)\n s1 := add(s1, C45)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 23 - PARTIAL\n s0 := add(s0, C46)\n s1 := add(s1, C47)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 24 - PARTIAL\n s0 := add(s0, C48)\n s1 := add(s1, C49)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 25 - PARTIAL\n s0 := add(s0, C50)\n s1 := add(s1, C51)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 26 - PARTIAL\n s0 := add(s0, C52)\n s1 := add(s1, C53)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 27 - PARTIAL\n s0 := add(s0, C54)\n s1 := add(s1, C55)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 28 - PARTIAL\n s0 := add(s0, C56)\n s1 := add(s1, C57)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 29 - PARTIAL\n s0 := add(s0, C58)\n s1 := add(s1, C59)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 30 - PARTIAL\n s0 := add(s0, C60)\n s1 := add(s1, C61)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 31 - PARTIAL\n s0 := add(s0, C62)\n s1 := add(s1, C63)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 32 - PARTIAL\n s0 := add(s0, C64)\n s1 := add(s1, C65)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 33 - PARTIAL\n s0 := add(s0, C66)\n s1 := add(s1, C67)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 34 - PARTIAL\n s0 := add(s0, C68)\n s1 := add(s1, C69)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 35 - PARTIAL\n s0 := add(s0, C70)\n s1 := add(s1, C71)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 36 - PARTIAL\n s0 := add(s0, C72)\n s1 := add(s1, C73)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 37 - PARTIAL\n s0 := add(s0, C74)\n s1 := add(s1, C75)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 38 - PARTIAL\n s0 := add(s0, C76)\n s1 := add(s1, C77)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 39 - PARTIAL\n s0 := add(s0, C78)\n s1 := add(s1, C79)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 40 - PARTIAL\n s0 := add(s0, C80)\n s1 := add(s1, C81)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 41 - PARTIAL\n s0 := add(s0, C82)\n s1 := add(s1, C83)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 42 - PARTIAL\n s0 := add(s0, C84)\n s1 := add(s1, C85)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 43 - PARTIAL\n s0 := add(s0, C86)\n s1 := add(s1, C87)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 44 - PARTIAL\n s0 := add(s0, C88)\n s1 := add(s1, C89)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 45 - PARTIAL\n s0 := add(s0, C90)\n s1 := add(s1, C91)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 46 - PARTIAL\n s0 := add(s0, C92)\n s1 := add(s1, C93)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 47 - PARTIAL\n s0 := add(s0, C94)\n s1 := add(s1, C95)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 48 - PARTIAL\n s0 := add(s0, C96)\n s1 := add(s1, C97)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 49 - PARTIAL\n s0 := add(s0, C98)\n s1 := add(s1, C99)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 50 - PARTIAL\n s0 := add(s0, C100)\n s1 := add(s1, C101)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 51 - PARTIAL\n s0 := add(s0, C102)\n s1 := add(s1, C103)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 52 - PARTIAL\n s0 := add(s0, C104)\n s1 := add(s1, C105)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 53 - PARTIAL\n s0 := add(s0, C106)\n s1 := add(s1, C107)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 54 - PARTIAL\n s0 := add(s0, C108)\n s1 := add(s1, C109)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 55 - PARTIAL\n s0 := add(s0, C110)\n s1 := add(s1, C111)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 56 - PARTIAL\n s0 := add(s0, C112)\n s1 := add(s1, C113)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 57 - PARTIAL\n s0 := add(s0, C114)\n s1 := add(s1, C115)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 58 - PARTIAL\n s0 := add(s0, C116)\n s1 := add(s1, C117)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 59 - PARTIAL\n s0 := add(s0, C118)\n s1 := add(s1, C119)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 60 - FULL\n s0 := add(s0, C120)\n s1 := add(s1, C121)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 61 - FULL\n s0 := add(s0, C122)\n s1 := add(s1, C123)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 62 - FULL\n s0 := add(s0, C124)\n s1 := add(s1, C125)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 63 - FULL\n s0 := add(s0, C126)\n s1 := add(s1, C127)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n s0 := mod(add(mulmod(s0, M00, q), mulmod(s1, M01, q)), q)\n\n result := s0\n }\n }\n}\n" - }, - "contracts/Rln.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.15;\n\nimport {IPoseidonHasher} from \"./PoseidonHasher.sol\";\n\n/// Invalid deposit amount\n/// @param required The required deposit amount\n/// @param provided The provided deposit amount\nerror InsufficientDeposit(uint256 required, uint256 provided);\n\n/// Provided Batch is empty\nerror EmptyBatch();\n\n/// Batch is full, during batch operations\nerror FullBatch();\n\n/// Member is already registered\nerror DuplicateIdCommitment();\n\n/// Batch size mismatch, when the length of secrets and receivers are not equal\n/// @param givenSecretsLen The length of the secrets array\n/// @param givenReceiversLen The length of the receivers array\nerror MismatchedBatchSize(uint256 givenSecretsLen, uint256 givenReceiversLen);\n\n/// Invalid withdrawal address, when the receiver is the contract itself or 0x0\nerror InvalidWithdrawalAddress(address to);\n\n/// Member is not registered\nerror MemberNotRegistered(uint256 idCommitment);\n\n/// Member has no stake\nerror MemberHasNoStake(uint256 idCommitment);\n\ncontract RLN {\n /// @notice The deposit amount required to register as a member\n uint256 public immutable MEMBERSHIP_DEPOSIT;\n\n /// @notice The depth of the merkle tree\n uint256 public immutable DEPTH;\n\n /// @notice The size of the merkle tree, i.e 2^depth\n uint256 public immutable SET_SIZE;\n\n /// @notice The index of the next member to be registered\n uint256 public idCommitmentIndex;\n\n /// @notice The amount of eth staked by each member\n mapping(uint256 => uint256) public stakedAmounts;\n\n /// @notice The membership status of each member\n mapping(uint256 => bool) public members;\n\n /// @notice The Poseidon hasher contract\n IPoseidonHasher public poseidonHasher;\n\n /// Emitted when a new member is added to the set\n /// @param idCommitment The idCommitment of the member\n /// @param index The index of the member in the set\n event MemberRegistered(uint256 idCommitment, uint256 index);\n\n /// Emitted when a member is removed from the set\n /// @param idCommitment The idCommitment of the member\n event MemberWithdrawn(uint256 idCommitment);\n\n constructor(\n uint256 membershipDeposit,\n uint256 depth,\n address _poseidonHasher\n ) {\n MEMBERSHIP_DEPOSIT = membershipDeposit;\n DEPTH = depth;\n SET_SIZE = 1 << depth;\n poseidonHasher = IPoseidonHasher(_poseidonHasher);\n }\n\n /// Allows a user to register as a member\n /// @param idCommitment The idCommitment of the member\n function register(uint256 idCommitment) external payable {\n if (msg.value != MEMBERSHIP_DEPOSIT)\n revert InsufficientDeposit(MEMBERSHIP_DEPOSIT, msg.value);\n _register(idCommitment, msg.value);\n }\n\n /// Allows batch registration of members\n /// @param idCommitments array of idCommitments\n function registerBatch(uint256[] calldata idCommitments) external payable {\n uint256 idCommitmentlen = idCommitments.length;\n if (idCommitmentlen == 0) revert EmptyBatch();\n if (idCommitmentIndex + idCommitmentlen >= SET_SIZE) revert FullBatch();\n uint256 requiredDeposit = MEMBERSHIP_DEPOSIT * idCommitmentlen;\n if (msg.value != requiredDeposit)\n revert InsufficientDeposit(requiredDeposit, msg.value);\n for (uint256 i = 0; i < idCommitmentlen; i++) {\n _register(idCommitments[i], msg.value / idCommitmentlen);\n }\n }\n\n /// Registers a member\n /// @param idCommitment The idCommitment of the member\n /// @param stake The amount of eth staked by the member\n function _register(uint256 idCommitment, uint256 stake) internal {\n if (members[idCommitment]) revert DuplicateIdCommitment();\n if (idCommitmentIndex >= SET_SIZE) revert FullBatch();\n\n members[idCommitment] = true;\n stakedAmounts[idCommitment] = stake;\n\n emit MemberRegistered(idCommitment, idCommitmentIndex);\n idCommitmentIndex += 1;\n }\n\n /// Allows a user to slash a batch of members\n /// @param secrets array of idSecretHashes\n /// @param receivers array of addresses to receive the funds\n function withdrawBatch(\n uint256[] calldata secrets,\n address payable[] calldata receivers\n ) external {\n uint256 batchSize = secrets.length;\n if (batchSize == 0) revert EmptyBatch();\n if (batchSize != receivers.length)\n revert MismatchedBatchSize(secrets.length, receivers.length);\n for (uint256 i = 0; i < batchSize; i++) {\n _withdraw(secrets[i], receivers[i]);\n }\n }\n\n /// Allows a user to slash a member\n /// @param secret The idSecretHash of the member\n function withdraw(uint256 secret, address payable receiver) external {\n _withdraw(secret, receiver);\n }\n\n /// Slashes a member by removing them from the set, and transferring their\n /// stake to the receiver\n /// @param secret The idSecretHash of the member\n /// @param receiver The address to receive the funds\n function _withdraw(uint256 secret, address payable receiver) internal {\n if (receiver == address(this) || receiver == address(0))\n revert InvalidWithdrawalAddress(receiver);\n\n // derive idCommitment\n uint256 idCommitment = hash(secret);\n // check if member is registered\n if (!members[idCommitment]) revert MemberNotRegistered(idCommitment);\n if (stakedAmounts[idCommitment] == 0)\n revert MemberHasNoStake(idCommitment);\n\n uint256 amountToTransfer = stakedAmounts[idCommitment];\n\n // delete member\n members[idCommitment] = false;\n stakedAmounts[idCommitment] = 0;\n\n // refund deposit\n receiver.transfer(amountToTransfer);\n\n emit MemberWithdrawn(idCommitment);\n }\n\n /// Hashes a value using the Poseidon hasher\n /// NOTE: The variant of Poseidon we use accepts only 1 input, assume n=2, and the second input is 0\n /// @param input The value to hash\n function hash(uint256 input) internal view returns (uint256) {\n return poseidonHasher.hash(input);\n }\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": false, - "runs": 200 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "devdoc", - "userdoc", - "storageLayout", - "evm.gasEstimates" - ], - "": ["ast"] - } - }, - "metadata": { - "useLiteralContent": true - }, - "remappings": [ - "ds-test/=lib/forge-std/lib/ds-test/src/", - "forge-std/=lib/forge-std/src/" - ] - } -} diff --git a/deployments/sepolia/solcInputs/d5475cf869d23da2a838dd607679cc44.json b/deployments/sepolia/solcInputs/d5475cf869d23da2a838dd607679cc44.json deleted file mode 100644 index 543d720..0000000 --- a/deployments/sepolia/solcInputs/d5475cf869d23da2a838dd607679cc44.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/PoseidonHasher.sol": { - "content": "// SPDX-License-Identifier: MIT\n\n// Forked from https://github.com/kilic/rlnapp/\n\npragma solidity 0.8.15;\n\ninterface IPoseidonHasher {\n /// @notice Hashes the input using the Poseidon hash function, n = 2, second input is the constant 0\n /// @param input The input to hash\n function hash(uint256 input) external pure returns (uint256 result);\n}\n\ncontract PoseidonHasher is IPoseidonHasher {\n uint256 constant Q =\n 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n uint256 constant C0 =\n 4417881134626180770308697923359573201005643519861877412381846989312604493735;\n uint256 constant C1 =\n 5433650512959517612316327474713065966758808864213826738576266661723522780033;\n uint256 constant C2 =\n 13641176377184356099764086973022553863760045607496549923679278773208775739952;\n uint256 constant C3 =\n 17949713444224994136330421782109149544629237834775211751417461773584374506783;\n uint256 constant C4 =\n 13765628375339178273710281891027109699578766420463125835325926111705201856003;\n uint256 constant C5 =\n 19179513468172002314585757290678967643352171735526887944518845346318719730387;\n uint256 constant C6 =\n 5157412437176756884543472904098424903141745259452875378101256928559722612176;\n uint256 constant C7 =\n 535160875740282236955320458485730000677124519901643397458212725410971557409;\n uint256 constant C8 =\n 1050793453380762984940163090920066886770841063557081906093018330633089036729;\n uint256 constant C9 =\n 10665495010329663932664894101216428400933984666065399374198502106997623173873;\n uint256 constant C10 =\n 19965634623406616956648724894636666805991993496469370618546874926025059150737;\n uint256 constant C11 =\n 13007250030070838431593222885902415182312449212965120303174723305710127422213;\n uint256 constant C12 =\n 16877538715074991604507979123743768693428157847423939051086744213162455276374;\n uint256 constant C13 =\n 18211747749504876135588847560312685184956239426147543810126553367063157141465;\n uint256 constant C14 =\n 18151553319826126919739798892854572062191241985315767086020821632812331245635;\n uint256 constant C15 =\n 19957033149976712666746140949846950406660099037474791840946955175819555930825;\n uint256 constant C16 =\n 3469514863538261843186854830917934449567467100548474599735384052339577040841;\n uint256 constant C17 =\n 989698510043911779243192466312362856042600749099921773896924315611668507708;\n uint256 constant C18 =\n 12568377015646290945235387813564567111330046038050864455358059568128000172201;\n uint256 constant C19 =\n 20856104135605479600325529349246932565148587186338606236677138505306779314172;\n uint256 constant C20 =\n 8206918720503535523121349917159924938835810381723474192155637697065780938424;\n uint256 constant C21 =\n 1309058477013932989380617265069188723120054926187607548493110334522527703566;\n uint256 constant C22 =\n 14076116939332667074621703729512195584105250395163383769419390236426287710606;\n uint256 constant C23 =\n 10153498892749751942204288991871286290442690932856658983589258153608012428674;\n uint256 constant C24 =\n 18202499207234128286137597834010475797175973146805180988367589376893530181575;\n uint256 constant C25 =\n 12739388830157083522877690211447248168864006284243907142044329113461613743052;\n uint256 constant C26 =\n 15123358710467780770838026754240340042441262572309759635224051333176022613949;\n uint256 constant C27 =\n 19925004701844594370904593774447343836015483888496504201331110250494635362184;\n uint256 constant C28 =\n 10352416606816998476681131583320899030072315953910679608943150613208329645891;\n uint256 constant C29 =\n 10567371822366244361703342347428230537114808440249611395507235283708966113221;\n uint256 constant C30 =\n 5635498582763880627392290206431559361272660937399944184533035305989295959602;\n uint256 constant C31 =\n 11866432933224219174041051738704352719163271639958083608224676028593315904909;\n uint256 constant C32 =\n 5795020705294401441272215064554385591292330721703923167136157291459784140431;\n uint256 constant C33 =\n 9482202378699252817564375087302794636287866584767523335624368774856230692758;\n uint256 constant C34 =\n 4245237636894546151746468406560945873445548423466753843402086544922216329298;\n uint256 constant C35 =\n 12000500941313982757584712677991730019124834399479314697467598397927435905133;\n uint256 constant C36 =\n 7596790274058425558167520209857956363736666939016807569082239187494363541787;\n uint256 constant C37 =\n 2484867918246116343205467273440098378820186751202461278013576281097918148877;\n uint256 constant C38 =\n 18312645949449997391810445935615409295369169383463185688973803378104013950190;\n uint256 constant C39 =\n 15320686572748723004980855263301182130424010735782762814513954166519592552733;\n uint256 constant C40 =\n 12618438900597948888520621062416758747872180395546164387827245287017031303859;\n uint256 constant C41 =\n 17438141672027706116733201008397064011774368832458707512367404736905021019585;\n uint256 constant C42 =\n 6374197807230665998865688675365359100400438034755781666913068586172586548950;\n uint256 constant C43 =\n 2189398913433273865510950346186699930188746169476472274335177556702504595264;\n uint256 constant C44 =\n 6268495580028970231803791523870131137294646402347399003576649137450213034606;\n uint256 constant C45 =\n 17896250365994900261202920044129628104272791547990619503076839618914047059275;\n uint256 constant C46 =\n 13692156312448722528008862371944543449350293305158722920787736248435893008873;\n uint256 constant C47 =\n 15234446864368744483209945022439268713300180233589581910497691316744177619376;\n uint256 constant C48 =\n 1572426502623310766593681563281600503979671244997798691029595521622402217227;\n uint256 constant C49 =\n 80103447810215150918585162168214870083573048458555897999822831203653996617;\n uint256 constant C50 =\n 8228820324013669567851850635126713973797711779951230446503353812192849106342;\n uint256 constant C51 =\n 5375851433746509614045812476958526065449377558695752132494533666370449415873;\n uint256 constant C52 =\n 12115998939203497346386774317892338270561208357481805380546938146796257365018;\n uint256 constant C53 =\n 9764067909645821279940531410531154041386008396840887338272986634350423466622;\n uint256 constant C54 =\n 8538708244538850542384936174629541085495830544298260335345008245230827876882;\n uint256 constant C55 =\n 7140127896620013355910287215441004676619168261422440177712039790284719613114;\n uint256 constant C56 =\n 14297402962228458726038826185823085337698917275385741292940049024977027409762;\n uint256 constant C57 =\n 6667115556431351074165934212337261254608231545257434281887966406956835140819;\n uint256 constant C58 =\n 20226761165244293291042617464655196752671169026542832236139342122602741090001;\n uint256 constant C59 =\n 12038289506489256655759141386763477208196694421666339040483042079632134429119;\n uint256 constant C60 =\n 19027757334170818571203982241812412991528769934917288000224335655934473717551;\n uint256 constant C61 =\n 16272152964456553579565580463468069884359929612321610357528838696790370074720;\n uint256 constant C62 =\n 2500392889689246014710135696485946334448570271481948765283016105301740284071;\n uint256 constant C63 =\n 8595254970528530312401637448610398388203855633951264114100575485022581946023;\n uint256 constant C64 =\n 11635945688914011450976408058407206367914559009113158286982919675551688078198;\n uint256 constant C65 =\n 614739068603482619581328040478536306925147663946742687395148680260956671871;\n uint256 constant C66 =\n 18692271780377861570175282183255720350972693125537599213951106550953176268753;\n uint256 constant C67 =\n 4987059230784976306647166378298632695585915319042844495357753339378260807164;\n uint256 constant C68 =\n 21851403978498723616722415377430107676258664746210815234490134600998983955497;\n uint256 constant C69 =\n 9830635451186415300891533983087800047564037813328875992115573428596207326204;\n uint256 constant C70 =\n 4842706106434537116860242620706030229206345167233200482994958847436425185478;\n uint256 constant C71 =\n 6422235064906823218421386871122109085799298052314922856340127798647926126490;\n uint256 constant C72 =\n 4564364104986856861943331689105797031330091877115997069096365671501473357846;\n uint256 constant C73 =\n 1944043894089780613038197112872830569538541856657037469098448708685350671343;\n uint256 constant C74 =\n 21179865974855950600518216085229498748425990426231530451599322283119880194955;\n uint256 constant C75 =\n 14296697761894107574369608843560006996183955751502547883167824879840894933162;\n uint256 constant C76 =\n 12274619649702218570450581712439138337725246879938860735460378251639845671898;\n uint256 constant C77 =\n 16371396450276899401411886674029075408418848209575273031725505038938314070356;\n uint256 constant C78 =\n 3702561221750983937578095019779188631407216522704543451228773892695044653565;\n uint256 constant C79 =\n 19721616877735564664624984774636557499099875603996426215495516594530838681980;\n uint256 constant C80 =\n 6383350109027696789969911008057747025018308755462287526819231672217685282429;\n uint256 constant C81 =\n 20860583956177367265984596617324237471765572961978977333122281041544719622905;\n uint256 constant C82 =\n 5766390934595026947545001478457407504285452477687752470140790011329357286275;\n uint256 constant C83 =\n 4043175758319898049344746138515323336207420888499903387536875603879441092484;\n uint256 constant C84 =\n 15579382179133608217098622223834161692266188678101563820988612253342538956534;\n uint256 constant C85 =\n 1864640783252634743892105383926602930909039567065240010338908865509831749824;\n uint256 constant C86 =\n 15943719865023133586707144161652035291705809358178262514871056013754142625673;\n uint256 constant C87 =\n 2326415993032390211558498780803238091925402878871059708106213703504162832999;\n uint256 constant C88 =\n 19995326402773833553207196590622808505547443523750970375738981396588337910289;\n uint256 constant C89 =\n 5143583711361588952673350526320181330406047695593201009385718506918735286622;\n uint256 constant C90 =\n 15436006486881920976813738625999473183944244531070780793506388892313517319583;\n uint256 constant C91 =\n 16660446760173633166698660166238066533278664023818938868110282615200613695857;\n uint256 constant C92 =\n 4966065365695755376133119391352131079892396024584848298231004326013366253934;\n uint256 constant C93 =\n 20683781957411705574951987677641476019618457561419278856689645563561076926702;\n uint256 constant C94 =\n 17280836839165902792086432296371645107551519324565649849400948918605456875699;\n uint256 constant C95 =\n 17045635513701208892073056357048619435743564064921155892004135325530808465371;\n uint256 constant C96 =\n 17055032967194400710390142791334572297458033582458169295920670679093585707295;\n uint256 constant C97 =\n 15727174639569115300068198908071514334002742825679221638729902577962862163505;\n uint256 constant C98 =\n 1001755657610446661315902885492677747789366510875120894840818704741370398633;\n uint256 constant C99 =\n 18638547332826171619311285502376343504539399518545103511265465604926625041234;\n uint256 constant C100 =\n 6751954224763196429755298529194402870632445298969935050224267844020826420799;\n uint256 constant C101 =\n 3526747115904224771452549517614107688674036840088422555827581348280834879405;\n uint256 constant C102 =\n 15705897908180497062880001271426561999724005008972544196300715293701537574122;\n uint256 constant C103 =\n 574386695213920937259007343820417029802510752426579750428758189312416867750;\n uint256 constant C104 =\n 15973040855000600860816974646787367136127946402908768408978806375685439868553;\n uint256 constant C105 =\n 20934130413948796333037139460875996342810005558806621330680156931816867321122;\n uint256 constant C106 =\n 6918585327145564636398173845411579411526758237572034236476079610890705810764;\n uint256 constant C107 =\n 14158163500813182062258176233162498241310167509137716527054939926126453647182;\n uint256 constant C108 =\n 4164602626597695668474100217150111342272610479949122406544277384862187287433;\n uint256 constant C109 =\n 12146526846507496913615390662823936206892812880963914267275606265272996025304;\n uint256 constant C110 =\n 10153527926900017763244212043512822363696541810586522108597162891799345289938;\n uint256 constant C111 =\n 13564663485965299104296214940873270349072051793008946663855767889066202733588;\n uint256 constant C112 =\n 5612449256997576125867742696783020582952387615430650198777254717398552960096;\n uint256 constant C113 =\n 12151885480032032868507892738683067544172874895736290365318623681886999930120;\n uint256 constant C114 =\n 380452237704664384810613424095477896605414037288009963200982915188629772177;\n uint256 constant C115 =\n 9067557551252570188533509616805287919563636482030947363841198066124642069518;\n uint256 constant C116 =\n 21280306817619711661335268484199763923870315733198162896599997188206277056900;\n uint256 constant C117 =\n 5567165819557297006750252582140767993422097822227408837378089569369734876257;\n uint256 constant C118 =\n 10411936321072105429908396649383171465939606386380071222095155850987201580137;\n uint256 constant C119 =\n 21338390051413922944780864872652000187403217966653363270851298678606449622266;\n uint256 constant C120 =\n 12156296560457833712186127325312904760045212412680904475497938949653569234473;\n uint256 constant C121 =\n 4271647814574748734312113971565139132510281260328947438246615707172526380757;\n uint256 constant C122 =\n 9061738206062369647211128232833114177054715885442782773131292534862178874950;\n uint256 constant C123 =\n 10134551893627587797380445583959894183158393780166496661696555422178052339133;\n uint256 constant C124 =\n 8932270237664043612366044102088319242789325050842783721780970129656616386103;\n uint256 constant C125 =\n 3339412934966886386194449782756711637636784424032779155216609410591712750636;\n uint256 constant C126 =\n 9704903972004596791086522314847373103670545861209569267884026709445485704400;\n uint256 constant C127 =\n 17467570179597572575614276429760169990940929887711661192333523245667228809456;\n uint256 constant M00 =\n 2910766817845651019878574839501801340070030115151021261302834310722729507541;\n uint256 constant M01 =\n 19727366863391167538122140361473584127147630672623100827934084310230022599144;\n uint256 constant M10 =\n 5776684794125549462448597414050232243778680302179439492664047328281728356345;\n uint256 constant M11 =\n 8348174920934122550483593999453880006756108121341067172388445916328941978568;\n\n function hash(\n uint256 input\n ) external pure override returns (uint256 result) {\n return _hash(input);\n }\n\n function _hash(uint256 input) internal pure returns (uint256 result) {\n assembly {\n // Poseidon parameters should be t = 2, RF = 8, RP = 56\n\n // We load the characteristic\n let q := Q\n\n // In zerokit implementation, if we pass inp = [a0,a1,..,an] to Poseidon what is effectively hashed is [0,a0,a1,..,an]\n // Note that a sequence of MIX-ARK involves 3 Bn254 field additions before the mulmod happens. Worst case we have a value corresponding to 2*(p-1) which is less than 2^256 and hence doesn't overflow\n //ROUND 0 - FULL\n let s0 := C0\n let s1 := add(input, C1)\n // SBOX\n let t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 1 - FULL\n s0 := add(s0, C2)\n s1 := add(s1, C3)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 2 - FULL\n s0 := add(s0, C4)\n s1 := add(s1, C5)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 3 - FULL\n s0 := add(s0, C6)\n s1 := add(s1, C7)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 4 - PARTIAL\n s0 := add(s0, C8)\n s1 := add(s1, C9)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 5 - PARTIAL\n s0 := add(s0, C10)\n s1 := add(s1, C11)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 6 - PARTIAL\n s0 := add(s0, C12)\n s1 := add(s1, C13)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 7 - PARTIAL\n s0 := add(s0, C14)\n s1 := add(s1, C15)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 8 - PARTIAL\n s0 := add(s0, C16)\n s1 := add(s1, C17)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 9 - PARTIAL\n s0 := add(s0, C18)\n s1 := add(s1, C19)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 10 - PARTIAL\n s0 := add(s0, C20)\n s1 := add(s1, C21)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 11 - PARTIAL\n s0 := add(s0, C22)\n s1 := add(s1, C23)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 12 - PARTIAL\n s0 := add(s0, C24)\n s1 := add(s1, C25)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 13 - PARTIAL\n s0 := add(s0, C26)\n s1 := add(s1, C27)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 14 - PARTIAL\n s0 := add(s0, C28)\n s1 := add(s1, C29)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 15 - PARTIAL\n s0 := add(s0, C30)\n s1 := add(s1, C31)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 16 - PARTIAL\n s0 := add(s0, C32)\n s1 := add(s1, C33)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 17 - PARTIAL\n s0 := add(s0, C34)\n s1 := add(s1, C35)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 18 - PARTIAL\n s0 := add(s0, C36)\n s1 := add(s1, C37)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 19 - PARTIAL\n s0 := add(s0, C38)\n s1 := add(s1, C39)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 20 - PARTIAL\n s0 := add(s0, C40)\n s1 := add(s1, C41)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 21 - PARTIAL\n s0 := add(s0, C42)\n s1 := add(s1, C43)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 22 - PARTIAL\n s0 := add(s0, C44)\n s1 := add(s1, C45)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 23 - PARTIAL\n s0 := add(s0, C46)\n s1 := add(s1, C47)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 24 - PARTIAL\n s0 := add(s0, C48)\n s1 := add(s1, C49)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 25 - PARTIAL\n s0 := add(s0, C50)\n s1 := add(s1, C51)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 26 - PARTIAL\n s0 := add(s0, C52)\n s1 := add(s1, C53)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 27 - PARTIAL\n s0 := add(s0, C54)\n s1 := add(s1, C55)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 28 - PARTIAL\n s0 := add(s0, C56)\n s1 := add(s1, C57)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 29 - PARTIAL\n s0 := add(s0, C58)\n s1 := add(s1, C59)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 30 - PARTIAL\n s0 := add(s0, C60)\n s1 := add(s1, C61)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 31 - PARTIAL\n s0 := add(s0, C62)\n s1 := add(s1, C63)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 32 - PARTIAL\n s0 := add(s0, C64)\n s1 := add(s1, C65)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 33 - PARTIAL\n s0 := add(s0, C66)\n s1 := add(s1, C67)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 34 - PARTIAL\n s0 := add(s0, C68)\n s1 := add(s1, C69)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 35 - PARTIAL\n s0 := add(s0, C70)\n s1 := add(s1, C71)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 36 - PARTIAL\n s0 := add(s0, C72)\n s1 := add(s1, C73)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 37 - PARTIAL\n s0 := add(s0, C74)\n s1 := add(s1, C75)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 38 - PARTIAL\n s0 := add(s0, C76)\n s1 := add(s1, C77)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 39 - PARTIAL\n s0 := add(s0, C78)\n s1 := add(s1, C79)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 40 - PARTIAL\n s0 := add(s0, C80)\n s1 := add(s1, C81)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 41 - PARTIAL\n s0 := add(s0, C82)\n s1 := add(s1, C83)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 42 - PARTIAL\n s0 := add(s0, C84)\n s1 := add(s1, C85)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 43 - PARTIAL\n s0 := add(s0, C86)\n s1 := add(s1, C87)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 44 - PARTIAL\n s0 := add(s0, C88)\n s1 := add(s1, C89)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 45 - PARTIAL\n s0 := add(s0, C90)\n s1 := add(s1, C91)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 46 - PARTIAL\n s0 := add(s0, C92)\n s1 := add(s1, C93)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 47 - PARTIAL\n s0 := add(s0, C94)\n s1 := add(s1, C95)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 48 - PARTIAL\n s0 := add(s0, C96)\n s1 := add(s1, C97)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 49 - PARTIAL\n s0 := add(s0, C98)\n s1 := add(s1, C99)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 50 - PARTIAL\n s0 := add(s0, C100)\n s1 := add(s1, C101)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 51 - PARTIAL\n s0 := add(s0, C102)\n s1 := add(s1, C103)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 52 - PARTIAL\n s0 := add(s0, C104)\n s1 := add(s1, C105)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 53 - PARTIAL\n s0 := add(s0, C106)\n s1 := add(s1, C107)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 54 - PARTIAL\n s0 := add(s0, C108)\n s1 := add(s1, C109)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 55 - PARTIAL\n s0 := add(s0, C110)\n s1 := add(s1, C111)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 56 - PARTIAL\n s0 := add(s0, C112)\n s1 := add(s1, C113)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 57 - PARTIAL\n s0 := add(s0, C114)\n s1 := add(s1, C115)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 58 - PARTIAL\n s0 := add(s0, C116)\n s1 := add(s1, C117)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 59 - PARTIAL\n s0 := add(s0, C118)\n s1 := add(s1, C119)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 60 - FULL\n s0 := add(s0, C120)\n s1 := add(s1, C121)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 61 - FULL\n s0 := add(s0, C122)\n s1 := add(s1, C123)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 62 - FULL\n s0 := add(s0, C124)\n s1 := add(s1, C125)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n t := add(mulmod(s0, M00, q), mulmod(s1, M01, q))\n s1 := add(mulmod(s0, M10, q), mulmod(s1, M11, q))\n s0 := t\n\n //ROUND 63 - FULL\n s0 := add(s0, C126)\n s1 := add(s1, C127)\n // SBOX\n t := mulmod(s0, s0, q)\n s0 := mulmod(mulmod(t, t, q), s0, q)\n t := mulmod(s1, s1, q)\n s1 := mulmod(mulmod(t, t, q), s1, q)\n // MIX\n s0 := mod(add(mulmod(s0, M00, q), mulmod(s1, M01, q)), q)\n\n result := s0\n }\n }\n}\n" - }, - "contracts/Rln.sol": { - "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.15;\n\nimport {IPoseidonHasher} from \"./PoseidonHasher.sol\";\n\ncontract RLN {\n /// @notice The deposit amount required to register as a member\n uint256 public immutable MEMBERSHIP_DEPOSIT;\n\n /// @notice The depth of the merkle tree\n uint256 public immutable DEPTH;\n\n /// @notice The size of the merkle tree, i.e 2^depth\n uint256 public immutable SET_SIZE;\n\n /// @notice The index of the next member to be registered\n uint256 public idCommitmentIndex;\n\n /// @notice The amount of eth staked by each member\n mapping(uint256 => uint256) public stakedAmounts;\n\n /// @notice The membership status of each member\n mapping(uint256 => bool) public members;\n\n /// @notice The Poseidon hasher contract\n IPoseidonHasher public poseidonHasher;\n\n /// Emitted when a new member is added to the set\n /// @param idCommitment The idCommitment of the member\n /// @param index The index of the member in the set\n event MemberRegistered(uint256 idCommitment, uint256 index);\n\n /// Emitted when a member is removed from the set\n /// @param idCommitment The idCommitment of the member\n event MemberWithdrawn(uint256 idCommitment);\n\n constructor(\n uint256 membershipDeposit,\n uint256 depth,\n address _poseidonHasher\n ) {\n MEMBERSHIP_DEPOSIT = membershipDeposit;\n DEPTH = depth;\n SET_SIZE = 1 << depth;\n poseidonHasher = IPoseidonHasher(_poseidonHasher);\n }\n\n /// Allows a user to register as a member\n /// @param idCommitment The idCommitment of the member\n function register(uint256 idCommitment) external payable {\n require(\n msg.value == MEMBERSHIP_DEPOSIT,\n \"RLN, register: membership deposit is not satisfied\"\n );\n _register(idCommitment, msg.value);\n }\n\n /// Allows batch registration of members\n /// @param idCommitments array of idCommitments\n function registerBatch(uint256[] calldata idCommitments) external payable {\n uint256 idCommitmentlen = idCommitments.length;\n require(idCommitmentlen > 0, \"RLN, registerBatch: batch size zero\");\n require(\n idCommitmentIndex + idCommitmentlen <= SET_SIZE,\n \"RLN, registerBatch: set is full\"\n );\n require(\n msg.value == MEMBERSHIP_DEPOSIT * idCommitmentlen,\n \"RLN, registerBatch: membership deposit is not satisfied\"\n );\n for (uint256 i = 0; i < idCommitmentlen; i++) {\n _register(idCommitments[i], msg.value / idCommitmentlen);\n }\n }\n\n /// Registers a member\n /// @param idCommitment The idCommitment of the member\n /// @param stake The amount of eth staked by the member\n function _register(uint256 idCommitment, uint256 stake) internal {\n require(\n !members[idCommitment],\n \"RLN, _register: member already registered\"\n );\n require(idCommitmentIndex < SET_SIZE, \"RLN, register: set is full\");\n\n members[idCommitment] = true;\n stakedAmounts[idCommitment] = stake;\n\n emit MemberRegistered(idCommitment, idCommitmentIndex);\n idCommitmentIndex += 1;\n }\n\n /// Allows a user to slash a batch of members\n /// @param secrets array of idSecretHashes\n /// @param receivers array of addresses to receive the funds\n function withdrawBatch(\n uint256[] calldata secrets,\n address payable[] calldata receivers\n ) external {\n uint256 batchSize = secrets.length;\n require(batchSize != 0, \"RLN, withdrawBatch: batch size zero\");\n require(\n batchSize == receivers.length,\n \"RLN, withdrawBatch: batch size mismatch receivers\"\n );\n for (uint256 i = 0; i < batchSize; i++) {\n _withdraw(secrets[i], receivers[i]);\n }\n }\n\n /// Allows a user to slash a member\n /// @param secret The idSecretHash of the member\n function withdraw(uint256 secret, address payable receiver) external {\n _withdraw(secret, receiver);\n }\n\n /// Slashes a member by removing them from the set, and transferring their\n /// stake to the receiver\n /// @param secret The idSecretHash of the member\n /// @param receiver The address to receive the funds\n function _withdraw(uint256 secret, address payable receiver) internal {\n require(\n receiver != address(0),\n \"RLN, _withdraw: empty receiver address\"\n );\n\n require(\n receiver != address(this),\n \"RLN, _withdraw: cannot withdraw to RLN\"\n );\n\n // derive idCommitment\n uint256 idCommitment = hash(secret);\n // check if member is registered\n require(members[idCommitment], \"RLN, _withdraw: member not registered\");\n\n // check if member has stake\n require(\n stakedAmounts[idCommitment] != 0,\n \"RLN, _withdraw: member has no stake\"\n );\n\n uint256 amountToTransfer = stakedAmounts[idCommitment];\n\n // delete member\n members[idCommitment] = false;\n stakedAmounts[idCommitment] = 0;\n\n // refund deposit\n receiver.transfer(amountToTransfer);\n\n emit MemberWithdrawn(idCommitment);\n }\n\n /// Hashes a value using the Poseidon hasher\n /// NOTE: The variant of Poseidon we use accepts only 1 input, assume n=2, and the second input is 0\n /// @param input The value to hash\n function hash(uint256 input) internal view returns (uint256) {\n return poseidonHasher.hash(input);\n }\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": false, - "runs": 200 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "devdoc", - "userdoc", - "storageLayout", - "evm.gasEstimates" - ], - "": ["ast"] - } - }, - "metadata": { - "useLiteralContent": true - }, - "remappings": [ - "ds-test/=lib/forge-std/lib/ds-test/src/", - "forge-std/=lib/forge-std/src/" - ] - } -} diff --git a/docs/index.md b/docs/index.md index b7181f7..0f449d3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -13,16 +13,16 @@ function verifyProof(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[2] inp ### hash ```solidity -function hash(uint256 input) external pure returns (uint256 result) +function hash(uint256[2] inputs) external pure returns (uint256 result) ``` -Hashes the input using the Poseidon hash function, n = 2, second input is the constant 0 +Hashes the input using the Poseidon hash function, n = 2 #### Parameters -| Name | Type | Description | -| ----- | ------- | ----------------- | -| input | uint256 | The input to hash | +| Name | Type | Description | +| ------ | ---------- | ----------------- | +| inputs | uint256[2] | The input to hash | ## PoseidonHasher @@ -32,819 +32,21 @@ Hashes the input using the Poseidon hash function, n = 2, second input is the co uint256 Q ``` -### C0 - -```solidity -uint256 C0 -``` - -### C1 - -```solidity -uint256 C1 -``` - -### C2 - -```solidity -uint256 C2 -``` - -### C3 - -```solidity -uint256 C3 -``` - -### C4 - -```solidity -uint256 C4 -``` - -### C5 - -```solidity -uint256 C5 -``` - -### C6 - -```solidity -uint256 C6 -``` - -### C7 - -```solidity -uint256 C7 -``` - -### C8 - -```solidity -uint256 C8 -``` - -### C9 - -```solidity -uint256 C9 -``` - -### C10 - -```solidity -uint256 C10 -``` - -### C11 - -```solidity -uint256 C11 -``` - -### C12 - -```solidity -uint256 C12 -``` - -### C13 - -```solidity -uint256 C13 -``` - -### C14 - -```solidity -uint256 C14 -``` - -### C15 - -```solidity -uint256 C15 -``` - -### C16 - -```solidity -uint256 C16 -``` - -### C17 - -```solidity -uint256 C17 -``` - -### C18 - -```solidity -uint256 C18 -``` - -### C19 - -```solidity -uint256 C19 -``` - -### C20 - -```solidity -uint256 C20 -``` - -### C21 - -```solidity -uint256 C21 -``` - -### C22 - -```solidity -uint256 C22 -``` - -### C23 - -```solidity -uint256 C23 -``` - -### C24 - -```solidity -uint256 C24 -``` - -### C25 - -```solidity -uint256 C25 -``` - -### C26 - -```solidity -uint256 C26 -``` - -### C27 - -```solidity -uint256 C27 -``` - -### C28 - -```solidity -uint256 C28 -``` - -### C29 - -```solidity -uint256 C29 -``` - -### C30 - -```solidity -uint256 C30 -``` - -### C31 - -```solidity -uint256 C31 -``` - -### C32 - -```solidity -uint256 C32 -``` - -### C33 - -```solidity -uint256 C33 -``` - -### C34 - -```solidity -uint256 C34 -``` - -### C35 - -```solidity -uint256 C35 -``` - -### C36 - -```solidity -uint256 C36 -``` - -### C37 - -```solidity -uint256 C37 -``` - -### C38 - -```solidity -uint256 C38 -``` - -### C39 - -```solidity -uint256 C39 -``` - -### C40 - -```solidity -uint256 C40 -``` - -### C41 - -```solidity -uint256 C41 -``` - -### C42 - -```solidity -uint256 C42 -``` - -### C43 - -```solidity -uint256 C43 -``` - -### C44 - -```solidity -uint256 C44 -``` - -### C45 - -```solidity -uint256 C45 -``` - -### C46 - -```solidity -uint256 C46 -``` - -### C47 - -```solidity -uint256 C47 -``` - -### C48 - -```solidity -uint256 C48 -``` - -### C49 - -```solidity -uint256 C49 -``` - -### C50 - -```solidity -uint256 C50 -``` - -### C51 - -```solidity -uint256 C51 -``` - -### C52 - -```solidity -uint256 C52 -``` - -### C53 - -```solidity -uint256 C53 -``` - -### C54 - -```solidity -uint256 C54 -``` - -### C55 - -```solidity -uint256 C55 -``` - -### C56 - -```solidity -uint256 C56 -``` - -### C57 - -```solidity -uint256 C57 -``` - -### C58 - -```solidity -uint256 C58 -``` - -### C59 - -```solidity -uint256 C59 -``` - -### C60 - -```solidity -uint256 C60 -``` - -### C61 - -```solidity -uint256 C61 -``` - -### C62 - -```solidity -uint256 C62 -``` - -### C63 - -```solidity -uint256 C63 -``` - -### C64 - -```solidity -uint256 C64 -``` - -### C65 - -```solidity -uint256 C65 -``` - -### C66 - -```solidity -uint256 C66 -``` - -### C67 - -```solidity -uint256 C67 -``` - -### C68 - -```solidity -uint256 C68 -``` - -### C69 - -```solidity -uint256 C69 -``` - -### C70 - -```solidity -uint256 C70 -``` - -### C71 - -```solidity -uint256 C71 -``` - -### C72 - -```solidity -uint256 C72 -``` - -### C73 - -```solidity -uint256 C73 -``` - -### C74 - -```solidity -uint256 C74 -``` - -### C75 - -```solidity -uint256 C75 -``` - -### C76 - -```solidity -uint256 C76 -``` - -### C77 - -```solidity -uint256 C77 -``` - -### C78 - -```solidity -uint256 C78 -``` - -### C79 - -```solidity -uint256 C79 -``` - -### C80 - -```solidity -uint256 C80 -``` - -### C81 - -```solidity -uint256 C81 -``` - -### C82 - -```solidity -uint256 C82 -``` - -### C83 - -```solidity -uint256 C83 -``` - -### C84 - -```solidity -uint256 C84 -``` - -### C85 - -```solidity -uint256 C85 -``` - -### C86 - -```solidity -uint256 C86 -``` - -### C87 - -```solidity -uint256 C87 -``` - -### C88 - -```solidity -uint256 C88 -``` - -### C89 - -```solidity -uint256 C89 -``` - -### C90 - -```solidity -uint256 C90 -``` - -### C91 - -```solidity -uint256 C91 -``` - -### C92 - -```solidity -uint256 C92 -``` - -### C93 - -```solidity -uint256 C93 -``` - -### C94 - -```solidity -uint256 C94 -``` - -### C95 - -```solidity -uint256 C95 -``` - -### C96 - -```solidity -uint256 C96 -``` - -### C97 - -```solidity -uint256 C97 -``` - -### C98 - -```solidity -uint256 C98 -``` - -### C99 - -```solidity -uint256 C99 -``` - -### C100 - -```solidity -uint256 C100 -``` - -### C101 - -```solidity -uint256 C101 -``` - -### C102 - -```solidity -uint256 C102 -``` - -### C103 - -```solidity -uint256 C103 -``` - -### C104 - -```solidity -uint256 C104 -``` - -### C105 - -```solidity -uint256 C105 -``` - -### C106 - -```solidity -uint256 C106 -``` - -### C107 - -```solidity -uint256 C107 -``` - -### C108 - -```solidity -uint256 C108 -``` - -### C109 - -```solidity -uint256 C109 -``` - -### C110 - -```solidity -uint256 C110 -``` - -### C111 - -```solidity -uint256 C111 -``` - -### C112 - -```solidity -uint256 C112 -``` - -### C113 - -```solidity -uint256 C113 -``` - -### C114 - -```solidity -uint256 C114 -``` - -### C115 - -```solidity -uint256 C115 -``` - -### C116 - -```solidity -uint256 C116 -``` - -### C117 - -```solidity -uint256 C117 -``` - -### C118 - -```solidity -uint256 C118 -``` - -### C119 - -```solidity -uint256 C119 -``` - -### C120 - -```solidity -uint256 C120 -``` - -### C121 - -```solidity -uint256 C121 -``` - -### C122 - -```solidity -uint256 C122 -``` - -### C123 - -```solidity -uint256 C123 -``` - -### C124 - -```solidity -uint256 C124 -``` - -### C125 - -```solidity -uint256 C125 -``` - -### C126 - -```solidity -uint256 C126 -``` - -### C127 - -```solidity -uint256 C127 -``` - -### M00 - -```solidity -uint256 M00 -``` - -### M01 - -```solidity -uint256 M01 -``` - -### M10 - -```solidity -uint256 M10 -``` - -### M11 - -```solidity -uint256 M11 -``` - ### hash ```solidity -function hash(uint256 input) external pure returns (uint256 result) +function hash(uint256[2] inputs) external pure returns (uint256 result) ``` -Hashes the input using the Poseidon hash function, n = 2, second input is the constant 0 +Hashes the input using the Poseidon hash function, n = 2 #### Parameters -| Name | Type | Description | -| ----- | ------- | ----------------- | -| input | uint256 | The input to hash | +| Name | Type | Description | +| ------ | ---------- | ----------------- | +| inputs | uint256[2] | The input to hash | -### \_hash - -```solidity -function _hash(uint256 input) internal pure returns (uint256 result) -``` - -## Rln +## RLN ### constructor @@ -1013,6 +215,14 @@ mapping(uint256 => uint256) members The membership status of each member maps from idCommitment to their index in the set +### memberExists + +```solidity +mapping(uint256 => bool) memberExists +``` + +The membership status of each member + ### withdrawalBalance ```solidity @@ -1045,6 +255,14 @@ uint32 deployedBlockNumber the deployed block number +### imtData + +```solidity +struct BinaryIMTData imtData +``` + +the Incremental Merkle Tree + ### MemberRegistered ```solidity @@ -1174,17 +392,17 @@ Allows a user to withdraw funds allocated to them upon slashing a member ### hash ```solidity -function hash(uint256 input) internal view returns (uint256) +function hash(uint256[2] inputs) internal view returns (uint256) ``` Hashes a value using the Poseidon hasher -NOTE: The variant of Poseidon we use accepts only 1 input, assume n=2, and the second input is 0 +NOTE: The variant of Poseidon we use accepts only 1 input, assume n=2 #### Parameters -| Name | Type | Description | -| ----- | ------- | ----------------- | -| input | uint256 | The value to hash | +| Name | Type | Description | +| ------ | ---------- | ------------------ | +| inputs | uint256[2] | The values to hash | ### isValidCommitment @@ -1200,6 +418,12 @@ function _verifyProof(uint256 idCommitment, address receiver, uint256[8] proof) _Groth16 proof verification_ +### computeRoot + +```solidity +function computeRoot() external view returns (uint256) +``` + ## Pairing ### G1Point diff --git a/test/poseidon.test.ts b/test/poseidon.test.ts index 1ef7146..83b68b5 100644 --- a/test/poseidon.test.ts +++ b/test/poseidon.test.ts @@ -10,12 +10,13 @@ describe("PoseidonHasher", () => { const poseidonHasher = await ethers.getContract("PoseidonHasher"); // We test hashing for a random number - const hash = await poseidonHasher.hash( - "19014214495641488759237505126948346942972912379615652741039992445865937985820" - ); + const hash = await poseidonHasher.hash([ + "19014214495641488759237505126948346942972912379615652741039992445865937985820", + "0", + ]); - expect(hash._hex).to.eql( - "0x0c3ac305f6a4fe9bfeb3eba978bc876e2a99208b8b56c80160cfb54ba8f02368" + expect(hash.toHexString()).to.eql( + "0x1d1ac5f6cf23b059eb43c657ce622b614b5960ea4b23f92d428d3e42982a4e13" ); }); }); diff --git a/test/rln.test.ts b/test/rln.test.ts index 73f3498..adc2501 100644 --- a/test/rln.test.ts +++ b/test/rln.test.ts @@ -7,7 +7,7 @@ describe("Rln", () => { }); it("should register new memberships", async () => { - const rln = await ethers.getContract("Rln", ethers.provider.getSigner(0)); + const rln = await ethers.getContract("RLN", ethers.provider.getSigner(0)); const price = await rln.MEMBERSHIP_DEPOSIT(); @@ -30,7 +30,7 @@ describe("Rln", () => { }); it("should slash membership", async () => { - const rln = await ethers.getContract("Rln", ethers.provider.getSigner(0)); + const rln = await ethers.getContract("RLN", ethers.provider.getSigner(0)); const price = await rln.MEMBERSHIP_DEPOSIT(); @@ -55,7 +55,7 @@ describe("Rln", () => { }); it("should not allow multiple registrations with same pubkey", async () => { - const rln = await ethers.getContract("Rln", ethers.provider.getSigner(0)); + const rln = await ethers.getContract("RLN", ethers.provider.getSigner(0)); const price = await rln.MEMBERSHIP_DEPOSIT();