// SPDX-License-Identifier: GPL-3.0 /* Copyright 2021 0KIMS association. This file is generated with [snarkJS](https://github.com/iden3/snarkjs). snarkJS is a free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. snarkJS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with snarkJS. If not, see . */ pragma solidity >=0.7.0 <0.9.0; contract HydraS3Verifier { // Scalar field size uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Base field size uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // Verification Key data uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042; uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958; uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132; uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731; uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679; uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856; uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634; uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; uint256 constant deltax1 = 5947204102927678610499403231647051947521117072329097157305165208669196293315; uint256 constant deltax2 = 14224678160608123428577879731596824888551385460032914677899463967517092526373; uint256 constant deltay1 = 17288202048179071253685552100101604797295876547572541738450181624714689114869; uint256 constant deltay2 = 149734489293243356395158312120537682710631495908615027499265582205314452224; uint256 constant IC0x = 15804039062076515439582959715370558033804154193866522341418754355668990462463; uint256 constant IC0y = 14939234806441587795059437678090138171548169820036013147603129099484876497888; uint256 constant IC1x = 17574099665254781488550735230757110542636506152573426744849028384901539447834; uint256 constant IC1y = 3927094394137710135730929374514051635184205592284228368582427365637193371478; uint256 constant IC2x = 9762792643860714667870459409829319206401350900356336674495197055016888347275; uint256 constant IC2y = 18011293241658362804015579521445734125489181919616086649848127919014030202617; uint256 constant IC3x = 12385252027129960806367476060506785456640618304875711338328852423495008033193; uint256 constant IC3y = 2256281551738685056734503912816912194783421393639894027582305404920448584611; uint256 constant IC4x = 12247901969505332851838456541737930986611048720900878028687799331466965383842; uint256 constant IC4y = 5115609312285538203135871902829659589761308200724699442187397112545827242173; uint256 constant IC5x = 11289605047556317740236530000963603385851604359744689361183618857858421877521; uint256 constant IC5y = 19122455760122586485775453836298363226577664525631024704803123477357473094043; uint256 constant IC6x = 2322876912700451715031374305648626862215611567247273525695988059790159746810; uint256 constant IC6y = 2833384466700074206789333374865206116513035916663953405111392576772057157895; uint256 constant IC7x = 16852621322621637269216093075383452648190232466483906496500195087093537821687; uint256 constant IC7y = 16325902168855819449916931199158908046645784592255315061212458299577977500520; uint256 constant IC8x = 9045291403758161491548366531866376141086206305461740421071148072806301607210; uint256 constant IC8y = 7799395230289644965330878409566581713230101235604913638470280886524557452953; uint256 constant IC9x = 10726025683042374714997923063769115768988772976131031693465276911424894725172; uint256 constant IC9y = 21790757495856406681981524211041114449350804812015195716893718875902541595802; uint256 constant IC10x = 13337209230583799459425148796693319956661189063060254833524470238213205422890; uint256 constant IC10y = 1597162274238127771814604231410975565645772671656985460391877169548544646597; uint256 constant IC11x = 20136331305168156006793572365329011003514170402815615710784798926522979694800; uint256 constant IC11y = 17567773802823829574949144493039157073893781951846322473131615675225838529142; uint256 constant IC12x = 13868116397658767466954299980068241431473329446954116983719941174605169496246; uint256 constant IC12y = 11930013804658906764937772303961699551383482058765795634756016067872875240002; uint256 constant IC13x = 19719975179921156451295023853307550118005040694701267473353189519853678396671; uint256 constant IC13y = 10634504646767467477946207833174471932211627037854767452071106721407106991734; uint256 constant IC14x = 21615447561552586718749473908482646469096544954209340826760900621642356459600; uint256 constant IC14y = 14223436823634552417735476264987577965820114975514698971620328268267537852060; // Memory data uint16 constant pVk = 0; uint16 constant pPairing = 128; uint16 constant pLastMem = 896; function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[14] calldata _pubSignals) public view returns (bool) { assembly { function checkField(v) { if iszero(lt(v, q)) { mstore(0, 0) return(0, 0x20) } } // G1 function to multiply a G1 value(x,y) to value in an address function g1_mulAccC(pR, x, y, s) { let success let mIn := mload(0x40) mstore(mIn, x) mstore(add(mIn, 32), y) mstore(add(mIn, 64), s) success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64) if iszero(success) { mstore(0, 0) return(0, 0x20) } mstore(add(mIn, 64), mload(pR)) mstore(add(mIn, 96), mload(add(pR, 32))) success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64) if iszero(success) { mstore(0, 0) return(0, 0x20) } } function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk { let _pPairing := add(pMem, pPairing) let _pVk := add(pMem, pVk) mstore(_pVk, IC0x) mstore(add(_pVk, 32), IC0y) // Compute the linear combination vk_x g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0))) g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32))) g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64))) g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96))) g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128))) g1_mulAccC(_pVk, IC6x, IC6y, calldataload(add(pubSignals, 160))) g1_mulAccC(_pVk, IC7x, IC7y, calldataload(add(pubSignals, 192))) g1_mulAccC(_pVk, IC8x, IC8y, calldataload(add(pubSignals, 224))) g1_mulAccC(_pVk, IC9x, IC9y, calldataload(add(pubSignals, 256))) g1_mulAccC(_pVk, IC10x, IC10y, calldataload(add(pubSignals, 288))) g1_mulAccC(_pVk, IC11x, IC11y, calldataload(add(pubSignals, 320))) g1_mulAccC(_pVk, IC12x, IC12y, calldataload(add(pubSignals, 352))) g1_mulAccC(_pVk, IC13x, IC13y, calldataload(add(pubSignals, 384))) g1_mulAccC(_pVk, IC14x, IC14y, calldataload(add(pubSignals, 416))) // -A mstore(_pPairing, calldataload(pA)) mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q)) // B mstore(add(_pPairing, 64), calldataload(pB)) mstore(add(_pPairing, 96), calldataload(add(pB, 32))) mstore(add(_pPairing, 128), calldataload(add(pB, 64))) mstore(add(_pPairing, 160), calldataload(add(pB, 96))) // alpha1 mstore(add(_pPairing, 192), alphax) mstore(add(_pPairing, 224), alphay) // beta2 mstore(add(_pPairing, 256), betax1) mstore(add(_pPairing, 288), betax2) mstore(add(_pPairing, 320), betay1) mstore(add(_pPairing, 352), betay2) // vk_x mstore(add(_pPairing, 384), mload(add(pMem, pVk))) mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32)))) // gamma2 mstore(add(_pPairing, 448), gammax1) mstore(add(_pPairing, 480), gammax2) mstore(add(_pPairing, 512), gammay1) mstore(add(_pPairing, 544), gammay2) // C mstore(add(_pPairing, 576), calldataload(pC)) mstore(add(_pPairing, 608), calldataload(add(pC, 32))) // delta2 mstore(add(_pPairing, 640), deltax1) mstore(add(_pPairing, 672), deltax2) mstore(add(_pPairing, 704), deltay1) mstore(add(_pPairing, 736), deltay2) let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20) isOk := and(success, mload(_pPairing)) } let pMem := mload(0x40) mstore(0x40, add(pMem, pLastMem)) // Validate that all evaluations ∈ F checkField(calldataload(add(_pubSignals, 0))) checkField(calldataload(add(_pubSignals, 32))) checkField(calldataload(add(_pubSignals, 64))) checkField(calldataload(add(_pubSignals, 96))) checkField(calldataload(add(_pubSignals, 128))) checkField(calldataload(add(_pubSignals, 160))) checkField(calldataload(add(_pubSignals, 192))) checkField(calldataload(add(_pubSignals, 224))) checkField(calldataload(add(_pubSignals, 256))) checkField(calldataload(add(_pubSignals, 288))) checkField(calldataload(add(_pubSignals, 320))) checkField(calldataload(add(_pubSignals, 352))) checkField(calldataload(add(_pubSignals, 384))) checkField(calldataload(add(_pubSignals, 416))) checkField(calldataload(add(_pubSignals, 448))) // Validate all evaluations let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) mstore(0, isValid) return(0, 0x20) } } }