From fe5de0332c3e832cf9542bda353ead1e2353eabf Mon Sep 17 00:00:00 2001 From: ilya-korotya Date: Thu, 23 Jan 2025 17:37:30 +0100 Subject: [PATCH] add additional checks; use issuance and expiration date from a circuit --- .../Groth16VerifierAnonAadhaarV1.sol | 32 ++++----- .../validators/AnonAadhaarV1Validator.sol | 40 +++++------ .../AnonAadhaarCredentialIssuing.sol | 71 ++++++++----------- helpers/DeployAnonAadharV1Validator.ts | 2 + .../sig/data/anon_aadhaar_proof.json | 26 +++---- test/verifier/anonAadhaarVerifier.test.ts | 2 +- 6 files changed, 83 insertions(+), 90 deletions(-) diff --git a/contracts/lib/groth16-verifiers/Groth16VerifierAnonAadhaarV1.sol b/contracts/lib/groth16-verifiers/Groth16VerifierAnonAadhaarV1.sol index 38fb527d..5e8f4bd6 100644 --- a/contracts/lib/groth16-verifiers/Groth16VerifierAnonAadhaarV1.sol +++ b/contracts/lib/groth16-verifiers/Groth16VerifierAnonAadhaarV1.sol @@ -37,10 +37,10 @@ contract Groth16VerifierAnonAadhaarV1 { uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; - uint256 constant deltax1 = 9752776248207923469867409382048716372612962508996673790438054623489759145780; - uint256 constant deltax2 = 9452966396337616788385483674588918865821745355579743187934167481883534967251; - uint256 constant deltay1 = 15208746120897712994584783416569201488530823308245332170362178262653051227153; - uint256 constant deltay2 = 1743063522514331149547203759617585666894492323061121432061356664097165019185; + uint256 constant deltax1 = 6478079098059644794955489442566644082399176810697800518011658098436917498892; + uint256 constant deltax2 = 20533572760095723474804352875860557301543433536962581034908820797172322919807; + uint256 constant deltay1 = 21245386610249170698116968675572587783674227146275757743664420681565081182869; + uint256 constant deltay2 = 10386730275318211024690558808663725078794784230034325529798577332498117576072; uint256 constant IC0x = 17202926283251598065231527376648019777623479314208943009386780888674303306367; @@ -52,23 +52,23 @@ contract Groth16VerifierAnonAadhaarV1 { uint256 constant IC2x = 8036455770137753300143301227052694753324655839004232562996994892756513744632; uint256 constant IC2y = 19136034516434561880116093412780628312815490220057647258792780777662444980579; - uint256 constant IC3x = 5706924235985036010295393494457870846665277481967479020222798374799047750256; - uint256 constant IC3y = 16335939767066344430970552411852108062971274211549461481263778305792680100688; + uint256 constant IC3x = 3940442621650413591068983245374150864513505919882828343063027081870992672761; + uint256 constant IC3y = 7309919931871551410757199630839777809199591660985793683310544750437874161098; - uint256 constant IC4x = 13362589808591082140154747717874938555566489737803726066109447908122332925248; - uint256 constant IC4y = 9533438191675367092873436171711161489331286873030419565001344655397871220342; + uint256 constant IC4x = 10195331611021692472002731464401822839965166489723331490625092654889335583774; + uint256 constant IC4y = 19736440280356731084887534771210193326516566628844380828000492447515522809993; - uint256 constant IC5x = 13606256073504308111394692719682918711474465633647202003403244063200398917656; - uint256 constant IC5y = 14074028033425546109580220784064373333536645170395823067627266760390456677393; + uint256 constant IC5x = 3967155256782991249497585330191610561634502566674424879624925810217490423888; + uint256 constant IC5y = 15858272309356719696591759833930043302501532122945137158462648437557232384225; - uint256 constant IC6x = 19096454032987284766595414848523440262913762053347052157186315602771633028839; - uint256 constant IC6y = 7276871217582302819620304900124070838673347672010981352688103755427813080463; + uint256 constant IC6x = 7942070049450027541861350701118353357568652203105370276041780340149721843166; + uint256 constant IC6y = 16314754584929173994990441055634310785842943985191344219819711057929556703221; - uint256 constant IC7x = 18459111221168914001640566342970864469601586632412046593346422818505556097195; - uint256 constant IC7y = 13100409853915252749737243319212327344620678393375462514810315616945336813081; + uint256 constant IC7x = 12471793991455189963585506426348025959650699796756002643337958427707643190711; + uint256 constant IC7y = 620400864296017290847650472076831719497052851618961801788210097425840826937; - uint256 constant IC8x = 9200173373433970145496240930187071045143369120243275026153868648172499323668; - uint256 constant IC8y = 7200362604079959194735981300560157143070925411981289227281356488895967807761; + uint256 constant IC8x = 8675771110852571397974598172419706929408516907379806631819260814303924703171; + uint256 constant IC8y = 13191500661270068116297073198636128655542165578063411215254177784841051928165; uint256 constant IC9x = 14814413443159487223931208725152452842059865722271281787555352116049799452733; uint256 constant IC9y = 17373462594478087004748496082618076921959076827177568046785097901984202939893; diff --git a/contracts/validators/AnonAadhaarV1Validator.sol b/contracts/validators/AnonAadhaarV1Validator.sol index 6e18e32f..2b8226aa 100644 --- a/contracts/validators/AnonAadhaarV1Validator.sol +++ b/contracts/validators/AnonAadhaarV1Validator.sol @@ -13,12 +13,12 @@ contract AnonAadhaarV1Validator is CredentialAtomicQueryValidatorBase { struct PubSignals { uint256 pubKeyHash; uint256 nullifier; - uint256 claimRoot; uint256 hashIndex; uint256 hashValue; + uint256 issuanceDate; + uint256 expirationDate; uint256 nullifierSeed; uint256 signalHash; - uint256 expirationDate; uint256 templateRoot; } /** @@ -39,12 +39,12 @@ contract AnonAadhaarV1Validator is CredentialAtomicQueryValidatorBase { ) public initializer { _setInputToIndex("pubKeyHash", 0); _setInputToIndex("nullifier", 1); - _setInputToIndex("claimRoot", 2); - _setInputToIndex("hashIndex", 3); - _setInputToIndex("hashValue", 4); - _setInputToIndex("nullifierSeed", 5); - _setInputToIndex("signalHash", 6); - _setInputToIndex("expirationDate", 7); + _setInputToIndex("hashIndex", 2); + _setInputToIndex("hashValue", 3); + _setInputToIndex("issuanceDate", 4); + _setInputToIndex("expirationDate", 5); + _setInputToIndex("nullifierSeed", 6); + _setInputToIndex("signalHash", 7); _setInputToIndex("templateRoot", 8); _initDefaultStateVariables(_stateContractAddr, _verifierContractAddr, CIRCUIT_ID, owner); @@ -67,12 +67,12 @@ contract AnonAadhaarV1Validator is CredentialAtomicQueryValidatorBase { PubSignals memory pubSignals = PubSignals({ pubKeyHash: inputs[0], nullifier: inputs[1], - claimRoot: inputs[2], - hashIndex: inputs[3], - hashValue: inputs[4], - nullifierSeed: inputs[5], - signalHash: inputs[6], - expirationDate: inputs[7], + hashIndex: inputs[2], + hashValue: inputs[3], + issuanceDate: inputs[4], + expirationDate: inputs[5], + nullifierSeed: inputs[6], + signalHash: inputs[7], templateRoot: inputs[8] }); @@ -132,12 +132,12 @@ contract AnonAadhaarV1Validator is CredentialAtomicQueryValidatorBase { ICircuitValidator.Signal[] memory signals = new ICircuitValidator.Signal[](9); signals[0] = ICircuitValidator.Signal({name: "pubKeyHash", value: pubSignals.pubKeyHash}); signals[1] = ICircuitValidator.Signal({name: "nullifier", value: pubSignals.nullifier}); - signals[2] = ICircuitValidator.Signal({name: "claimRoot", value: pubSignals.claimRoot}); - signals[3] = ICircuitValidator.Signal({name: "hashIndex", value: pubSignals.hashIndex}); - signals[4] = ICircuitValidator.Signal({name: "hashValue", value: pubSignals.hashValue}); - signals[5] = ICircuitValidator.Signal({name: "nullifierSeed", value: pubSignals.nullifierSeed}); - signals[6] = ICircuitValidator.Signal({name: "signalHash", value: pubSignals.signalHash}); - signals[7] = ICircuitValidator.Signal({name: "expirationDate", value: pubSignals.expirationDate}); + signals[2] = ICircuitValidator.Signal({name: "hashIndex", value: pubSignals.hashIndex}); + signals[3] = ICircuitValidator.Signal({name: "hashValue", value: pubSignals.hashValue}); + signals[4] = ICircuitValidator.Signal({name: "issuanceDate", value: pubSignals.issuanceDate}); + signals[5] = ICircuitValidator.Signal({name: "expirationDate", value: pubSignals.expirationDate}); + signals[6] = ICircuitValidator.Signal({name: "nullifierSeed", value: pubSignals.nullifierSeed}); + signals[7] = ICircuitValidator.Signal({name: "signalHash", value: pubSignals.signalHash}); signals[8] = ICircuitValidator.Signal({name: "templateRoot", value: pubSignals.templateRoot}); return signals; } diff --git a/contracts/verifiers/AnonAadhaarCredentialIssuing.sol b/contracts/verifiers/AnonAadhaarCredentialIssuing.sol index 664e860a..01a6ac4b 100644 --- a/contracts/verifiers/AnonAadhaarCredentialIssuing.sol +++ b/contracts/verifiers/AnonAadhaarCredentialIssuing.sol @@ -18,6 +18,8 @@ contract AnonAadhaarCredentialIssuing is IdentityBase, EmbeddedZKPVerifier { struct AnonAadhaarCredentialIssuingStorage { uint256 nullifierSeed; uint256 publicKeysHash; + uint256 expirationTime; + uint256 templateRoot; mapping(uint256 => bool) nullifiers; } @@ -38,13 +40,17 @@ contract AnonAadhaarCredentialIssuing is IdentityBase, EmbeddedZKPVerifier { function initialize( uint256 nullifierSeed, - uint256 publicKeyHash, - address _stateContractAddr, + uint256 publicKeyHash, + uint256 expirationTime, + uint256 templateRoot, + address _stateContractAddr, bytes2 idType ) public initializer { AnonAadhaarCredentialIssuingStorage storage $ = _getAnonAadhaarCredentialIssuingStorage(); $.nullifierSeed = nullifierSeed; $.publicKeysHash = publicKeyHash; + $.expirationTime = expirationTime; + $.templateRoot = templateRoot; super.initialize(_stateContractAddr, idType); super.__EmbeddedZKPVerifier_init(_msgSender(), IState(_stateContractAddr)); @@ -53,10 +59,12 @@ contract AnonAadhaarCredentialIssuing is IdentityBase, EmbeddedZKPVerifier { function _validatePublicInputs( uint256 hashIndex, uint256 hashValue, - uint256 expirationDate, uint256 nullifier, uint256 pubKeyHash, - uint256 nullifierSeed + uint256 nullifierSeed, + uint256 issuanceDate, + uint256 expirationDate, + uint256 templateRoot ) private view { AnonAadhaarCredentialIssuingStorage storage $ = _getAnonAadhaarCredentialIssuingStorage(); require(hashIndex != 0, "Invalid hashIndex"); @@ -65,7 +73,11 @@ contract AnonAadhaarCredentialIssuing is IdentityBase, EmbeddedZKPVerifier { require(nullifierSeed == $.nullifierSeed, "Invalid nullifierSeed"); require(pubKeyHash == $.publicKeysHash, "Invalid pubKeyHash"); - require(expirationDate > block.timestamp, "Credential is expired"); + require(templateRoot == $.templateRoot, "Invalid templateRoot"); + + uint256 expectedExpiration = issuanceDate + $.expirationTime; + require(expirationDate == expectedExpiration, "Invalid expirationDate"); + require(expirationDate > block.timestamp, "Proof is expired"); require(!$.nullifiers[nullifier], "Nullifier already exists"); } @@ -84,46 +96,25 @@ contract AnonAadhaarCredentialIssuing is IdentityBase, EmbeddedZKPVerifier { require(responses.length == 1, "Only one response is allowed"); uint256 hashIndex = super.getProofStorageField(_msgSender(), responses[0].requestId, "hashIndex"); uint256 hashValue = super.getProofStorageField(_msgSender(), responses[0].requestId, "hashValue"); - uint256 expirationDate = super.getProofStorageField(_msgSender(), responses[0].requestId, "expirationDate"); uint256 nullifier = super.getProofStorageField(_msgSender(), responses[0].requestId, "nullifier"); uint256 pubKeyHash = super.getProofStorageField(_msgSender(), responses[0].requestId, "pubKeyHash"); uint256 nullifierSeed = super.getProofStorageField(_msgSender(), responses[0].requestId, "nullifierSeed"); + uint256 issuanceDate = super.getProofStorageField(_msgSender(), responses[0].requestId, "issuanceDate"); + uint256 expirationDate = super.getProofStorageField(_msgSender(), responses[0].requestId, "expirationDate"); + uint256 templateRoot = super.getProofStorageField(_msgSender(), responses[0].requestId, "templateRoot"); + - _validatePublicInputs(hashIndex, hashValue, expirationDate, nullifier, pubKeyHash, nullifierSeed); + _validatePublicInputs( + hashIndex, + hashValue, + nullifier, + pubKeyHash, + nullifierSeed, + issuanceDate, + expirationDate, + templateRoot + ); _setNullifier(nullifier); _addHashAndTransit(hashIndex, hashValue); } } - -/* -The code we need if we want to convert timestamps to the YYYY-MM-DD format and compare them - -function _compareDates(uint256 timestamp) internal view returns (bool) { - // Convert nanoseconds to seconds - uint256 secondsTimestamp = timestamp.div(1e9); - - // Get the current date - (uint256 currentYear, uint256 currentMonth, uint256 currentDay) = _timestampToDate(block.timestamp); - - // Get the expiration date - (uint256 expYear, uint256 expMonth, uint256 expDay) = _timestampToDate(secondsTimestamp); - - // Compare year, month, and day - if (expYear > currentYear) return true; - if (expYear == currentYear && expMonth > currentMonth) return true; - if (expYear == currentYear && expMonth == currentMonth && expDay > currentDay) return true; - - return false; - } - - function _timestampToDate(uint256 timestamp) internal pure returns (uint256 year, uint256 month, uint256 day) { - uint256 SECONDS_PER_DAY = 24 * 60 * 60; - uint256 DAYS_IN_YEAR = 365; - uint256 DAYS_IN_LEAP_YEAR = 366; - uint256 DAYS_IN_MONTH = 30; - - year = timestamp / (SECONDS_PER_DAY * DAYS_IN_YEAR); - month = (timestamp % (SECONDS_PER_DAY * DAYS_IN_YEAR)) / (SECONDS_PER_DAY * DAYS_IN_MONTH); - day = ((timestamp % (SECONDS_PER_DAY * DAYS_IN_YEAR)) % (SECONDS_PER_DAY * DAYS_IN_MONTH)) / SECONDS_PER_DAY; - } -*/ \ No newline at end of file diff --git a/helpers/DeployAnonAadharV1Validator.ts b/helpers/DeployAnonAadharV1Validator.ts index bb99b7a5..3da6926e 100644 --- a/helpers/DeployAnonAadharV1Validator.ts +++ b/helpers/DeployAnonAadharV1Validator.ts @@ -93,6 +93,8 @@ export class Groth16VerifierAnonAadhaarV1DeployHelper { const aadhaarIssuerTx = await deployment.initialize( 12345678, BigInt("15134874015316324267425466444584014077184337590635665158241104437045239495873"), + 15776640, + BigInt("19885546056720838706860449020869651677281577675447204956487418402102594191373"), stateContractAddress, state.defaultIdType, ); diff --git a/test/validators/sig/data/anon_aadhaar_proof.json b/test/validators/sig/data/anon_aadhaar_proof.json index 13b7fde5..67fddfda 100644 --- a/test/validators/sig/data/anon_aadhaar_proof.json +++ b/test/validators/sig/data/anon_aadhaar_proof.json @@ -1,29 +1,29 @@ { "pub_signals": [ "15134874015316324267425466444584014077184337590635665158241104437045239495873", - "20883870714734602590504997352338571539423183306657935615322485719404078821399", - "18729648289086421571137268294888100218092815780174563740882479952354359161586", - "3375683699579602341351588179964014014035617303355018200724769264279740144593", - "4014752329325518869955150710481748021109011929967383408318766675788303116713", + "21757637725804557105145673996425001348443365012102601099132628620689700248520", + "17583699629297087435396747947464104801390496987348590937346068476255878224190", + "11011149991037021719606390653883695507172517046012692737863092331336195927706", + "1737635400", + "1753412040", "12345678", "1001", - "1752685841", "19885546056720838706860449020869651677281577675447204956487418402102594191373" ], "proof": { "pi_a": [ - "6975148102362890318733286224648810647492172894642081364699578026825106424042", - "11744254957150939486190783489024046544506803323899444365339689384261671196583", + "12487121249606992194230478436044089973576822593478466000565174611663948074158", + "15590504958674151786029026096032455225587475546725060953718647279837828243194", "1" ], "pi_b": [ [ - "1159428455756792858340104700961471981067269931486244381539212669752794380024", - "7971647615217301430660362435022981135364187623023423870613900377711973572230" + "13402987638855931287006008937152285833534447856496191421752989954432404156611", + "14526586495636946138920550458682115724329743553293332534538201663911090069840" ], [ - "11397235344618348843723434438826626739007005733394010837036053896419415448084", - "3317112087765369456882388872999702851068407410424189029277568287263092387252" + "1949307931881352616288038803798309135657871994128018698835805495204275405038", + "16182465157694128275643558591706620112581904519510730926662012536552246962676" ], [ "1", @@ -31,8 +31,8 @@ ] ], "pi_c": [ - "11550543927212348039106493735277653324410491795293188141894207293714144034839", - "5939709037852542240984698506551237577030620157318154980836464594230693001981", + "8428148849298891551853291732196324429726324933780176160987580144345147637657", + "11858812461761192279572418794629613870239351794238943967711208732975260881088", "1" ], "protocol": "groth16", diff --git a/test/verifier/anonAadhaarVerifier.test.ts b/test/verifier/anonAadhaarVerifier.test.ts index 16faa523..ab0d09c4 100644 --- a/test/verifier/anonAadhaarVerifier.test.ts +++ b/test/verifier/anonAadhaarVerifier.test.ts @@ -23,7 +23,7 @@ describe("Verify anon aadhaar proof onchain", async () => { const tx = await deployment.submitZKPResponseV2(singleProof, emptyCrossChainProofs); await tx.wait(); - const proof = await deployment.getClaimProof(inputs[3]); + const proof = await deployment.getClaimProof(inputs[2]); expect(proof[1]).to.be.true; await expect(