// 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 PolicyVerifier { // Scalar field size uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // Base field size uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; // Verification Key data uint256 constant alphax = 16428432848801857252194528405604668803277877773566238944394625302971855135431; uint256 constant alphay = 16846502678714586896801519656441059708016666274385668027902869494772365009666; uint256 constant betax1 = 3182164110458002340215786955198810119980427837186618912744689678939861918171; uint256 constant betax2 = 16348171800823588416173124589066524623406261996681292662100840445103873053252; uint256 constant betay1 = 4920802715848186258981584729175884379674325733638798907835771393452862684714; uint256 constant betay2 = 19687132236965066906216944365591810874384658708175106803089633851114028275753; uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634; uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; uint256 constant deltax1 = 4726133483067958706709802054376008034544647925905911458094724357248269425799; uint256 constant deltax2 = 16072607094659115614547883967746239635504326278335334912006972513849098245839; uint256 constant deltay1 = 11203687531230926398535183926097597681756904825203494507227548973281272644444; uint256 constant deltay2 = 3604142255062465940096785427478914319895970277242814167053549440184150876314; uint256 constant IC0x = 14596213740275404235670177308736524800213025015847092451527839580894823380975; uint256 constant IC0y = 17692342733725574201661523082332715437848035399963642064683982297572226886192; uint256 constant IC1x = 19855141108994808551361904190639367832888411922132651065932795723181053827353; uint256 constant IC1y = 20158871534772080681423662248984772416011816977191731285201224806872022740575; uint256 constant IC2x = 15054821111638604363850561777316395132721810263067612358416801230424993837140; uint256 constant IC2y = 20190362383807582954786161338286035883343610918108072011809621466440790095741; uint256 constant IC3x = 7288522416678249207450067919903421038313341083803913698052603436872238123563; uint256 constant IC3y = 18739960816838753880788928931658046488717513711644952290883342422976549909538; uint256 constant IC4x = 16143105199493603157323248868324726675307446794350570555038388215369104009558; uint256 constant IC4y = 17575304910423956981622833038534133978399293287663128388379279267624190170908; uint256 constant IC5x = 10217164987127989880986188783490174469221357210289800766693431177548487762451; uint256 constant IC5y = 7951664889138236272874264565251578500606354032983464895388620201806735100345; uint256 constant IC6x = 8692861040499615340920833307062432476377871951565391268982713134058818302341; uint256 constant IC6y = 16907655871732347647682630112214032287817326705262806693049260757434540980584; uint256 constant IC7x = 15411931848299966898618942626030474842335407475292959122906958901165138643360; uint256 constant IC7y = 5753050594638939132950835267272287570677622107364105073970924063148395826791; uint256 constant IC8x = 9992376917652839215644365317522171757671909514426367302401159658994589687659; uint256 constant IC8y = 5264839808841237852579805696995950637598906720993610928520197516195107341948; uint256 constant IC9x = 13698523611227193061124527785931994875889312246602046391559468565331557975877; uint256 constant IC9y = 11489680914829368640606525547873202746008990594590867157813780798213171041226; uint256 constant IC10x = 4231096094726674014120844724357314399090896314222929930279866118010451583817; uint256 constant IC10y = 19677385851574864129461479023767291940247752563355858573885451702446593937175; uint256 constant IC11x = 4665527506454727850944788992351693288081149227457234132132333712280848200931; uint256 constant IC11y = 19275518772143820091266247203980319078406635829511452120389236215641513961135; uint256 constant IC12x = 17039823442749016887669520545613776316033953286926344253652713178506252478202; uint256 constant IC12y = 11736741093139356569303928483281861352228962024603663690679863342320647618293; uint256 constant IC13x = 12147922996722994921736290213899287186317154276348649730212195319304121098434; uint256 constant IC13y = 17269933126247646012364792478603636249569303872616962387504156733206221677644; uint256 constant IC14x = 20359575317751053700783838949517374730447017781760543913036377406204054944290; uint256 constant IC14y = 8139817555752545074241094876123899700403918850957499913428534422544643291061; uint256 constant IC15x = 5827980395934312856655499243189747389134143071693823935398893392918623477087; uint256 constant IC15y = 19447744770313586953633597643293475630571992245898505753338906368023246521197; uint256 constant IC16x = 6803864047950103925526618935373436673491045586180405569796486598473553724957; uint256 constant IC16y = 14003633053591184478907248663761759840026211685178175496302291455682497956488; uint256 constant IC17x = 2205999438998752607893832188233027943787636624485341517059474371696087343400; uint256 constant IC17y = 9932953834617427833389707369124388383010374558987734905657307711590063700869; uint256 constant IC18x = 12695057744829958612762789199157417800414687679991201721163953791664249245522; uint256 constant IC18y = 20230337522990724653558555386974365672284743780897933910103772660532783580540; uint256 constant IC19x = 2737681934655859936081340840520889998893201513366232300672499112835758192294; uint256 constant IC19y = 4165695845388381085796434470190086427879419366960052199380269690282488164335; uint256 constant IC20x = 3106129280984461560486743029868021692988649400939468151020743834876018655741; uint256 constant IC20y = 1949522400250521026857498875451897050094481678139745092022845733740920859721; uint256 constant IC21x = 11962561767553045831657655207720597203887639924741392059500726107792075490727; uint256 constant IC21y = 7186295383800015606928143505800712005375141657097269566317558283259448782705; uint256 constant IC22x = 16428524087010499444843408465340970439499164110859554840681375469192454721625; uint256 constant IC22y = 5024116712999564162257681687199620911218955063243468123484854209541817107266; uint256 constant IC23x = 6045924087587908171859366459399342879796968814906678635299118769706491910611; uint256 constant IC23y = 19744125962565248494782507766590443108440238066215455133795389882987288914808; uint256 constant IC24x = 3442142638100028356341071664999928172703386318330477375886615601964402441857; uint256 constant IC24y = 17926655910886645101020962622056848423670530831439147866602691188463166045986; uint256 constant IC25x = 14691131560345152165712985980059066514773437771739216312031312258194546829938; uint256 constant IC25y = 14182062641260265733864664255626414974132607976685368106198259366685828270760; uint256 constant IC26x = 333010478301987114145585006898842698647168805895020127629655456924805544705; uint256 constant IC26y = 9979815063596703497940363216544359073716643954764709391360277399276860194752; uint256 constant IC27x = 7885078741832725174723906537417405995281945663699932680617802951651667964436; uint256 constant IC27y = 11885679376286520570796688555800131314976582389744139121767841752424794716644; uint256 constant IC28x = 1606106332433915642247988558792737041272538971662677054773139254334258877566; uint256 constant IC28y = 8033795542531698537835261699717406298271282932234447277355978500759686618570; uint256 constant IC29x = 10694071858182173496301020651677494273262668763410820097689625833960047245142; uint256 constant IC29y = 12012071961173993880035786455661855278982054417573865972730836702281721752089; uint256 constant IC30x = 3762901654645611880572901147062390911058658773587503090441183525319682049297; uint256 constant IC30y = 6509396219299780963106428341357943769566399123511021370430950038696156258135; uint256 constant IC31x = 13822235771185164324515522317500726946868311247361396388263936469804949630469; uint256 constant IC31y = 6203337881418777259436942109863742269266320052551450915693864741725885883239; uint256 constant IC32x = 7959570412378560732377149437313385582701720128306380879317557644393741442873; uint256 constant IC32y = 21241535354147455857641573660704299459058909801053418646873671116001278707434; // 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[32] calldata _pubSignals) public view returns (bool) { assembly { function checkField(v) { if iszero(lt(v, r)) { 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))) g1_mulAccC(_pVk, IC15x, IC15y, calldataload(add(pubSignals, 448))) g1_mulAccC(_pVk, IC16x, IC16y, calldataload(add(pubSignals, 480))) g1_mulAccC(_pVk, IC17x, IC17y, calldataload(add(pubSignals, 512))) g1_mulAccC(_pVk, IC18x, IC18y, calldataload(add(pubSignals, 544))) g1_mulAccC(_pVk, IC19x, IC19y, calldataload(add(pubSignals, 576))) g1_mulAccC(_pVk, IC20x, IC20y, calldataload(add(pubSignals, 608))) g1_mulAccC(_pVk, IC21x, IC21y, calldataload(add(pubSignals, 640))) g1_mulAccC(_pVk, IC22x, IC22y, calldataload(add(pubSignals, 672))) g1_mulAccC(_pVk, IC23x, IC23y, calldataload(add(pubSignals, 704))) g1_mulAccC(_pVk, IC24x, IC24y, calldataload(add(pubSignals, 736))) g1_mulAccC(_pVk, IC25x, IC25y, calldataload(add(pubSignals, 768))) g1_mulAccC(_pVk, IC26x, IC26y, calldataload(add(pubSignals, 800))) g1_mulAccC(_pVk, IC27x, IC27y, calldataload(add(pubSignals, 832))) g1_mulAccC(_pVk, IC28x, IC28y, calldataload(add(pubSignals, 864))) g1_mulAccC(_pVk, IC29x, IC29y, calldataload(add(pubSignals, 896))) g1_mulAccC(_pVk, IC30x, IC30y, calldataload(add(pubSignals, 928))) g1_mulAccC(_pVk, IC31x, IC31y, calldataload(add(pubSignals, 960))) g1_mulAccC(_pVk, IC32x, IC32y, calldataload(add(pubSignals, 992))) // -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))) checkField(calldataload(add(_pubSignals, 480))) checkField(calldataload(add(_pubSignals, 512))) checkField(calldataload(add(_pubSignals, 544))) checkField(calldataload(add(_pubSignals, 576))) checkField(calldataload(add(_pubSignals, 608))) checkField(calldataload(add(_pubSignals, 640))) checkField(calldataload(add(_pubSignals, 672))) checkField(calldataload(add(_pubSignals, 704))) checkField(calldataload(add(_pubSignals, 736))) checkField(calldataload(add(_pubSignals, 768))) checkField(calldataload(add(_pubSignals, 800))) checkField(calldataload(add(_pubSignals, 832))) checkField(calldataload(add(_pubSignals, 864))) checkField(calldataload(add(_pubSignals, 896))) checkField(calldataload(add(_pubSignals, 928))) checkField(calldataload(add(_pubSignals, 960))) checkField(calldataload(add(_pubSignals, 992))) // Validate all evaluations let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) mstore(0, isValid) return(0, 0x20) } } }