Skip to content

Commit 7286848

Browse files
committed
refactor: root verifier design
1 parent 182a9b3 commit 7286848

File tree

11 files changed

+192
-152
lines changed

11 files changed

+192
-152
lines changed

src/solidity/script/AddVerifiers.s.sol renamed to src/solidity/script/AddSubVerifiers.s.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ contract Deploy is Script {
102102
console.log("Outer (13 subproofs) verifier deployed at:", verifierAddresses[9]);
103103

104104
// Add verifiers to ZKPassportVerifier
105-
console.log("Adding verifiers to ZKPassportVerifier...");
106-
zkPassportVerifier.addVerifiers(vkeyHashes, verifierAddresses);
107-
console.log("Verifiers added to ZKPassportVerifier");
105+
console.log("Adding sub-verifiers to ZKPassportVerifier...");
106+
zkPassportVerifier.addSubVerifiers(vkeyHashes, verifierAddresses);
107+
console.log("Sub-verifiers added to ZKPassportVerifier");
108108

109109
// Stop broadcasting transactions
110110
vm.stopBroadcast();

src/solidity/script/Deploy.s.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ contract Deploy is Script {
9999
console.log("ZKPassportVerifier deployed at:", address(zkPassportVerifier));
100100

101101
// Add verifiers to ZKPassportVerifier
102-
console.log("Adding verifiers to ZKPassportVerifier...");
103-
zkPassportVerifier.addVerifiers(vkeyHashes, verifierAddresses);
104-
console.log("Verifiers added to ZKPassportVerifier");
102+
console.log("Adding sub-verifiers to ZKPassportVerifier...");
103+
zkPassportVerifier.addSubVerifiers(vkeyHashes, verifierAddresses);
104+
console.log("Sub-verifiers added to ZKPassportVerifier");
105105

106106
// Stop broadcasting transactions
107107
vm.stopBroadcast();

src/solidity/script/DeployWithExistingVerifiers.s.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ contract Deploy is Script {
5757
ZKPassportVerifier zkPassportVerifier = new ZKPassportVerifier(rootRegistry);
5858
console.log("ZKPassportVerifier deployed at:", address(zkPassportVerifier));
5959

60-
// Add verifiers to ZKPassportVerifier
61-
console.log("Adding verifiers to ZKPassportVerifier...");
62-
zkPassportVerifier.addVerifiers(vkeyHashes, verifierAddresses);
63-
console.log("Verifiers added to ZKPassportVerifier");
60+
// Add sub-verifiers to ZKPassportVerifier
61+
console.log("Adding sub-verifiers to ZKPassportVerifier...");
62+
zkPassportVerifier.addSubVerifiers(vkeyHashes, verifierAddresses);
63+
console.log("Sub-verifiers added to ZKPassportVerifier");
6464

6565
// Stop broadcasting transactions
6666
vm.stopBroadcast();
6767

68-
// Create JSON for verifiers
68+
// Create JSON for sub-verifiers
6969
string memory verifiers = "verifiers";
7070
vm.serializeAddress(verifiers, "outer_count_4", verifierAddresses[0]);
7171
vm.serializeAddress(verifiers, "outer_count_5", verifierAddresses[1]);

src/solidity/src/SampleContract.sol

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ pragma solidity >=0.8.21;
44

55
import {DateUtils} from "../src/DateUtils.sol";
66
import {StringUtils} from "../src/StringUtils.sol";
7-
import {DisclosedData} from "../src/Types.sol";
8-
import {ZKPassportVerifier, ProofType, ProofVerificationParams, DisclosedData} from "../src/ZKPassportVerifier.sol";
7+
import {DisclosedData, ProofVerificationParams} from "../src/Types.sol";
8+
import {ZKPassportVerifier} from "../src/ZKPassportVerifier.sol";
9+
import {ZKPassportRootVerifier} from "../src/ZKPassportRootVerifier.sol";
910
import {console} from "forge-std/console.sol";
1011

1112
contract SampleContract {
1213
address public admin;
13-
ZKPassportVerifier public zkPassportVerifier;
14-
14+
uint256 public constant ZKPASSPORT_VERIFIER_VERSION = 1;
15+
ZKPassportRootVerifier public zkPassportRootVerifier;
1516
// Unique Identifier => whether it was verified or not
1617
mapping(bytes32 => bool) public isVerified;
1718
// Unique Identifier => nationality
@@ -34,8 +35,8 @@ contract SampleContract {
3435
_;
3536
}
3637

37-
function setZKPassportVerifier(address _zkPassportVerifier) public onlyAdmin {
38-
zkPassportVerifier = ZKPassportVerifier(_zkPassportVerifier);
38+
function setZKPassportVerifier(address _verifier) public onlyAdmin {
39+
zkPassportRootVerifier = ZKPassportRootVerifier(_verifier);
3940
}
4041

4142
function setDomain(string calldata _domain) public onlyAdmin {
@@ -59,25 +60,28 @@ contract SampleContract {
5960
// and the SDK will tell you which one they have
6061
bool isIDCard
6162
) public returns (bytes32) {
62-
(bool verified, bytes32 uniqueIdentifier) = zkPassportVerifier.verifyProof(params);
63+
// Get the current verifier from the ZKPassportRootVerifier
64+
ZKPassportVerifier verifier = ZKPassportVerifier(zkPassportRootVerifier.getVerifier(ZKPASSPORT_VERIFIER_VERSION));
65+
// Verify the proof
66+
(bool verified, bytes32 uniqueIdentifier) = verifier.verifyProof(params);
6367
require(verified, "Proof is invalid");
6468
require(!isVerified[uniqueIdentifier], "User already verified");
6569
// Check the proof was generated using your domain name (scope) and the subscope
6670
// you specified
6771
require(
68-
zkPassportVerifier.verifyScopes(params.proofVerificationData.publicInputs, validDomain, validScope),
72+
verifier.verifyScopes(params.proofVerificationData.publicInputs, validDomain, validScope),
6973
"Invalid domain or scope"
7074
);
71-
require(zkPassportVerifier.isAgeAboveOrEqual(18, params.commitments), "Age is not 18+");
72-
DisclosedData memory disclosedData = zkPassportVerifier.getDisclosedData(
75+
require(verifier.isAgeAboveOrEqual(18, params.commitments), "Age is not 18+");
76+
DisclosedData memory disclosedData = verifier.getDisclosedData(
7377
params.commitments,
74-
isIDCard
78+
isIDCard
7579
);
7680
string[] memory nationalityExclusionList = new string[](3);
7781
nationalityExclusionList[0] = "ESP";
7882
nationalityExclusionList[1] = "ITA";
7983
nationalityExclusionList[2] = "PRT";
80-
require(zkPassportVerifier.isNationalityOut(nationalityExclusionList, params.commitments), "Nationality is part of the exclusion list");
84+
require(verifier.isNationalityOut(nationalityExclusionList, params.commitments), "Nationality is part of the exclusion list");
8185

8286
// If all good, mark the user as verified
8387
isVerified[uniqueIdentifier] = true;

src/solidity/src/ZKPassportRootVerifier.sol

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,46 @@ contract ZKPassportRootVerifier {
99
address public guardian;
1010
bool public paused;
1111

12-
IZKPassportVerifier public verifier;
12+
mapping(uint256 => IZKPassportVerifier) public verifiers;
1313

1414
// Events
1515
event AdminUpdated(address indexed oldAdmin, address indexed newAdmin);
1616
event GuardianUpdated(address indexed oldGuardian, address indexed newGuardian);
17-
event VerifierUpdated(address indexed oldVerifier, address indexed newVerifier);
17+
event VerifierAdded(uint256 indexed version, address indexed verifier);
18+
event VerifierRemoved(uint256 indexed version, address indexed verifier);
19+
event VerifierUpdated(uint256 indexed version, address indexed oldVerifier, address indexed newVerifier);
1820
event PausedStatusChanged(bool paused);
1921

2022
/**
2123
* @dev Constructor
2224
* @param _admin The address of the admin
2325
* @param _guardian The address of the guardian
26+
* @param _version The initial version number for the verifier
2427
* @param _verifier The address of the ZKPassport verifier implementation
2528
*/
26-
constructor(address _admin, address _guardian, address _verifier) {
29+
constructor(address _admin, address _guardian, uint256 _version, address _verifier) {
2730
require(_admin != address(0), "Admin cannot be zero address");
31+
require(_verifier != address(0), "Verifier cannot be zero address");
32+
require(_version > 0, "Version must be greater than 0");
2833
admin = _admin;
2934
guardian = _guardian;
30-
verifier = IZKPassportVerifier(_verifier);
35+
verifiers[_version] = IZKPassportVerifier(_verifier);
36+
emit VerifierAdded(_version, _verifier);
3137
}
3238

3339
/**
34-
* @notice Verifies a ZKPassport proof
40+
* @notice Verifies a ZKPassport proof using a specific verifier version
41+
* @param version The version number of the verifier to use
3542
* @param params The proof verification parameters
3643
* @return valid True if the proof is valid or false otherwise
3744
* @return uniqueIdentifier The unique identifier associated with the ID used to generate the proof
3845
*/
3946
function verify(
47+
uint256 version,
4048
ProofVerificationParams calldata params
4149
) external view whenNotPaused returns (bool valid, bytes32 uniqueIdentifier) {
50+
IZKPassportVerifier verifier = verifiers[version];
51+
require(address(verifier) != address(0), "Verifier not found for version");
4252
(valid, uniqueIdentifier) = verifier.verifyProof(params);
4353
return (valid, uniqueIdentifier);
4454
}
@@ -71,10 +81,52 @@ contract ZKPassportRootVerifier {
7181
emit GuardianUpdated(oldGuardian, newGuardian);
7282
}
7383

74-
function setVerifier(address newVerifier) external onlyAdmin {
75-
address oldVerifier = address(verifier);
76-
verifier = IZKPassportVerifier(newVerifier);
77-
emit VerifierUpdated(oldVerifier, newVerifier);
84+
/**
85+
* @notice Gets the verifier address for a specific version
86+
* @param version The version number
87+
* @return The verifier address for the given version
88+
*/
89+
function getVerifier(uint256 version) external view returns (address) {
90+
return address(verifiers[version]);
91+
}
92+
93+
/**
94+
* @notice Adds a verifier for a specific version
95+
* @param version The version number
96+
* @param newVerifier The address of the verifier
97+
*/
98+
function addVerifier(uint256 version, address newVerifier) external onlyAdmin {
99+
require(newVerifier != address(0), "Verifier cannot be zero address");
100+
require(version > 0, "Version must be greater than 0");
101+
require((address)(verifiers[version]) == address(0), "Verifier already exists for version");
102+
verifiers[version] = IZKPassportVerifier(newVerifier);
103+
emit VerifierAdded(version, newVerifier);
104+
}
105+
106+
/**
107+
* @notice Removes a verifier for a specific version
108+
* @param version The version number
109+
*/
110+
function removeVerifier(uint256 version) external onlyAdmin {
111+
require(version > 0, "Version must be greater than 0");
112+
address verifierAddress = address(verifiers[version]);
113+
require(verifierAddress != address(0), "Verifier not found for version");
114+
delete verifiers[version];
115+
emit VerifierRemoved(version, verifierAddress);
116+
}
117+
118+
/**
119+
* @notice Updates a verifier for a specific version
120+
* @param version The version number
121+
* @param newVerifier The address of the verifier
122+
*/
123+
function updateVerifier(uint256 version, address newVerifier) external onlyAdmin {
124+
require(version > 0, "Version must be greater than 0");
125+
require(newVerifier != address(0), "Verifier cannot be zero address");
126+
require((address)(verifiers[version]) != address(0), "Verifier not found for version");
127+
address oldVerifier = address(verifiers[version]);
128+
verifiers[version] = IZKPassportVerifier(newVerifier);
129+
emit VerifierUpdated(version, oldVerifier, newVerifier);
78130
}
79131

80132
function setPaused(bool _paused) external onlyGuardian {

src/solidity/src/ZKPassportVerifier.sol

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ contract ZKPassportVerifier {
1919
bool public paused;
2020

2121
// Mapping from vkey hash of each Outer Circuit to its Ultra Honk Verifier address
22-
mapping(bytes32 => address) public vkeyHashToVerifier;
22+
mapping(bytes32 => address) public vkeyHashToSubVerifier;
2323

2424
// Maybe make this immutable as this should most likely not change
2525
IRootRegistry public rootRegistry;
@@ -28,8 +28,8 @@ contract ZKPassportVerifier {
2828
event AdminUpdated(address indexed oldAdmin, address indexed newAdmin);
2929
event PausedStatusChanged(bool paused);
3030
event ZKPassportVerifierDeployed(address indexed admin, uint256 timestamp);
31-
event VerifierAdded(bytes32 indexed vkeyHash, address indexed verifier);
32-
event VerifierRemoved(bytes32 indexed vkeyHash);
31+
event SubVerifierAdded(bytes32 indexed vkeyHash, address indexed verifier);
32+
event SubVerifierRemoved(bytes32 indexed vkeyHash);
3333
event CertificateRegistryRootAdded(bytes32 indexed certificateRegistryRoot);
3434
event CertificateRegistryRootRemoved(bytes32 indexed certificateRegistryRoot);
3535
event SanctionsTreesRootUpdates(bytes32 indexed _sanctionsTreesRoot);
@@ -66,20 +66,20 @@ contract ZKPassportVerifier {
6666
emit PausedStatusChanged(_paused);
6767
}
6868

69-
function addVerifiers(
69+
function addSubVerifiers(
7070
bytes32[] calldata vkeyHashes,
7171
address[] calldata verifiers
7272
) external onlyAdmin {
7373
for (uint256 i = 0; i < vkeyHashes.length; i++) {
74-
vkeyHashToVerifier[vkeyHashes[i]] = verifiers[i];
75-
emit VerifierAdded(vkeyHashes[i], verifiers[i]);
74+
vkeyHashToSubVerifier[vkeyHashes[i]] = verifiers[i];
75+
emit SubVerifierAdded(vkeyHashes[i], verifiers[i]);
7676
}
7777
}
7878

79-
function removeVerifiers(bytes32[] calldata vkeyHashes) external onlyAdmin {
79+
function removeSubVerifiers(bytes32[] calldata vkeyHashes) external onlyAdmin {
8080
for (uint256 i = 0; i < vkeyHashes.length; i++) {
81-
delete vkeyHashToVerifier[vkeyHashes[i]];
82-
emit VerifierRemoved(vkeyHashes[i]);
81+
delete vkeyHashToSubVerifier[vkeyHashes[i]];
82+
emit SubVerifierRemoved(vkeyHashes[i]);
8383
}
8484
}
8585

@@ -102,7 +102,7 @@ contract ZKPassportVerifier {
102102
* @param isIDCard Whether the proof is an ID card
103103
* @return disclosedData The data disclosed by the proof
104104
*/
105-
function getDisclosedData(
105+
function getDisclosedData(
106106
Commitments calldata commitments,
107107
bool isIDCard
108108
) public pure returns (DisclosedData memory disclosedData) {
@@ -589,7 +589,7 @@ contract ZKPassportVerifier {
589589
}
590590

591591
function _getVerifier(bytes32 vkeyHash) internal view returns (address) {
592-
address verifier = vkeyHashToVerifier[vkeyHash];
592+
address verifier = vkeyHashToSubVerifier[vkeyHash];
593593
require(verifier != address(0), "Verifier not found");
594594
return verifier;
595595
}
@@ -665,7 +665,7 @@ contract ZKPassportVerifier {
665665
|| params.serviceConfig.devMode,
666666
"Mock proofs are only allowed in dev mode"
667667
);
668-
668+
669669
// For now, only non-salted nullifiers are supported
670670
// but salted nullifiers can be used in dev mode
671671
// They will be later once a proper registration mechanism is implemented

0 commit comments

Comments
 (0)