Skip to content

Commit

Permalink
Merge pull request #70 from hyperledger-labs/an-enc-nul-kyc
Browse files Browse the repository at this point in the history
adding an example for supporting KYC in the token with nullifier with encryption values
  • Loading branch information
jimthematrix authored Sep 18, 2024
2 parents c6ff39b + 8f1250e commit e0427b0
Show file tree
Hide file tree
Showing 15 changed files with 2,227 additions and 26 deletions.
16 changes: 8 additions & 8 deletions solidity/contracts/lib/verifier_anon_enc.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ contract Groth16Verifier_AnonEnc {
uint256 constant IC0x = 5696326670703652601376328914723856805804139150397636629981154943267586835846;
uint256 constant IC0y = 17913431813079674015620165360736989993822627917830194405007674349883405519566;

uint256 constant IC1x = 15825765194464726182776026234639522157004618110842020817264286413596445235307;
uint256 constant IC1y = 2401477487480347699703028792091325200698394178743640467196981936283298710021;
uint256 constant IC1x = 2102562587253616254650248571898720579563063454685611900201869023012028011038;
uint256 constant IC1y = 858837120372047227699859025595943051604219338012183710955972141361344096680;

uint256 constant IC2x = 17823254154132200329306690888156067227498822342519393685861534093309766001383;
uint256 constant IC2y = 14804040920166770014088667887230353137747938842993092323563528559936821334324;
uint256 constant IC2x = 19871902121561448541783335513612822391415363559792595451397804594141318386828;
uint256 constant IC2y = 14203964380144242038882743638980469366132880555873818345914201687170773944754;

uint256 constant IC3x = 18619661077507789630281262029605339062675871751807780618791872378570042056116;
uint256 constant IC3y = 18692831968495678168274986594838227336308377551834418943816657968243321416157;
uint256 constant IC3x = 4534338244167504974683945726615729215678954323916000129150608047181600075942;
uint256 constant IC3y = 9004530693581096650487103914238080672423858350236817229254519649589395343912;

uint256 constant IC4x = 8481249797936633465645328566302395583826148290507195864467073391607936154307;
uint256 constant IC4y = 4631061052012679777402506942756063974564041904906197227863591152456358430540;
uint256 constant IC4x = 16926200767829183396766074136228821955738540059328214039731068817771880630127;
uint256 constant IC4y = 15535238050385142389806452090946716626530242126040333805866336792975972380578;

uint256 constant IC5x = 269115022971501175992618085182824077406065858697651888560831707201556157978;
uint256 constant IC5y = 19699073094724988754117299114476621695804537148277402334737306097425629024180;
Expand Down
16 changes: 8 additions & 8 deletions solidity/contracts/lib/verifier_anon_enc_nullifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ contract Groth16Verifier_AnonEncNullifier {
uint256 constant IC0x = 19712575420668268335634440622054263372704657131549679423053748840610444649065;
uint256 constant IC0y = 21552018618280422667464008645151951952543569291144282502207358485399703168568;

uint256 constant IC1x = 8879640517323472103773105774693203238739849734532829129136892239475022333668;
uint256 constant IC1y = 8763769862439095053692831300380880413523736171679197931386220812298104316000;
uint256 constant IC1x = 21152648367462137565411101477610760889415992049938974004172633386627195379833;
uint256 constant IC1y = 17526913059347331839566720566403027766484314611214702153099182458740108823;

uint256 constant IC2x = 938844563415264744387226778430871504680270942210685580230120080929277918399;
uint256 constant IC2y = 9128906501228717785843913573881993155178978243801248472013755207523145161265;
uint256 constant IC2x = 5554249810657633166990745736699774333938659965451342592982728994998805456417;
uint256 constant IC2y = 9730676046857216859008721613182313555756289801254042508531677626774346999622;

uint256 constant IC3x = 15866014959526954538183423799071681422553639776348384721828133108069370471390;
uint256 constant IC3y = 17150051530085128616371619156987380853738195686559145384648523741607899076676;
uint256 constant IC3x = 16411770669872316544841615427270736472060848758458781353444450000872952405569;
uint256 constant IC3y = 3883712029134278704236321509155602434293779347341551692030084302663589933567;

uint256 constant IC4x = 16628587721511911382464102713531591331106282985537150732913149203131020489047;
uint256 constant IC4y = 15415751731187982732941102993178329101138735638465538195218064540808443483176;
uint256 constant IC4x = 7689756896440471053876099704125828625789315755353261183292592808881136591701;
uint256 constant IC4y = 8154637307804119872460314948142196702392444351248969101164117581937044926170;

uint256 constant IC5x = 12299330364713292827284970278663419727424821736280679334696618553775046366194;
uint256 constant IC5y = 21075649501958706881669057145213727696785798949405955661717827102964559861134;
Expand Down
254 changes: 254 additions & 0 deletions solidity/contracts/lib/verifier_anon_enc_nullifier_kyc.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
// 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 <https://www.gnu.org/licenses/>.
*/

pragma solidity >=0.7.0 <0.9.0;

contract Groth16Verifier_AnonEncNullifierKyc {
// 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 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
uint256 constant deltax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
uint256 constant deltay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
uint256 constant deltay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;


uint256 constant IC0x = 9571444203847882263349163823295111750012388583457810565732023354927681835330;
uint256 constant IC0y = 8269430673392355800760839451470053559913816443341643262118006327992857911204;

uint256 constant IC1x = 4171425333877223863056817685674841454723358686631303251580406544847360463144;
uint256 constant IC1y = 15508434706912610115961511481609592716639093445421134335652880195025374357944;

uint256 constant IC2x = 2805234997490797748511701790284534458659062187129667755544299868178828988756;
uint256 constant IC2y = 12737871927823892823240455203969207068418359360382939881586564793007265918634;

uint256 constant IC3x = 10037927645989308427370729946962854922194022862178974033089345641900642443287;
uint256 constant IC3y = 1869974150112738935511161628734764742128849823652210548167483049626273686915;

uint256 constant IC4x = 20687486203577926209406522416577489369623505298901447042889614462294165837937;
uint256 constant IC4y = 2451926520013626473243440086333573559066473857550647156934680886755185047100;

uint256 constant IC5x = 17506157096475522989244923493066068666613854999605413994180693698287006754601;
uint256 constant IC5y = 18337141315691397667266548067044460253572013083720894042089481649614687489349;

uint256 constant IC6x = 13169264733918854243504094459072017908892434194925230289069972473474865423260;
uint256 constant IC6y = 12873033270668213434072395062604551402080299183418425353301844285688316634747;

uint256 constant IC7x = 4139352737455682815820399999502807530902270791132588001997383898128565726560;
uint256 constant IC7y = 18130358037765445238866373406538395199727660880929816773059128417420908294103;

uint256 constant IC8x = 10242723724534050633824073816542552050545643197784462676335615048377039832420;
uint256 constant IC8y = 1522077533586266907104192963207500158509684879768383246564448114116860886045;

uint256 constant IC9x = 9331953561001587156072982617181494822635260561293948857418310817015123003664;
uint256 constant IC9y = 21434180133029315517714324102175079176171466970274711902142297829796086888419;

uint256 constant IC10x = 9864640468360420795111662135353906469273928885319595720979255522131895987062;
uint256 constant IC10y = 4347845420812651539643028407865491584531559916191524645768616247857747093924;

uint256 constant IC11x = 12816855581744969923196393315369134257252339197623955937790101684782832727528;
uint256 constant IC11y = 10852386397854977410896573210092846697497925902496902459833247615681245355742;

uint256 constant IC12x = 14713198324057425181537280290297404746877953868974288063529731081142062871032;
uint256 constant IC12y = 12697331297870828686780559216672799476293214005074082773567772130976271883336;

uint256 constant IC13x = 15748313782243366848688530768530734630700786383695534160287365098087100629526;
uint256 constant IC13y = 19624787309979166735737404819294173148608360816934232838701010568600344101162;


// 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[13] 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)))


// -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)))


// Validate all evaluations
let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)

mstore(0, isValid)
return(0, 0x20)
}
}
}
Loading

0 comments on commit e0427b0

Please sign in to comment.