rln-interep-contract/deployments/goerli/solcInputs/8b4ce4f50b3f4c16f7b5cbd084d87412.json
2022-12-02 15:25:17 +05:30

64 lines
61 KiB
JSON

{
"language": "Solidity",
"sources": {
"@appliedzkp/semaphore-contracts/base/SemaphoreConstants.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nuint256 constant SNARK_SCALAR_FIELD = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n"
},
"@appliedzkp/semaphore-contracts/base/SemaphoreCore.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"../interfaces/ISemaphoreCore.sol\";\nimport \"../interfaces/IVerifier.sol\";\n\n/// @title Semaphore core contract.\n/// @notice Minimal code to allow users to signal their endorsement of an arbitrary string.\n/// @dev The following code verifies that the proof is correct and saves the hash of the\n/// nullifier to prevent double-signaling. External nullifier and Merkle trees (i.e. groups) must be\n/// managed externally.\ncontract SemaphoreCore is ISemaphoreCore {\n /// @dev Gets a nullifier hash and returns true or false.\n /// It is used to prevent double-signaling.\n mapping(uint256 => bool) internal nullifierHashes;\n\n /// @dev Asserts that no nullifier already exists and if the zero-knowledge proof is valid.\n /// Otherwise it reverts.\n /// @param signal: Semaphore signal.\n /// @param root: Root of the Merkle tree.\n /// @param nullifierHash: Nullifier hash.\n /// @param externalNullifier: External nullifier.\n /// @param proof: Zero-knowledge proof.\n /// @param verifier: Verifier address.\n function _verifyProof(\n bytes32 signal,\n uint256 root,\n uint256 nullifierHash,\n uint256 externalNullifier,\n uint256[8] calldata proof,\n IVerifier verifier\n ) internal view {\n require(!nullifierHashes[nullifierHash], \"SemaphoreCore: you cannot use the same nullifier twice\");\n\n uint256 signalHash = _hashSignal(signal);\n\n verifier.verifyProof(\n [proof[0], proof[1]],\n [[proof[2], proof[3]], [proof[4], proof[5]]],\n [proof[6], proof[7]],\n [root, nullifierHash, signalHash, externalNullifier]\n );\n }\n\n /// @dev Stores the nullifier hash to prevent double-signaling.\n /// Attention! Remember to call it when you verify a proof if you\n /// need to prevent double-signaling.\n /// @param nullifierHash: Semaphore nullifier hash.\n function _saveNullifierHash(uint256 nullifierHash) internal {\n nullifierHashes[nullifierHash] = true;\n }\n\n /// @dev Creates a keccak256 hash of the signal.\n /// @param signal: Semaphore signal.\n /// @return Hash of the signal.\n function _hashSignal(bytes32 signal) private pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(signal))) >> 8;\n }\n}\n"
},
"@appliedzkp/semaphore-contracts/interfaces/ISemaphoreCore.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @title SemaphoreCore interface.\n/// @dev Interface of SemaphoreCore contract.\ninterface ISemaphoreCore {\n /// @notice Emitted when a proof is verified correctly and a new nullifier hash is added.\n /// @param nullifierHash: Hash of external and identity nullifiers.\n event NullifierHashAdded(uint256 nullifierHash);\n}\n"
},
"@appliedzkp/semaphore-contracts/interfaces/IVerifier.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @title Verifier interface.\n/// @dev Interface of Verifier contract.\ninterface IVerifier {\n function verifyProof(\n uint256[2] memory a,\n uint256[2][2] memory b,\n uint256[2] memory c,\n uint256[4] memory input\n ) external view;\n}\n"
},
"@interep/contracts/IInterep.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @title Interep interface.\n/// @dev Interface of a Interep contract.\ninterface IInterep {\n struct Verifier {\n address contractAddress;\n uint8 merkleTreeDepth;\n }\n\n struct Group {\n bytes32 provider;\n bytes32 name;\n uint256 root;\n uint8 depth;\n }\n\n /// @dev Emitted when a Semaphore proof is verified.\n /// @param groupId: Id of the group.\n /// @param signal: Semaphore signal.\n event ProofVerified(uint256 indexed groupId, bytes32 signal);\n\n /// @dev Emitted when an Interep group is updated.\n /// @param groupId: Id of the group.\n /// @param provider: Provider of the group.\n /// @param name: Name of the group.\n /// @param root: Root hash of the tree.\n /// @param depth: Depth of the tree.\n event GroupUpdated(\n uint256 groupId,\n bytes32 indexed provider,\n bytes32 indexed name,\n uint256 root,\n uint8 indexed depth\n );\n\n /// @dev Updates the Interep groups.\n /// @param groups: List of Interep groups.\n function updateGroups(Group[] calldata groups) external;\n\n /// @dev Saves the nullifier hash to avoid double signaling and emits an event\n /// if the zero-knowledge proof is valid.\n /// @param groupId: Id of the group.\n /// @param signal: Semaphore signal.\n /// @param nullifierHash: Nullifier hash.\n /// @param externalNullifier: External nullifier.\n /// @param proof: Zero-knowledge proof.\n function verifyProof(\n uint256 groupId,\n bytes32 signal,\n uint256 nullifierHash,\n uint256 externalNullifier,\n uint256[8] calldata proof\n ) external;\n\n /// @dev Returns the root hash of an Interep group.\n /// @param groupId: Id of the group.\n /// @return Root hash of the group.\n function getRoot(uint256 groupId) external view returns (uint256);\n\n /// @dev Returns the tree depth of an Interep group.\n /// @param groupId: Id of the group.\n /// @return Tree depth of the group.\n function getDepth(uint256 groupId) external view returns (uint8);\n}\n"
},
"@interep/contracts/Interep.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"./IInterep.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@appliedzkp/semaphore-contracts/interfaces/IVerifier.sol\";\nimport \"@appliedzkp/semaphore-contracts/base/SemaphoreCore.sol\";\nimport \"@appliedzkp/semaphore-contracts/base/SemaphoreConstants.sol\";\n\n/// @title Interep\n/// @dev Interep is a collection of reputation Semaphore groups in which members\n/// can prove their Web2 reputation (or their membership in a group) without revealing their identity.\n/// Each Interep group is actually a Merkle tree, whose leaves represent the members of the group.\n/// Interep groups are saved off-chain but the Merkle tree roots of those groups are saved on-chain\n/// at regular intervals, so that users can verify their Semaphore ZK proof on-chain with this contract.\ncontract Interep is IInterep, Ownable, SemaphoreCore {\n /// @dev Gets a tree depth and returns its verifier address.\n mapping(uint8 => IVerifier) public verifiers;\n\n /// @dev Gets a group id and returns the group data.\n mapping(uint256 => Group) public groups;\n\n /// @dev Checks if there is a verifier for the given tree depth.\n /// @param depth: Depth of the tree.\n modifier onlySupportedDepth(uint8 depth) {\n require(address(verifiers[depth]) != address(0), \"Interep: tree depth is not supported\");\n _;\n }\n\n /// @dev Initializes the Semaphore verifiers used to verify the user's ZK proofs.\n /// @param _verifiers: List of Semaphore verifiers (address and related Merkle tree depth).\n constructor(Verifier[] memory _verifiers) {\n for (uint8 i = 0; i < _verifiers.length; i++) {\n verifiers[_verifiers[i].merkleTreeDepth] = IVerifier(_verifiers[i].contractAddress);\n }\n }\n\n /// @dev See {IInterep-updateGroups}.\n function updateGroups(Group[] calldata _groups) external override onlyOwner {\n for (uint8 i = 0; i < _groups.length; i++) {\n uint256 groupId = uint256(keccak256(abi.encodePacked(_groups[i].provider, _groups[i].name))) %\n SNARK_SCALAR_FIELD;\n\n _updateGroup(groupId, _groups[i]);\n }\n }\n\n /// @dev See {IInterep-verifyProof}.\n function verifyProof(\n uint256 groupId,\n bytes32 signal,\n uint256 nullifierHash,\n uint256 externalNullifier,\n uint256[8] calldata proof\n ) external override {\n uint256 root = getRoot(groupId);\n uint8 depth = getDepth(groupId);\n\n require(depth != 0, \"Interep: group does not exist\");\n\n IVerifier verifier = verifiers[depth];\n\n _verifyProof(signal, root, nullifierHash, externalNullifier, proof, verifier);\n\n _saveNullifierHash(nullifierHash);\n\n emit ProofVerified(groupId, signal);\n }\n\n /// @dev See {IInterep-getRoot}.\n function getRoot(uint256 groupId) public view override returns (uint256) {\n return groups[groupId].root;\n }\n\n /// @dev See {IInterep-getDepth}.\n function getDepth(uint256 groupId) public view override returns (uint8) {\n return groups[groupId].depth;\n }\n\n /// @dev Updates an Interep group.\n /// @param groupId: Id of the group.\n /// @param group: Group data.\n function _updateGroup(uint256 groupId, Group calldata group) private onlySupportedDepth(group.depth) {\n groups[groupId] = group;\n\n emit GroupUpdated(groupId, group.provider, group.name, group.root, group.depth);\n }\n}\n"
},
"@openzeppelin/contracts/access/Ownable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n"
},
"@openzeppelin/contracts/utils/Context.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n"
},
"contracts/PoseidonHasher.sol": {
"content": "// SPDX-License-Identifier: MIT\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\npragma solidity 0.8.15;\n\nimport {IPoseidonHasher} from \"./PoseidonHasher.sol\";\nimport {IValidGroupStorage} from \"./ValidGroupStorage.sol\";\nimport {IInterep} from \"@interep/contracts/IInterep.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 IValidGroupStorage public validGroupStorage;\n IInterep public interep;\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 address _validGroupStorage\n ) {\n MEMBERSHIP_DEPOSIT = membershipDeposit;\n DEPTH = depth;\n SET_SIZE = 1 << depth;\n poseidonHasher = IPoseidonHasher(_poseidonHasher);\n validGroupStorage = IValidGroupStorage(_validGroupStorage);\n interep = IInterep(validGroupStorage.interep());\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 /// @dev Registers a member via a valid Interep Semaphore group.\n /// @param groupId: Id of the group.\n /// @param signal: Semaphore signal.\n /// @param nullifierHash: Nullifier hash.\n /// @param externalNullifier: External nullifier.\n /// @param proof: Zero-knowledge proof.\n /// @param idCommitment: ID Commitment of the member.\n function register(\n uint256 groupId,\n bytes32 signal,\n uint256 nullifierHash,\n uint256 externalNullifier,\n uint256[8] calldata proof,\n uint256 idCommitment\n ) external {\n require(\n validGroupStorage.isValidGroup(groupId),\n \"RLN, register: invalid interep group\"\n );\n interep.verifyProof(\n groupId,\n signal,\n nullifierHash,\n externalNullifier,\n proof\n );\n _register(idCommitment, 0);\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 // refund deposit\n (bool sent, ) = receiver.call{value: stakedAmounts[idCommitment]}(\"\");\n require(sent, \"transfer failed\");\n\n // delete member\n members[idCommitment] = false;\n stakedAmounts[idCommitment] = 0;\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"
},
"contracts/ValidGroupStorage.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"@interep/contracts/Interep.sol\";\n\ninterface IValidGroupStorage {\n function isValidGroup(uint256 groupId) external view returns (bool);\n\n function interep() external view returns (address);\n}\n\ncontract ValidGroupStorage {\n mapping(uint256 => bool) public validGroups;\n\n Interep public interep;\n\n struct Group {\n bytes32 provider;\n bytes32 name;\n }\n\n constructor(address _interep, Group[] memory _groups) {\n interep = Interep(_interep);\n for (uint8 i = 0; i < _groups.length; i++) {\n uint256 groupId = uint256(\n keccak256(\n abi.encodePacked(_groups[i].provider, _groups[i].name)\n )\n ) % SNARK_SCALAR_FIELD;\n (bytes32 provider, bytes32 name, , ) = interep.groups(groupId);\n if (provider == _groups[i].provider && name == _groups[i].name) {\n validGroups[groupId] = true;\n } else {\n revert(\"[ValidGroupStorage] Invalid group\");\n }\n }\n }\n\n function isValidGroup(uint256 _groupId) public view returns (bool) {\n return validGroups[_groupId];\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
}
}
}