diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index f0d8e56..bc27ec2 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -15,7 +15,9 @@ jobs: steps: - name: Checkout the repository uses: actions/checkout@v3 + - name: Setup uses: ./.github/actions/setup + - name: Run tests run: npm run test diff --git a/.solhint.json b/.solhint.json index 03fea97..1434dce 100644 --- a/.solhint.json +++ b/.solhint.json @@ -2,13 +2,18 @@ "extends": "solhint:recommended", "plugins": ["prettier"], "rules": { + "reentrancy": "error", "prettier/prettier": "warn", - "reentrancy": "off", "modifier-name-mixedcase": "off", - "no-empty-blocks": "off", - "func-visibility": "off", - "max-states-count": "off", + "func-name-mixedcase": "off", + "no-empty-blocks": "warn", + "func-visibility": ["warn", { "ignoreConstructors": true }], + "max-states-count": "warn", "not-rely-on-time": "off", - "compiler-version": "off" + "var-name-mixedcase": "off", + "gas-custom-errors": "off", + "reason-string": "off", + "no-inline-assembly": "off", + "explicit-types": "off" } } diff --git a/assets/registerIdentityLight256.dev/RegisterIdentityLight256.groth16.vkey.json b/assets/registerIdentityLight256.dev/RegisterIdentityLight256.groth16.vkey.json new file mode 100644 index 0000000..1db14bb --- /dev/null +++ b/assets/registerIdentityLight256.dev/RegisterIdentityLight256.groth16.vkey.json @@ -0,0 +1,95 @@ +{ + "protocol": "groth16", + "curve": "bn128", + "nPublic": 3, + "vk_alpha_1": [ + "20491192805390485299153009773594534940189261866228447918068658471970481763042", + "9383485363053290200918347156157836566562967994039712273449902621266178545958", + "1" + ], + "vk_beta_2": [ + [ + "6375614351688725206403948262868962793625744043794305715222011528459656738731", + "4252822878758300859123897981450591353533073413197771768651442665752259397132" + ], + [ + "10505242626370262277552901082094356697409835680220590971873171140371331206856", + "21847035105528745403288232691147584728191162732299865338377159692350059136679" + ], + ["1", "0"] + ], + "vk_gamma_2": [ + [ + "10857046999023057135944570762232829481370756359578518086990519993285655852781", + "11559732032986387107991004021392285783925812861821192530917403151452391805634" + ], + [ + "8495653923123431417604973247489272438418190587263600148770280649306958101930", + "4082367875863433681332203403145435568316851327593401208105741076214120093531" + ], + ["1", "0"] + ], + "vk_delta_2": [ + [ + "10024655051728395812564307039738346388454604848124933406202507965194273799917", + "10937043963655185952891449223625636213959039570715537527210240567875698546497" + ], + [ + "19680239487707527798110040460768721884036997340435808307578785917462138857357", + "3288878702757913739253373321195210173509136075843368700533242800223626150044" + ], + ["1", "0"] + ], + "vk_alphabeta_12": [ + [ + [ + "2029413683389138792403550203267699914886160938906632433982220835551125967885", + "21072700047562757817161031222997517981543347628379360635925549008442030252106" + ], + [ + "5940354580057074848093997050200682056184807770593307860589430076672439820312", + "12156638873931618554171829126792193045421052652279363021382169897324752428276" + ], + [ + "7898200236362823042373859371574133993780991612861777490112507062703164551277", + "7074218545237549455313236346927434013100842096812539264420499035217050630853" + ] + ], + [ + [ + "7077479683546002997211712695946002074877511277312570035766170199895071832130", + "10093483419865920389913245021038182291233451549023025229112148274109565435465" + ], + [ + "4595479056700221319381530156280926371456704509942304414423590385166031118820", + "19831328484489333784475432780421641293929726139240675179672856274388269393268" + ], + [ + "11934129596455521040620786944827826205713621633706285934057045369193958244500", + "8037395052364110730298837004334506829870972346962140206007064471173334027475" + ] + ] + ], + "IC": [ + [ + "4179432338433124082507168334716073369977625424306513458535481875746097550658", + "12714499129458131796726486922435073908760835207347394165560527204719372283417", + "1" + ], + [ + "15796010941534208751370774490726059448355760291220049636894135052670536978530", + "4411190147057228862091306245729888086078023337791017667104000774333055394870", + "1" + ], + [ + "18796505394079206082600292661633691936761371596120188411147722737603294837590", + "1121894399568100959910413213468154592683150638260580461512139659150923719975", + "1" + ], + [ + "4678945113863386760438849690757650811219476819937609876975421977973533253953", + "14173498963267645827891248481396713947897070300527005985896563335692207023061", + "1" + ] + ] +} diff --git a/assets/registerIdentityLight256.dev/RegisterIdentityLight256.groth16.zkey b/assets/registerIdentityLight256.dev/RegisterIdentityLight256.groth16.zkey new file mode 100644 index 0000000..1df1743 Binary files /dev/null and b/assets/registerIdentityLight256.dev/RegisterIdentityLight256.groth16.zkey differ diff --git a/assets/registerIdentityLight256.dev/registerIdentityLight256_js/RegisterIdentityLight256.wasm b/assets/registerIdentityLight256.dev/registerIdentityLight256_js/RegisterIdentityLight256.wasm new file mode 100644 index 0000000..4aabfa8 Binary files /dev/null and b/assets/registerIdentityLight256.dev/registerIdentityLight256_js/RegisterIdentityLight256.wasm differ diff --git a/assets/registerIdentityLight256.dev/registerIdentityLight256_js/generate_witness.js b/assets/registerIdentityLight256.dev/registerIdentityLight256_js/generate_witness.js new file mode 100644 index 0000000..eabb86e --- /dev/null +++ b/assets/registerIdentityLight256.dev/registerIdentityLight256_js/generate_witness.js @@ -0,0 +1,20 @@ +const wc = require("./witness_calculator.js"); +const { readFileSync, writeFile } = require("fs"); + +if (process.argv.length != 5) { + console.log("Usage: node generate_witness.js "); +} else { + const input = JSON.parse(readFileSync(process.argv[3], "utf8")); + + const buffer = readFileSync(process.argv[2]); + wc(buffer).then(async witnessCalculator => { + // const w= await witnessCalculator.calculateWitness(input,0); + // for (let i=0; i< w.length; i++){ + // console.log(w[i]); + // } + const buff= await witnessCalculator.calculateWTNSBin(input,0); + writeFile(process.argv[4], buff, function(err) { + if (err) throw err; + }); + }); +} diff --git a/assets/registerIdentityLight256.dev/registerIdentityLight256_js/witness_calculator.js b/assets/registerIdentityLight256.dev/registerIdentityLight256_js/witness_calculator.js new file mode 100644 index 0000000..20e6e20 --- /dev/null +++ b/assets/registerIdentityLight256.dev/registerIdentityLight256_js/witness_calculator.js @@ -0,0 +1,337 @@ +module.exports = async function builder(code, options) { + + options = options || {}; + + let wasmModule; + try { + wasmModule = await WebAssembly.compile(code); + } catch (err) { + console.log(err); + console.log("\nTry to run circom --c in order to generate c++ code instead\n"); + throw new Error(err); + } + + let wc; + + let errStr = ""; + let msgStr = ""; + + const instance = await WebAssembly.instantiate(wasmModule, { + runtime: { + exceptionHandler : function(code) { + let err; + if (code == 1) { + err = "Signal not found.\n"; + } else if (code == 2) { + err = "Too many signals set.\n"; + } else if (code == 3) { + err = "Signal already set.\n"; + } else if (code == 4) { + err = "Assert Failed.\n"; + } else if (code == 5) { + err = "Not enough memory.\n"; + } else if (code == 6) { + err = "Input signal array access exceeds the size.\n"; + } else { + err = "Unknown error.\n"; + } + throw new Error(err + errStr); + }, + printErrorMessage : function() { + errStr += getMessage() + "\n"; + // console.error(getMessage()); + }, + writeBufferMessage : function() { + const msg = getMessage(); + // Any calls to `log()` will always end with a `\n`, so that's when we print and reset + if (msg === "\n") { + console.log(msgStr); + msgStr = ""; + } else { + // If we've buffered other content, put a space in between the items + if (msgStr !== "") { + msgStr += " " + } + // Then append the message to the message we are creating + msgStr += msg; + } + }, + showSharedRWMemory : function() { + printSharedRWMemory (); + } + + } + }); + + const sanityCheck = + options +// options && +// ( +// options.sanityCheck || +// options.logGetSignal || +// options.logSetSignal || +// options.logStartComponent || +// options.logFinishComponent +// ); + + + wc = new WitnessCalculator(instance, sanityCheck); + return wc; + + function getMessage() { + var message = ""; + var c = instance.exports.getMessageChar(); + while ( c != 0 ) { + message += String.fromCharCode(c); + c = instance.exports.getMessageChar(); + } + return message; + } + + function printSharedRWMemory () { + const shared_rw_memory_size = instance.exports.getFieldNumLen32(); + const arr = new Uint32Array(shared_rw_memory_size); + for (let j=0; j { + const h = fnvHash(k); + const hMSB = parseInt(h.slice(0,8), 16); + const hLSB = parseInt(h.slice(8,16), 16); + const fArr = flatArray(input[k]); + let signalSize = this.instance.exports.getInputSignalSize(hMSB, hLSB); + if (signalSize < 0){ + throw new Error(`Signal ${k} not found\n`); + } + if (fArr.length < signalSize) { + throw new Error(`Not enough values for input signal ${k}\n`); + } + if (fArr.length > signalSize) { + throw new Error(`Too many values for input signal ${k}\n`); + } + for (let i=0; i0) { + res.unshift(0); + i--; + } + } + return res; +} + +function fromArray32(arr) { //returns a BigInt + var res = BigInt(0); + const radix = BigInt(0x100000000); + for (let i = 0; i. +*/ + +pragma solidity >=0.7.0 <0.9.0; + +contract RegisterIdentityLight160Verifier { + // 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 = + 7464177824610983307005740376234062407980911552344061210615932548437251433336; + uint256 constant deltax2 = + 12332182442772026061532463402195922904484652168320406058917153242039787029124; + uint256 constant deltay1 = + 3091641843146585314920371491385675874805613124750904273225176458140419096189; + uint256 constant deltay2 = + 20249923108983612536541993853253052729015083279950856711269450127011991451714; + + uint256 constant IC0x = + 20349435726303868385690895524466146481538595742316644502027428688090812304748; + uint256 constant IC0y = + 8497653594025335127509748616381019098271669042312847018720793147370622770322; + + uint256 constant IC1x = + 7618230016779813947936548809162030741013764904420405332759144755798695997641; + uint256 constant IC1y = + 12245121283281875421296145276713189976174075865252576946667873206706959263144; + + uint256 constant IC2x = + 12143967266017632687075184861752968737400472253371389347964345909784645967094; + uint256 constant IC2y = + 19277562751550954377761419603853342685141377171185508208174780508899555392348; + + uint256 constant IC3x = + 20574052471301075832166532620085793553873377990800519535149126747662976784503; + uint256 constant IC3y = + 11361754778472978979167817608710117232580993916765512558182336192859531891328; + + // 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[3] 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))) + + // -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))) + + // Validate all evaluations + let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) + + mstore(0, isValid) + return(0, 0x20) + } + } +} diff --git a/contracts/passport/verifiers2/light/RegisterIdentityLight224Verifier.sol b/contracts/passport/verifiers2/light/RegisterIdentityLight224Verifier.sol new file mode 100644 index 0000000..caf53f7 --- /dev/null +++ b/contracts/passport/verifiers2/light/RegisterIdentityLight224Verifier.sol @@ -0,0 +1,205 @@ +// 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 RegisterIdentityLight224Verifier { + // 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 = + 7834705987400213832654482879284608247211273342907346498433201812351743326550; + uint256 constant deltax2 = + 15713463791781049874728070408359051925633360844252096970748543581073820154017; + uint256 constant deltay1 = + 9960303067610396047265975354690935301458735339005627828526828963951265833671; + uint256 constant deltay2 = + 18785935708316386048807622408608175376450166653438440654145636676645554166030; + + uint256 constant IC0x = + 16021720986994023839045556452771522836858090081700715530292594617309924269579; + uint256 constant IC0y = + 13594283472226049115124097576752908610589316199529061389269052153309165676516; + + uint256 constant IC1x = + 18690805862834858837267080816430038044064723091728304099870642848030496550770; + uint256 constant IC1y = + 10215125565427426491709621200106259568328671289468640624443539421364531371216; + + uint256 constant IC2x = + 18796505394079206082600292661633691936761371596120188411147722737603294837590; + uint256 constant IC2y = + 1121894399568100959910413213468154592683150638260580461512139659150923719975; + + uint256 constant IC3x = + 4678945113863386760438849690757650811219476819937609876975421977973533253953; + uint256 constant IC3y = + 14173498963267645827891248481396713947897070300527005985896563335692207023061; + + // 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[3] 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))) + + // -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))) + + // Validate all evaluations + let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) + + mstore(0, isValid) + return(0, 0x20) + } + } +} diff --git a/contracts/passport/verifiers2/light/RegisterIdentityLight256Verifier.sol b/contracts/passport/verifiers2/light/RegisterIdentityLight256Verifier.sol new file mode 100644 index 0000000..ab2eea1 --- /dev/null +++ b/contracts/passport/verifiers2/light/RegisterIdentityLight256Verifier.sol @@ -0,0 +1,205 @@ +// 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 RegisterIdentityLight256Verifier { + // 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 = + 10937043963655185952891449223625636213959039570715537527210240567875698546497; + uint256 constant deltax2 = + 10024655051728395812564307039738346388454604848124933406202507965194273799917; + uint256 constant deltay1 = + 3288878702757913739253373321195210173509136075843368700533242800223626150044; + uint256 constant deltay2 = + 19680239487707527798110040460768721884036997340435808307578785917462138857357; + + uint256 constant IC0x = + 4179432338433124082507168334716073369977625424306513458535481875746097550658; + uint256 constant IC0y = + 12714499129458131796726486922435073908760835207347394165560527204719372283417; + + uint256 constant IC1x = + 15796010941534208751370774490726059448355760291220049636894135052670536978530; + uint256 constant IC1y = + 4411190147057228862091306245729888086078023337791017667104000774333055394870; + + uint256 constant IC2x = + 18796505394079206082600292661633691936761371596120188411147722737603294837590; + uint256 constant IC2y = + 1121894399568100959910413213468154592683150638260580461512139659150923719975; + + uint256 constant IC3x = + 4678945113863386760438849690757650811219476819937609876975421977973533253953; + uint256 constant IC3y = + 14173498963267645827891248481396713947897070300527005985896563335692207023061; + + // 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[3] 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))) + + // -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))) + + // Validate all evaluations + let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) + + mstore(0, isValid) + return(0, 0x20) + } + } +} diff --git a/contracts/passport/verifiers2/light/RegisterIdentityLight384Verifier.sol b/contracts/passport/verifiers2/light/RegisterIdentityLight384Verifier.sol new file mode 100644 index 0000000..effaa6b --- /dev/null +++ b/contracts/passport/verifiers2/light/RegisterIdentityLight384Verifier.sol @@ -0,0 +1,205 @@ +// 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 RegisterIdentityLight384Verifier { + // 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 = + 11165441086203221830564434281092153828694100276925141548132295268982789784218; + uint256 constant deltax2 = + 20920478363756885826557448382492133433438051226802271107044625325075887619878; + uint256 constant deltay1 = + 329638903360336659502662742168939111382564162309368768872389687402883811153; + uint256 constant deltay2 = + 16379963167594355624397041694142678582673604414859527578769631435571901320739; + + uint256 constant IC0x = + 8958748513494058508599191426944138752237723060989629885038137078978463172227; + uint256 constant IC0y = + 4914214867090836473397542537588042343107930445150928081188031438063227238585; + + uint256 constant IC1x = + 11637195806071434341598534723644239565519206257928292801099367935388755595989; + uint256 constant IC1y = + 13796067696679506753382694179027254081697448827749121543805129157701971513652; + + uint256 constant IC2x = + 9660917988021801458534214617659058002652266153176087555013704979536707738690; + uint256 constant IC2y = + 4470882805288917516012047038336848119476613701332909259888198696601506932384; + + uint256 constant IC3x = + 7956535661116822197218826069905896150124433038776757351581060766576643991459; + uint256 constant IC3y = + 3526572257993380078734696900863011236346281307961566554617165013663546039781; + + // 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[3] 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))) + + // -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))) + + // Validate all evaluations + let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) + + mstore(0, isValid) + return(0, 0x20) + } + } +} diff --git a/contracts/passport/verifiers2/light/RegisterIdentityLight512Verifier.sol b/contracts/passport/verifiers2/light/RegisterIdentityLight512Verifier.sol new file mode 100644 index 0000000..c79170a --- /dev/null +++ b/contracts/passport/verifiers2/light/RegisterIdentityLight512Verifier.sol @@ -0,0 +1,205 @@ +// 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 RegisterIdentityLight512Verifier { + // 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 = + 3387259999311938725151085858998115553074670755997850426319505603531219882007; + uint256 constant deltax2 = + 11162227726412670331525004561008161086115274445056892148102775713121895310353; + uint256 constant deltay1 = + 6751278131593240514485822017454775551862786472928973888422025785566093161187; + uint256 constant deltay2 = + 12176000192246658389921929645549310373381949728546676297767733512117951594990; + + uint256 constant IC0x = + 2361597157333949405444551808660905822518513818917441435771632219638879364895; + uint256 constant IC0y = + 11843470797144390446779295046401105119065931507359093609062612428361329499677; + + uint256 constant IC1x = + 11520068037387614772235658828483597072828893176043759014855542849469627748429; + uint256 constant IC1y = + 12806915968118383368769176060835098711480471542738558271454427667093846432359; + + uint256 constant IC2x = + 9660917988021801458534214617659058002652266153176087555013704979536707738690; + uint256 constant IC2y = + 4470882805288917516012047038336848119476613701332909259888198696601506932384; + + uint256 constant IC3x = + 7956535661116822197218826069905896150124433038776757351581060766576643991459; + uint256 constant IC3y = + 3526572257993380078734696900863011236346281307961566554617165013663546039781; + + // 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[3] 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))) + + // -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))) + + // Validate all evaluations + let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) + + mstore(0, isValid) + return(0, 0x20) + } + } +} diff --git a/contracts/registration/RegistrationSimple.sol b/contracts/registration/RegistrationSimple.sol new file mode 100644 index 0000000..c1c4036 --- /dev/null +++ b/contracts/registration/RegistrationSimple.sol @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; + +import {SetHelper} from "@solarity/solidity-lib/libs/arrays/SetHelper.sol"; +import {VerifierHelper} from "@solarity/solidity-lib/libs/zkp/snarkjs/VerifierHelper.sol"; + +import {StateKeeper} from "../state/StateKeeper.sol"; +import {TSSUpgradeable} from "../state/TSSUpgradeable.sol"; + +contract RegistrationSimple is Initializable, TSSUpgradeable { + using ECDSA for bytes32; + using VerifierHelper for address; + + using SetHelper for EnumerableSet.AddressSet; + using EnumerableSet for EnumerableSet.AddressSet; + + string public constant REGISTRATION_SIMPLE_PREFIX = "Registration simple prefix"; + + uint256 internal constant _PROOF_SIGNALS_COUNT = 3; + + enum MethodId { + None, + UpdateSignerList, + AddSigners, + RemoveSigners + } + + struct Passport { + uint256 dgCommit; + bytes32 dg1Hash; + bytes32 publicKey; + bytes32 passportHash; + address verifier; + } + + StateKeeper public stateKeeper; + + EnumerableSet.AddressSet private _signers; + + constructor() { + _disableInitializers(); + } + + function __RegistrationSimple_init( + address tssSigner_, + string calldata chainName_, + address stateKeeper_, + address[] calldata signers_ + ) external initializer { + __TSSSigner_init(tssSigner_, chainName_); + + stateKeeper = StateKeeper(stateKeeper_); + + _signers.add(signers_); + } + + function registerSimple( + uint256 identityKey_, + Passport memory passport_, + bytes memory signature_, + VerifierHelper.ProofPoints memory zkPoints_ + ) external virtual { + require(identityKey_ > 0, "RegistrationSimple: identity can not be zero"); + + bytes32 signedData_ = _buildSignedData(passport_); + address dataSigner_ = ECDSA.recover(signedData_.toEthSignedMessageHash(), signature_); + + _requireSigner(dataSigner_); + + stateKeeper.useSignature(keccak256(signature_)); + + _verifyZKProof( + passport_.verifier, + uint256(passport_.dg1Hash), + passport_.dgCommit, + identityKey_, + zkPoints_ + ); + + stateKeeper.addBond( + passport_.publicKey, + passport_.passportHash, + bytes32(identityKey_), + passport_.dgCommit + ); + } + + function updateSignerList(bytes calldata data_, bytes calldata proof_) external virtual { + uint256 nonce_ = _getAndIncrementNonce(uint8(MethodId.UpdateSignerList)); + bytes32 leaf_ = keccak256(abi.encodePacked(address(this), data_, chainName, nonce_)); + + _checkMerkleSignature(leaf_, proof_); + _useNonce(uint8(MethodId.UpdateSignerList), nonce_); + + (address[] memory signers_, uint8[] memory actions_) = abi.decode( + data_, + (address[], uint8[]) + ); + + for (uint256 i = 0; i < signers_.length; i++) { + if (MethodId(actions_[i]) == MethodId.AddSigners) { + _signers.add(signers_[i]); + } else if (MethodId(actions_[i]) == MethodId.RemoveSigners) { + _signers.remove(signers_[i]); + } else { + revert("RegistrationSimple: invalid methodId"); + } + } + } + + function _buildSignedData(Passport memory passport_) internal view returns (bytes32) { + return + keccak256( + abi.encodePacked( + REGISTRATION_SIMPLE_PREFIX, + address(this), + passport_.passportHash, + // Inside the DG1 commitment, we have the identity key; therefore, + // if the identity is to be reissued, the key will also change, + // as well as the backend signature. + // The DG1 commitment is bound to the DG1 hash via a ZKP. + passport_.dgCommit, + passport_.publicKey, + passport_.verifier + ) + ); + } + + function _verifyZKProof( + address verifier_, + uint256 dg1Hash_, + uint256 dg1Commitment_, + uint256 pkIdentityHash_, + VerifierHelper.ProofPoints memory zkPoints_ + ) internal view { + uint256[] memory pubSignals_ = new uint256[](_PROOF_SIGNALS_COUNT); + + pubSignals_[0] = dg1Hash_; // output + pubSignals_[1] = dg1Commitment_; // output + pubSignals_[2] = pkIdentityHash_; // output + + require( + verifier_.verifyProof(pubSignals_, zkPoints_), + "RegistrationSimple: invalid zk proof" + ); + } + + function _requireSigner(address account_) private view { + require(_signers.contains(account_), "RegistrationSimple: caller is not the signer"); + } +} diff --git a/deploy/10_setup.migration.ts b/deploy/10_setup.migration.ts index 311103c..990167b 100644 --- a/deploy/10_setup.migration.ts +++ b/deploy/10_setup.migration.ts @@ -38,6 +38,7 @@ import { PMNEOptVerifier2__factory, PMNEOpt2Verifier2__factory, CECDSADispatcher__factory, + RegistrationSimple__factory, } from "@ethers-v6"; import { @@ -97,6 +98,7 @@ export = async (deployer: Deployer) => { const config = (await getConfig())!; const stateKeeper = await deployer.deployed(StateKeeperMock__factory, "StateKeeper Proxy"); const registration = await deployer.deployed(Registration2Mock__factory, "Registration2 Proxy"); + const registrationSimple = await deployer.deployed(RegistrationSimple__factory, "RegistrationSimple Proxy"); // ------------------------ CERTIFICATE ------------------------ @@ -376,4 +378,5 @@ export = async (deployer: Deployer) => { await registration.mockAddPassportVerifier(Z_MNE_OPT_2, await pMneOpt2Verifier.getAddress()); await stateKeeper.mockAddRegistrations([config.registrationName], [await registration.getAddress()]); + await stateKeeper.mockAddRegistrations([config.simpleRegistrationName], [await registrationSimple.getAddress()]); }; diff --git a/deploy/12_verifiers.migration.ts b/deploy/12_verifiers.migration.ts new file mode 100644 index 0000000..0365874 --- /dev/null +++ b/deploy/12_verifiers.migration.ts @@ -0,0 +1,36 @@ +import { Deployer, Reporter } from "@solarity/hardhat-migrate"; + +import { + RegisterIdentityLight160Verifier__factory, + RegisterIdentityLight224Verifier__factory, + RegisterIdentityLight256Verifier__factory, + RegisterIdentityLight384Verifier__factory, + RegisterIdentityLight512Verifier__factory, + RegistrationSimple__factory, +} from "@/generated-types/ethers"; + +import { deployProxy } from "@/deploy/helpers"; +import { getConfig } from "@/deploy/config/config"; + +export = async (deployer: Deployer) => { + const registration1 = await deployer.deploy(RegisterIdentityLight160Verifier__factory); + const registration2 = await deployer.deploy(RegisterIdentityLight224Verifier__factory); + const registration3 = await deployer.deploy(RegisterIdentityLight256Verifier__factory); + const registration4 = await deployer.deploy(RegisterIdentityLight384Verifier__factory); + const registration5 = await deployer.deploy(RegisterIdentityLight512Verifier__factory); + + const config = (await getConfig())!; + + // TODO: delete after mainnet deployment + const registrationSimple = await deployProxy(deployer, RegistrationSimple__factory, "RegistrationSimple"); + await registrationSimple.__RegistrationSimple_init(config.tssSigner, config.chainName, config.stateKeeper, []); + + Reporter.reportContracts( + ["RegistrationSimple", `${await registrationSimple.getAddress()}`], + ["RegisterIdentityLight160Verifier", `${await registration1.getAddress()}`], + ["RegisterIdentityLight224Verifier", `${await registration2.getAddress()}`], + ["RegisterIdentityLight256Verifier", `${await registration3.getAddress()}`], + ["RegisterIdentityLight384Verifier", `${await registration4.getAddress()}`], + ["RegisterIdentityLight512Verifier", `${await registration5.getAddress()}`], + ); +}; diff --git a/deploy/2_registration.migration.ts b/deploy/2_registration.migration.ts index d877f9a..597e685 100644 --- a/deploy/2_registration.migration.ts +++ b/deploy/2_registration.migration.ts @@ -11,7 +11,7 @@ import { deployCECDSADispatcher, } from "./helpers"; -import { Registration2Mock__factory, StateKeeperMock__factory } from "@ethers-v6"; +import { Registration2Mock__factory, RegistrationSimple__factory, StateKeeperMock__factory } from "@ethers-v6"; import { getConfig } from "./config/config"; @@ -22,6 +22,14 @@ export = async (deployer: Deployer) => { const registration = await deployProxy(deployer, Registration2Mock__factory, "Registration2"); await registration.__Registration_init(config.tssSigner, config.chainName, await stateKeeper.getAddress()); + const registrationSimple = await deployProxy(deployer, RegistrationSimple__factory, "RegistrationSimple"); + await registrationSimple.__RegistrationSimple_init( + config.tssSigner, + config.chainName, + await stateKeeper.getAddress(), + config.simpleRegistrationSigners, + ); + await deployPVerifiers(deployer); await deployCRSADispatcher(deployer, "SHA1", "65537", "512", "0x0282020100"); @@ -48,5 +56,8 @@ export = async (deployer: Deployer) => { await deployPNOAADispatcher(deployer); await deployPECDSASHA12704Dispatcher(deployer); - Reporter.reportContracts(["Registration2", `${await registration.getAddress()}`]); + Reporter.reportContracts( + ["Registration2", `${await registration.getAddress()}`], + ["RegistrationSimple", `${await registrationSimple.getAddress()}`], + ); }; diff --git a/deploy/config/localhost.ts b/deploy/config/localhost.ts index 70e9af5..6bab5dc 100644 --- a/deploy/config/localhost.ts +++ b/deploy/config/localhost.ts @@ -3,3 +3,6 @@ export const chainName = "Localhost"; export const tssSigner = "0x038D006846a3e203738cF80A02418e124203beb2"; export const icaoMasterTreeMerkleRoot = "0xca09a639ceafe2c7b3d37f1ddd78ae0b203332a3e7b180aa35435a0d3a8cd8c7"; export const registrationName = "SecondRegistration"; +export const simpleRegistrationName = "SimpleRegistration"; +export const simpleRegistrationSigners = []; +export const stateKeeper = "0x0000000000000000000000000000000000000000"; diff --git a/deploy/config/rarimo-mainnet.ts b/deploy/config/rarimo-mainnet.ts index efb2d8d..1057b9c 100644 --- a/deploy/config/rarimo-mainnet.ts +++ b/deploy/config/rarimo-mainnet.ts @@ -3,3 +3,6 @@ export const chainName = "Rarimo-mainnet"; export const tssSigner = "0xFBCC100421aC00FDf826948e467f0c95fDE72e18"; export const icaoMasterTreeMerkleRoot = "0x0eef24f25513eb3d3e13856805319553013158c347209287d090d3100e33c55b"; export const registrationName = "SecondRegistration"; +export const simpleRegistrationName = "SimpleRegistration"; +export const simpleRegistrationSigners = []; +export const stateKeeper = "0x7d4E8Da1d10f8Db46C52414175d4003ab0Aef506"; diff --git a/deploy/config/rarimo-testnet.ts b/deploy/config/rarimo-testnet.ts index b1cba33..187667d 100644 --- a/deploy/config/rarimo-testnet.ts +++ b/deploy/config/rarimo-testnet.ts @@ -3,3 +3,6 @@ export const chainName = "Rarimo-testnet"; export const tssSigner = "0x038D006846a3e203738cF80A02418e124203beb2"; export const icaoMasterTreeMerkleRoot = "0x0eef24f25513eb3d3e13856805319553013158c347209287d090d3100e33c55b"; export const registrationName = "SecondRegistration"; +export const simpleRegistrationName = "SimpleRegistration"; +export const simpleRegistrationSigners = []; +export const stateKeeper = "0x0Ca8340633e0D728db012D59bD543fD80dDabFC9"; diff --git a/hardhat.config.ts b/hardhat.config.ts index 075123f..85ad31a 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -3,6 +3,7 @@ import "@nomicfoundation/hardhat-chai-matchers"; import "@solarity/hardhat-migrate"; import "@solarity/hardhat-gobind"; import "@solarity/hardhat-markup"; +import "@solarity/hardhat-zkit"; import "@typechain/hardhat"; import "hardhat-contract-sizer"; import "hardhat-gas-reporter"; diff --git a/package-lock.json b/package-lock.json index 3223fed..9e89364 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,10 +22,12 @@ "@nomicfoundation/hardhat-network-helpers": "^1.0.10", "@solarity/hardhat-gobind": "^1.2.2", "@solarity/hardhat-markup": "^1.0.7", - "@solarity/hardhat-migrate": "^2.1.7", + "@solarity/hardhat-migrate": "^2.1.11", + "@solarity/hardhat-zkit": "^0.5.3", "@typechain/ethers-v6": "^0.5.1", "@typechain/hardhat": "^9.1.0", "@types/chai": "^4.3.14", + "@types/fs-extra": "^11.0.4", "@types/mocha": "^10.0.6", "@types/node": "^18.16.0", "bignumber.js": "^9.1.2", @@ -33,6 +35,7 @@ "circomlibjs": "^0.1.7", "dotenv": "16.4.5", "ethers": "^6.11.1", + "fs-extra": "^11.2.0", "hardhat": "2.20.1", "hardhat-contract-sizer": "^2.10.0", "hardhat-gas-reporter": "^2.0.2", @@ -127,6 +130,17 @@ "node": ">=12" } }, + "node_modules/@distributedlab/circom-parser": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@distributedlab/circom-parser/-/circom-parser-0.2.2.tgz", + "integrity": "sha512-HXxtg+v/4GPAG5n4e55cjQtmUgumITok8s58L9yWGX14EmVwxbZ8jFeLR9W3rAGI0HTCBF4UemZKPocqVQetSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "antlr4": "4.13.1-patch-1", + "ejs": "3.1.10" + } + }, "node_modules/@ensdomains/address-encoder": { "version": "0.1.9", "resolved": "https://registry.npmjs.org/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz", @@ -1021,6 +1035,36 @@ "node": ">=14" } }, + "node_modules/@iden3/bigarray": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@iden3/bigarray/-/bigarray-0.0.2.tgz", + "integrity": "sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g==", + "dev": true, + "license": "GPL-3.0" + }, + "node_modules/@iden3/binfileutils": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@iden3/binfileutils/-/binfileutils-0.0.12.tgz", + "integrity": "sha512-naAmzuDufRIcoNfQ1d99d7hGHufLA3wZSibtr4dMe6ZeiOPV1KwOZWTJ1YVz4HbaWlpDuzVU72dS4ATQS4PXBQ==", + "dev": true, + "license": "GPL-3.0", + "dependencies": { + "fastfile": "0.0.20", + "ffjavascript": "^0.3.0" + } + }, + "node_modules/@iden3/binfileutils/node_modules/ffjavascript": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.3.1.tgz", + "integrity": "sha512-4PbK1WYodQtuF47D4pRI5KUg3Q392vuP5WjE1THSnceHdXwU3ijaoS0OqxTzLknCtz4Z2TtABzkBdBdMn3B/Aw==", + "dev": true, + "license": "GPL-3.0", + "dependencies": { + "wasmbuilder": "0.0.16", + "wasmcurves": "0.2.2", + "web-worker": "1.2.0" + } + }, "node_modules/@iden3/contracts": { "version": "1.4.7", "resolved": "https://registry.npmjs.org/@iden3/contracts/-/contracts-1.4.7.tgz", @@ -1732,10 +1776,11 @@ } }, "node_modules/@nomicfoundation/hardhat-ethers": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.5.tgz", - "integrity": "sha512-RNFe8OtbZK6Ila9kIlHp0+S80/0Bu/3p41HUpaRIoHLm6X3WekTd83vob3rE54Duufu1edCiBDxspBzi2rxHHw==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.8.tgz", + "integrity": "sha512-zhOZ4hdRORls31DTOqg+GmEZM0ujly8GGIuRY7t7szEk2zW/arY1qDug/py8AEktT00v5K+b6RvbVog+va51IA==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.1.1", "lodash.isequal": "^4.5.0" @@ -1758,17 +1803,18 @@ } }, "node_modules/@nomicfoundation/hardhat-verify": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.4.tgz", - "integrity": "sha512-B8ZjhOrmbbRWqJi65jvQblzjsfYktjqj2vmOm+oc2Vu8drZbT2cjeSCRHZKbS7lOtfW78aJZSFvw+zRLCiABJA==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.12.tgz", + "integrity": "sha512-Lg3Nu7DCXASQRVI/YysjuAX2z8jwOCbS0w5tz2HalWGSTZThqA0v9N0v0psHbKNqzPJa8bNOeapIVSziyJTnAg==", "dev": true, + "license": "MIT", "dependencies": { "@ethersproject/abi": "^5.1.2", "@ethersproject/address": "^5.0.2", "cbor": "^8.1.0", - "chalk": "^2.4.2", "debug": "^4.1.1", "lodash.clonedeep": "^4.5.0", + "picocolors": "^1.1.0", "semver": "^6.3.0", "table": "^6.8.0", "undici": "^5.14.0" @@ -1782,6 +1828,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -1985,6 +2032,21 @@ "web3": "^1.0.0-beta.36" } }, + "node_modules/@nomiclabs/hardhat-truffle5/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, "node_modules/@nomiclabs/hardhat-web3": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-web3/-/hardhat-web3-2.0.0.tgz", @@ -2409,23 +2471,191 @@ } }, "node_modules/@solarity/hardhat-migrate": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@solarity/hardhat-migrate/-/hardhat-migrate-2.1.8.tgz", - "integrity": "sha512-HWQ660heuHWT1I3aAFTknJ2+OFZ9cVOKMeBjMR3G05/td7mxGhCYSYZXl0fZeNNOjauNjgw/L4hIqImFfJ8tmA==", + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@solarity/hardhat-migrate/-/hardhat-migrate-2.1.11.tgz", + "integrity": "sha512-Cgj1uW3w988cZSSJ++Qrer1AwaOFU2cffSNkwgCBQZdJGgKCPqlBonq7Ajy4jXzvoi7jTE7drqyBroQTW31aIQ==", "dev": true, + "license": "MIT", + "workspaces": [ + "test/fixture-projects/*" + ], "dependencies": { - "@nomicfoundation/hardhat-ethers": "3.0.5", - "@nomicfoundation/hardhat-verify": "2.0.4", + "@nomicfoundation/hardhat-ethers": "3.0.8", + "@nomicfoundation/hardhat-verify": "2.0.12", "@nomiclabs/hardhat-truffle5": "2.0.7", - "axios": "1.6.7", - "ethers": "6.11.1", - "ora": "5.4.1" + "axios": "1.7.9", + "ethers": "6.13.4", + "ora": "5.4.1", + "prettier": "3.4.2" }, "peerDependencies": { "hardhat": "^2.10.0", "typechain": "^8.0.0" } }, + "node_modules/@solarity/hardhat-migrate/node_modules/prettier": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/@solarity/hardhat-zkit": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@solarity/hardhat-zkit/-/hardhat-zkit-0.5.3.tgz", + "integrity": "sha512-8L2V7ILpojRbz92kz7tIzkar5+bnTymkF0w1TjKk141damyVLf98k9uUbN8I8skjHUFUQGlqcLluly0RjetV1g==", + "dev": true, + "license": "MIT", + "workspaces": [ + "test/fixture-projects/*" + ], + "dependencies": { + "@distributedlab/circom-parser": "0.2.2", + "@solarity/zkit": "0.3.2", + "@solarity/zktype": "0.4.2", + "@wasmer/wasi": "0.12.0", + "chalk": "4.1.2", + "cli-progress": "3.12.0", + "cli-table3": "0.6.5", + "debug": "4.3.5", + "is-typed-array": "1.1.13", + "lodash": "4.17.21", + "ora": "5.4.1", + "path-browserify": "1.0.1", + "resolve": "1.22.8", + "semver": "7.6.3", + "snarkjs": "0.7.5", + "uuid": "9.0.1", + "zod": "3.23.8" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "hardhat": "^2.16.0" + } + }, + "node_modules/@solarity/hardhat-zkit/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@solarity/hardhat-zkit/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@solarity/hardhat-zkit/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@solarity/hardhat-zkit/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@solarity/hardhat-zkit/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@solarity/hardhat-zkit/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@solarity/hardhat-zkit/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@solarity/hardhat-zkit/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@solarity/solidity-lib": { "version": "2.7.12", "resolved": "https://registry.npmjs.org/@solarity/solidity-lib/-/solidity-lib-2.7.12.tgz", @@ -2439,6 +2669,51 @@ "@uniswap/v3-periphery": "1.4.4" } }, + "node_modules/@solarity/zkit": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@solarity/zkit/-/zkit-0.3.2.tgz", + "integrity": "sha512-wcsrS3e8YXiiL2KvuiwiTI0TDwhIdLl+OCelaXgZEJEDsADdro9ad986U2FK0faZa1FZqTkolzkYRec6h8c5gA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ejs": "3.1.10", + "snarkjs": "0.7.5" + } + }, + "node_modules/@solarity/zktype": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@solarity/zktype/-/zktype-0.4.2.tgz", + "integrity": "sha512-dJYy5EvQt4ugOZZJvBSWyoVHuejKS7A91V0QJB0uVzIN+xRIRV5HGUOcDB15rz217mHCStnxLBSJ7R5IsADKPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ejs": "3.1.10", + "prettier": "3.3.3", + "typescript": "5.5.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@solarity/zkit": "^0.3.0-rc.0" + } + }, + "node_modules/@solarity/zktype/node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/@solidity-parser/parser": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", @@ -3403,6 +3678,17 @@ "@types/ms": "*" } }, + "node_modules/@types/fs-extra": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", + "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/jsonfile": "*", + "@types/node": "*" + } + }, "node_modules/@types/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", @@ -3419,6 +3705,16 @@ "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", "dev": true }, + "node_modules/@types/jsonfile": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", @@ -3582,6 +3878,19 @@ "node": ">=10" } }, + "node_modules/@wasmer/wasi": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@wasmer/wasi/-/wasi-0.12.0.tgz", + "integrity": "sha512-FJhLZKAfLWm/yjQI7eCRHNbA8ezmb7LSpUYFkHruZXs2mXk2+DaQtSElEtOoNrVQ4vApTyVaAd5/b7uEu8w6wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "browser-process-hrtime": "^1.0.0", + "buffer-es6": "^4.9.3", + "path-browserify": "^1.0.0", + "randomfill": "^1.0.4" + } + }, "node_modules/abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", @@ -3985,12 +4294,13 @@ "dev": true }, "node_modules/axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", "dev": true, + "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -4062,6 +4372,23 @@ "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", "dev": true }, + "node_modules/bfj": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.1.0.tgz", + "integrity": "sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "^3.7.2", + "check-types": "^11.2.3", + "hoopy": "^0.1.4", + "jsonpath": "^1.1.1", + "tryer": "^1.0.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/big-integer": { "version": "1.6.36", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz", @@ -4373,6 +4700,13 @@ "integrity": "sha512-+3USgYsC7bzb5yU0/p2HnnynZl0ak0E6uoIm4UW4Aby/8s8HFCq6NCfrrf1E9c3O8OCSzq3oYO1tUVqIi61Nww==", "dev": true }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -4437,6 +4771,13 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-es6": { + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/buffer-es6/-/buffer-es6-4.9.3.tgz", + "integrity": "sha512-Ibt+oXxhmeYJSsCkODPqNpPmyegefiD8rfutH1NYGhMZQhSp95Rz7haemgnJ6dxa6LT+JLLbtgOMORRluwKktw==", + "dev": true, + "license": "MIT" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -4568,6 +4909,7 @@ "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", "dev": true, + "license": "MIT", "dependencies": { "nofilter": "^3.1.0" }, @@ -4666,6 +5008,13 @@ "node": "*" } }, + "node_modules/check-types": { + "version": "11.2.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", + "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==", + "dev": true, + "license": "MIT" + }, "node_modules/cheerio": { "version": "1.0.0-rc.12", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", @@ -4779,6 +5128,31 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/circom_runtime": { + "version": "0.1.28", + "resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.28.tgz", + "integrity": "sha512-ACagpQ7zBRLKDl5xRZ4KpmYIcZDUjOiNRuxvXLqhnnlLSVY1Dbvh73TI853nqoR0oEbihtWmMSjgc5f+pXf/jQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "ffjavascript": "0.3.1" + }, + "bin": { + "calcwit": "calcwit.js" + } + }, + "node_modules/circom_runtime/node_modules/ffjavascript": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.3.1.tgz", + "integrity": "sha512-4PbK1WYodQtuF47D4pRI5KUg3Q392vuP5WjE1THSnceHdXwU3ijaoS0OqxTzLknCtz4Z2TtABzkBdBdMn3B/Aw==", + "dev": true, + "license": "GPL-3.0", + "dependencies": { + "wasmbuilder": "0.0.16", + "wasmcurves": "0.2.2", + "web-worker": "1.2.0" + } + }, "node_modules/circomlibjs": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/circomlibjs/-/circomlibjs-0.1.7.tgz", @@ -4878,6 +5252,19 @@ "node": ">=8" } }, + "node_modules/cli-progress": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz", + "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.3" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/cli-spinners": { "version": "2.9.2", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", @@ -4891,10 +5278,11 @@ } }, "node_modules/cli-table3": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.4.tgz", - "integrity": "sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", "dev": true, + "license": "MIT", "dependencies": { "string-width": "^4.2.0" }, @@ -5737,6 +6125,22 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -6335,9 +6739,9 @@ } }, "node_modules/ethers": { - "version": "6.11.1", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.11.1.tgz", - "integrity": "sha512-mxTAE6wqJQAbp5QAe/+o+rXOID7Nw91OZXvgpjDa1r4fAbq2Nu314oEZSbjoRLacuCzs7kUC3clEvkCQowffGg==", + "version": "6.13.4", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.13.4.tgz", + "integrity": "sha512-21YtnZVg4/zKkCQPjrDj38B1r4nQvTZLopUGMLQ1ePU2zV/joCfDC3t3iKQjWRzjjjbzR+mdAIoikeBRNkdllA==", "dev": true, "funding": [ { @@ -6349,14 +6753,15 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { "@adraffy/ens-normalize": "1.10.1", "@noble/curves": "1.2.0", "@noble/hashes": "1.3.2", - "@types/node": "18.15.13", + "@types/node": "22.7.5", "aes-js": "4.0.0-beta.5", - "tslib": "2.4.0", - "ws": "8.5.0" + "tslib": "2.7.0", + "ws": "8.17.1" }, "engines": { "node": ">=14.0.0" @@ -6387,10 +6792,21 @@ } }, "node_modules/ethers/node_modules/@types/node": { - "version": "18.15.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", - "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==", - "dev": true + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/ethers/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" }, "node_modules/ethjs-unit": { "version": "0.1.6", @@ -6598,6 +7014,13 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fastfile": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.20.tgz", + "integrity": "sha512-r5ZDbgImvVWCP0lA/cGNgQcZqR+aYdFx3u+CtJqUE510pBUVGMn4ulL/iRTI4tACTYsNJ736uzFxEBXesPAktA==", + "dev": true, + "license": "GPL-3.0" + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -6618,6 +7041,39 @@ "web-worker": "1.2.0" } }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -6810,17 +7266,41 @@ } }, "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-extra/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, + "license": "MIT", "engines": { - "node": ">=6 <7 || >=8" + "node": ">= 10.0.0" } }, "node_modules/fs-minipass": { @@ -7635,6 +8115,31 @@ "setimmediate": "^1.0.5" } }, + "node_modules/hardhat/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/hardhat/node_modules/fs-extra/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/hardhat/node_modules/jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", @@ -7893,6 +8398,16 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -8254,6 +8769,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-data-view": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", @@ -8580,6 +9111,108 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jake/node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jake/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jake/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jake/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/js-sdsl": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.2.tgz", @@ -8680,6 +9313,38 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "dev": true, + "license": "MIT", + "dependencies": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "node_modules/jsonpath/node_modules/esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsonpath/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true, + "license": "MIT" + }, "node_modules/jsonschema": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", @@ -8882,7 +9547,8 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.isequal": { "version": "4.5.0", @@ -8988,6 +9654,13 @@ "node": ">=8" } }, + "node_modules/logplease": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/logplease/-/logplease-1.2.15.tgz", + "integrity": "sha512-jLlHnlsPSJjpwUfcNyUxXCl33AYg2cHhIf9QhGL2T4iPT0XPB+xP1LRKFPgIg1M/sg9kAJvy94w9CzBNrfnstA==", + "dev": true, + "license": "MIT" + }, "node_modules/loupe": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", @@ -9672,6 +10345,7 @@ "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.19" } @@ -10204,6 +10878,13 @@ "upper-case-first": "^1.1.0" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, "node_modules/path-case": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", @@ -10318,10 +10999,11 @@ "dev": true }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -10587,6 +11269,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/r1csfile": { + "version": "0.0.48", + "resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.48.tgz", + "integrity": "sha512-kHRkKUJNaor31l05f2+RFzvcH5XSa7OfEfd/l4hzjte6NL6fjRkSMfZ4BjySW9wmfdwPOtq3mXurzPvPGEf5Tw==", + "dev": true, + "license": "GPL-3.0", + "dependencies": { + "@iden3/bigarray": "0.0.2", + "@iden3/binfileutils": "0.0.12", + "fastfile": "0.0.20", + "ffjavascript": "0.3.0" + } + }, + "node_modules/r1csfile/node_modules/ffjavascript": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.3.0.tgz", + "integrity": "sha512-l7sR5kmU3gRwDy8g0Z2tYBXy5ttmafRPFOqY7S6af5cq51JqJWt5eQ/lSR/rs2wQNbDYaYlQr5O+OSUf/oMLoQ==", + "dev": true, + "license": "GPL-3.0", + "dependencies": { + "wasmbuilder": "0.0.16", + "wasmcurves": "0.2.2", + "web-worker": "1.2.0" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -10596,6 +11303,17 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -11265,13 +11983,11 @@ "dev": true }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -11279,24 +11995,6 @@ "node": ">=10" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -11683,6 +12381,40 @@ "no-case": "^2.2.0" } }, + "node_modules/snarkjs": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/snarkjs/-/snarkjs-0.7.5.tgz", + "integrity": "sha512-h+3c4rXZKLhLuHk4LHydZCk/h5GcNvk5GjVKRRkHmfb6Ntf8gHOA9zea3g656iclRuhqQ3iKDWFgiD9ypLrKiA==", + "dev": true, + "license": "GPL-3.0", + "dependencies": { + "@iden3/binfileutils": "0.0.12", + "bfj": "^7.0.2", + "blake2b-wasm": "^2.4.0", + "circom_runtime": "0.1.28", + "ejs": "^3.1.6", + "fastfile": "0.0.20", + "ffjavascript": "0.3.1", + "js-sha3": "^0.8.0", + "logplease": "^1.2.15", + "r1csfile": "0.0.48" + }, + "bin": { + "snarkjs": "build/cli.cjs" + } + }, + "node_modules/snarkjs/node_modules/ffjavascript": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.3.1.tgz", + "integrity": "sha512-4PbK1WYodQtuF47D4pRI5KUg3Q392vuP5WjE1THSnceHdXwU3ijaoS0OqxTzLknCtz4Z2TtABzkBdBdMn3B/Aw==", + "dev": true, + "license": "GPL-3.0", + "dependencies": { + "wasmbuilder": "0.0.16", + "wasmcurves": "0.2.2", + "web-worker": "1.2.0" + } + }, "node_modules/solc": { "version": "0.4.26", "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", @@ -12240,6 +12972,16 @@ "node": ">=8" } }, + "node_modules/static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escodegen": "^1.8.1" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -12491,6 +13233,19 @@ "node": ">=4" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/swap-case": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", @@ -12898,6 +13653,13 @@ "node": ">=0.6" } }, + "node_modules/tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "dev": true, + "license": "MIT" + }, "node_modules/ts-command-line-args": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", @@ -13059,10 +13821,11 @@ } }, "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "dev": true, + "license": "0BSD" }, "node_modules/tsort": { "version": "0.0.1", @@ -13170,6 +13933,21 @@ "typescript": ">=4.3.0" } }, + "node_modules/typechain/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, "node_modules/typechain/node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -13300,10 +14078,11 @@ } }, "node_modules/typescript": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", - "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -14510,16 +15289,17 @@ "dev": true }, "node_modules/ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -14682,6 +15462,16 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 73ee4ab..4a606a1 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "compile": "npx hardhat compile --force", "coverage": "npx hardhat coverage --solcoverjs ./.solcover.ts", "clean": "npx hardhat clean", - "test": "npx hardhat test", + "prepare-circuits": "npx hardhat zkit make && ./scripts/replace-circuits-files.sh", + "test": "npm run prepare-circuits && npx hardhat test", "test-all": "npx hardhat migrate && npm run test", "private-network": "npx hardhat node", "private-network-fork": "npx hardhat node --fork https://mainnet.infura.io/v3/$(grep INFURA_KEY .env | cut -d '\"' -f2)", @@ -43,6 +44,7 @@ "deploy-avalanche": "npx hardhat migrate --network avalanche --verify", "generate-types": "TYPECHAIN_FORCE=true npx hardhat typechain && npx hardhat gobind", "generate-docs": "npx hardhat markup", + "solhint-check": "solhint \"./contracts/**/*.sol\"", "lint-fix": "npm run lint-sol-fix && npm run lint-ts-fix && npm run lint-json-fix", "lint-json-fix": "prettier --write \"./**/*.json\"", "lint-ts-fix": "prettier --write \"./**/*.ts\"", @@ -63,10 +65,12 @@ "@nomicfoundation/hardhat-network-helpers": "^1.0.10", "@solarity/hardhat-gobind": "^1.2.2", "@solarity/hardhat-markup": "^1.0.7", - "@solarity/hardhat-migrate": "^2.1.7", + "@solarity/hardhat-migrate": "^2.1.11", + "@solarity/hardhat-zkit": "^0.5.3", "@typechain/ethers-v6": "^0.5.1", "@typechain/hardhat": "^9.1.0", "@types/chai": "^4.3.14", + "@types/fs-extra": "^11.0.4", "@types/mocha": "^10.0.6", "@types/node": "^18.16.0", "bignumber.js": "^9.1.2", @@ -74,6 +78,7 @@ "circomlibjs": "^0.1.7", "dotenv": "16.4.5", "ethers": "^6.11.1", + "fs-extra": "^11.2.0", "hardhat": "2.20.1", "hardhat-contract-sizer": "^2.10.0", "hardhat-gas-reporter": "^2.0.2", diff --git a/scripts/replace-circuits-files.sh b/scripts/replace-circuits-files.sh new file mode 100755 index 0000000..55dac32 --- /dev/null +++ b/scripts/replace-circuits-files.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +cp -f assets/registerIdentityLight256.dev/registerIdentityLight256_js/generate_witness.js zkit/artifacts/circuits/RegisterIdentityLight256.circom/RegisterIdentityLight256_js/generate_witness.js +cp -f assets/registerIdentityLight256.dev/registerIdentityLight256_js/RegisterIdentityLight256.wasm zkit/artifacts/circuits/RegisterIdentityLight256.circom/RegisterIdentityLight256_js +cp -f assets/registerIdentityLight256.dev/registerIdentityLight256_js/witness_calculator.js zkit/artifacts/circuits/RegisterIdentityLight256.circom/RegisterIdentityLight256_js +cp -f assets/registerIdentityLight256.dev/RegisterIdentityLight256.groth16.vkey.json zkit/artifacts/circuits/RegisterIdentityLight256.circom +cp -f assets/registerIdentityLight256.dev/RegisterIdentityLight256.groth16.zkey zkit/artifacts/circuits/RegisterIdentityLight256.circom diff --git a/test/helpers/dg1.ts b/test/helpers/dg1.ts new file mode 100644 index 0000000..a98bef2 --- /dev/null +++ b/test/helpers/dg1.ts @@ -0,0 +1,111 @@ +import { Poseidon } from "@iden3/js-crypto"; + +export type DG1Fields = { + citizenship: string; // 3 chars + name: string; // 31 chars + nameResidual: string; // 8 chars + documentNumber: string; // 9 chars + nationality: string; // 3 chars + birthDate: string; // 6 chars (i.g., YYMMDD) + sex: string; // 1 char ('M'/'F'/'O') + expirationDate: string; // 6 chars (i.g., YYMMDD) +}; + +/** + * Encodes an ASCII string into bits (MSB-first) and writes it into the dg1 array at the given offset. + * @param dg1 - The dg1 bit array (modified in place). + * @param str - ASCII string to encode. + * @param offset - Starting bit offset in the dg1 array. + */ +export function writeASCIIString(dg1: bigint[], str: string, offset: number) { + for (let i = 0; i < str.length; i++) { + const charCode = str.charCodeAt(i); + // Write 8 bits, MSB first + for (let b = 0; b < 8; b++) { + // Extract bit (7-b)th bit from charCode + const bit = (charCode >> (7 - b)) & 1; + dg1[offset + i * 8 + b] = BigInt(bit); + } + } +} + +/** + * Ensures that a string is the correct length, padding or throwing an error if necessary. + * @param str - The original string. + * @param requiredLength - The required length in characters. + * @param padChar - The character to pad with if str is shorter than requiredLength. + */ +export function ensureLength(str: string, requiredLength: number, padChar = "\0") { + if (str.length === requiredLength) return str; + if (str.length < requiredLength) { + return str.padEnd(requiredLength, padChar); + } + throw new Error(`String too long. Required length: ${requiredLength}, got: ${str.length}`); +} + +/** + * Creates a valid dg1 array of 1024 bits from the given fields. + * All fields must match the required lengths. If shorter, they are padded. + * Date: 6 chars => 48 bits + */ +export function createDG1Data(fields: DG1Fields): bigint[] { + const dg1 = Array(1024).fill(0n); + + // Ensure lengths + fields.citizenship = ensureLength(fields.citizenship, 3, "0"); + fields.name = ensureLength(fields.name, 31, " "); + fields.nameResidual = ensureLength(fields.nameResidual, 8, " "); + fields.documentNumber = ensureLength(fields.documentNumber, 9, "0"); + fields.nationality = ensureLength(fields.nationality, 3, "0"); + fields.birthDate = ensureLength(fields.birthDate, 6, "0"); + fields.sex = ensureLength(fields.sex, 1, "X"); + fields.expirationDate = ensureLength(fields.expirationDate, 6, "0"); + + // Offsets and sizes in bits + const CITIZENSHIP_FIELD_SHIFT = 56; + + const NAME_FIELD_SHIFT = 80; + const NAME_FIELD_SIZE = 248; // 31 * 8 + + const NAME_FIELD_RESIDUAL_SHIFT = NAME_FIELD_SHIFT + NAME_FIELD_SIZE; // 80 + 248 = 328 + + const DOCUMENT_NUMBER_SHIFT = 392; + + const NATIONALITY_FIELD_SHIFT = 472; + + const BIRTH_DATE_SHIFT = 496; + + const SEX_POSITION = 69; // As given + const SEX_FIELD_SHIFT = SEX_POSITION * 8; // 552 + + const EXPIRATION_DATE_SHIFT = 560; + + // Write fields + writeASCIIString(dg1, fields.citizenship, CITIZENSHIP_FIELD_SHIFT); + writeASCIIString(dg1, fields.name, NAME_FIELD_SHIFT); + writeASCIIString(dg1, fields.nameResidual, NAME_FIELD_RESIDUAL_SHIFT); + writeASCIIString(dg1, fields.documentNumber, DOCUMENT_NUMBER_SHIFT); + writeASCIIString(dg1, fields.nationality, NATIONALITY_FIELD_SHIFT); + writeASCIIString(dg1, fields.birthDate, BIRTH_DATE_SHIFT); + writeASCIIString(dg1, fields.sex, SEX_FIELD_SHIFT); + writeASCIIString(dg1, fields.expirationDate, EXPIRATION_DATE_SHIFT); + + return dg1; +} + +const CHUNK_SIZE = 186; +export function getDG1Commitment(dg1: bigint[], skIdentity: bigint): bigint { + const chunks: bigint[] = Array(4).fill(0); + + for (let i = 0; i < 4; i++) { + chunks[i] = BigInt( + "0b" + + dg1 + .slice(i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE) + .reverse() + .join(""), + ); + } + + return Poseidon.hash([...chunks, Poseidon.hash([skIdentity])]); +} diff --git a/test/registration/RegistrationSimple.test.ts b/test/registration/RegistrationSimple.test.ts new file mode 100644 index 0000000..053d50d --- /dev/null +++ b/test/registration/RegistrationSimple.test.ts @@ -0,0 +1,173 @@ +import { zkit, ethers } from "hardhat"; +import { HDNodeWallet } from "ethers"; + +import { Groth16Proof } from "@solarity/zkit"; + +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; + +import { createDG1Data } from "@/test/helpers/dg1"; + +import { getPoseidon, Reverter, TSSMerkleTree, TSSSigner } from "@/test/helpers"; + +import { PoseidonSMTMock, RegisterIdentityLight256Verifier, RegistrationSimple, StateKeeperMock } from "@ethers-v6"; + +import { PrivateRegisterIdentityLight256Groth16, RegisterIdentityLight256 } from "@/generated-types/zkit"; +import { VerifierHelper } from "@/generated-types/ethers/contracts/registration/Registration"; + +const treeSize = 80; +const chainName = "Tests"; + +const registrationName = "Registration"; + +const icaoMerkleRoot = "0x2c50ce3aa92bc3dd0351a89970b02630415547ea83c487befbc8b1795ea90c45"; + +describe("RegistrationSimple", () => { + const reverter = new Reverter(); + + let signHelper: TSSSigner; + let merkleTree: TSSMerkleTree; + + let OWNER: SignerWithAddress; + let SIGNER: HDNodeWallet; + + let registerLight: RegisterIdentityLight256; + + let registrationSimple: RegistrationSimple; + + let registrationSmt: PoseidonSMTMock; + let certificatesSmt: PoseidonSMTMock; + let stateKeeper: StateKeeperMock; + + let registerLightVerifier: RegisterIdentityLight256Verifier; + + before(async () => { + registerLight = await zkit.getCircuit("RegisterIdentityLight256"); + + [OWNER] = await ethers.getSigners(); + SIGNER = ethers.Wallet.createRandom(); + + const StateKeeper = await ethers.getContractFactory("StateKeeperMock", { + libraries: { + PoseidonUnit1L: await (await getPoseidon(1)).getAddress(), + PoseidonUnit2L: await (await getPoseidon(2)).getAddress(), + PoseidonUnit3L: await (await getPoseidon(3)).getAddress(), + }, + }); + const PoseidonSMT = await ethers.getContractFactory("PoseidonSMTMock", { + libraries: { + PoseidonUnit2L: await (await getPoseidon(2)).getAddress(), + PoseidonUnit3L: await (await getPoseidon(3)).getAddress(), + }, + }); + + registerLightVerifier = await ethers.deployContract("RegisterIdentityLight256Verifier"); + + registrationSimple = await ethers.deployContract("RegistrationSimple"); + + const Proxy = await ethers.getContractFactory("ERC1967Proxy"); + + registrationSmt = await PoseidonSMT.deploy(); + certificatesSmt = await PoseidonSMT.deploy(); + stateKeeper = await StateKeeper.deploy(); + + let proxy = await Proxy.deploy(await stateKeeper.getAddress(), "0x"); + stateKeeper = await ethers.getContractAt("StateKeeperMock", await proxy.getAddress()); + + proxy = await Proxy.deploy(await registrationSmt.getAddress(), "0x"); + registrationSmt = await ethers.getContractAt("PoseidonSMTMock", await proxy.getAddress()); + + proxy = await Proxy.deploy(await certificatesSmt.getAddress(), "0x"); + certificatesSmt = await ethers.getContractAt("PoseidonSMTMock", await proxy.getAddress()); + + proxy = await Proxy.deploy(await registrationSimple.getAddress(), "0x"); + registrationSimple = await ethers.getContractAt("RegistrationSimple", await proxy.getAddress()); + + await registrationSmt.__PoseidonSMT_init(SIGNER.address, chainName, await stateKeeper.getAddress(), treeSize); + await certificatesSmt.__PoseidonSMT_init(SIGNER.address, chainName, await stateKeeper.getAddress(), treeSize); + + await stateKeeper.__StateKeeper_init( + SIGNER.address, + chainName, + await registrationSmt.getAddress(), + await certificatesSmt.getAddress(), + icaoMerkleRoot, + ); + + await registrationSimple.__RegistrationSimple_init(SIGNER.address, chainName, await stateKeeper.getAddress(), [ + OWNER.address, + ]); + + signHelper = new TSSSigner(SIGNER); + merkleTree = new TSSMerkleTree(signHelper); + + await stateKeeper.mockAddRegistrations([registrationName], [await registrationSimple.getAddress()]); + + await reverter.snapshot(); + }); + + afterEach(reverter.revert); + + it("should successfully register a user", async () => { + const dg1Data = createDG1Data({ + citizenship: "ABW", + name: "Somebody", + nameResidual: "", + documentNumber: "", + expirationDate: "251210", + birthDate: "221210", + sex: "M", + nationality: "ABW", + }); + + const identityKey = 123n; + + const inputs: PrivateRegisterIdentityLight256Groth16 = { + dg1: dg1Data, + skIdentity: identityKey, + }; + const proof = await registerLight.generateProof(inputs); + const passportData: RegistrationSimple.PassportStruct = { + dgCommit: ethers.toBeHex(proof.publicSignals.dg1Commitment, 32), + dg1Hash: ethers.toBeHex(proof.publicSignals.dg1Hash, 32), + publicKey: ethers.toBeHex(0n, 32), + passportHash: ethers.toBeHex(proof.publicSignals.dg1Hash, 32), + verifier: await registerLightVerifier.getAddress(), + }; + + const signature = await getSimpleSignature(passportData); + + await registrationSimple.registerSimple( + proof.publicSignals.pkIdentityHash, + passportData, + signature, + formatProof(proof.proof), + ); + }); + + function formatProof(data: Groth16Proof): VerifierHelper.ProofPointsStruct { + return { + a: [data.pi_a[0], data.pi_a[1]], + b: [ + [data.pi_b[0][1], data.pi_b[0][0]], + [data.pi_b[1][1], data.pi_b[1][0]], + ], + c: [data.pi_c[0], data.pi_c[1]], + }; + } + + async function getSimpleSignature(passportData: RegistrationSimple.PassportStruct) { + const message = ethers.solidityPackedKeccak256( + ["string", "address", "bytes32", "bytes32", "bytes32", "address"], + [ + await registrationSimple.REGISTRATION_SIMPLE_PREFIX(), + await registrationSimple.getAddress(), + passportData.passportHash, + passportData.dgCommit, + passportData.publicKey, + passportData.verifier, + ], + ); + + return OWNER.provider.send("eth_sign", [OWNER.address, message]); + } +});