Skip to content

Commit

Permalink
check verifierID in requests for V3
Browse files Browse the repository at this point in the history
  • Loading branch information
daveroga committed Jan 13, 2025
1 parent f607131 commit 848e609
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 59 deletions.
7 changes: 7 additions & 0 deletions contracts/verifiers/UniversalVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ contract UniversalVerifier is
_setState(state);
}

/**
* @dev Sets the verifier ID
*/
function setVerifierID(uint256 verifierID) public onlyOwner {
_setVerifierID(verifierID);
}

/**
* @dev Sets the request owner address
* @param requestId The ID of the request
Expand Down
34 changes: 34 additions & 0 deletions contracts/verifiers/Verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {IAuthValidator} from "../interfaces/IAuthValidator.sol";
import {IState} from "../interfaces/IState.sol";
import {VerifierLib} from "../lib/VerifierLib.sol";
import {IVerifier} from "../interfaces/IVerifier.sol";
import {GenesisUtils} from "../lib/GenesisUtils.sol";

error RequestIdNotFound(uint256 requestId);
error RequestAlreadyExists(uint256 requestId);
Expand All @@ -26,6 +27,7 @@ error UserNotAuthenticated();
error MetadataNotSupportedYet();
error GroupMustHaveAtLeastTwoRequests(uint256 groupID);
error NullifierSessionIDAlreadyExists(uint256 nullifierSessionID);
error VerifierIDIsNotValid(uint256 requestVerifierID, uint256 expectedVerifierID);

abstract contract Verifier is IVerifier, ContextUpgradeable {
/// @dev Key to retrieve the linkID from the proof storage
Expand Down Expand Up @@ -64,6 +66,8 @@ abstract contract Verifier is IVerifier, ContextUpgradeable {
string[] _authTypes;
mapping(string authType => AuthTypeData) _authMethods;
mapping(uint256 nullifierSessionID => uint256 requestId) _nullifierSessionIDs;
// verifierID to check in requests
uint256 _verifierID;
}

// solhint-disable-next-line
Expand Down Expand Up @@ -153,6 +157,11 @@ abstract contract Verifier is IVerifier, ContextUpgradeable {

function __Verifier_init_unchained(IState state) internal onlyInitializing {
_setState(state);
// initial calculation of verifierID from contract address and default id type from State contract
VerifierStorage storage s = _getVerifierStorage();
bytes2 idType = s._state.getDefaultIdType();
uint256 calculatedVerifierID = GenesisUtils.calcIdFromEthAddress(idType, address(this));
_setVerifierID(calculatedVerifierID);
}

function _getVerifierStorage() private pure returns (VerifierStorage storage $) {
Expand All @@ -161,6 +170,11 @@ abstract contract Verifier is IVerifier, ContextUpgradeable {
}
}

function _setVerifierID(uint256 verifierID) internal {
VerifierStorage storage s = _getVerifierStorage();
s._verifierID = verifierID;
}

/**
* @dev Checks if a request ID exists
* @param requestId The ID of the request
Expand Down Expand Up @@ -272,6 +286,7 @@ abstract contract Verifier is IVerifier, ContextUpgradeable {
// 2. Set requests checking groups and nullifierSessionID uniqueness
for (uint256 i = 0; i < requests.length; i++) {
_checkNullifierSessionIdUniqueness(requests[i]);
_checkVerifierID(requests[i]);

uint256 groupID = requests[i].validator.getRequestParams(requests[i].params).groupID;

Expand All @@ -290,6 +305,17 @@ abstract contract Verifier is IVerifier, ContextUpgradeable {
}
}

function _checkVerifierID(IVerifier.Request calldata request) internal view {
VerifierStorage storage s = _getVerifierStorage();
uint256 requestVerifierID = request.validator.getRequestParams(request.params).verifierID;

if (requestVerifierID != 0) {
if (requestVerifierID != s._verifierID) {
revert VerifierIDIsNotValid(requestVerifierID, s._verifierID);
}
}
}

function _checkNullifierSessionIdUniqueness(IVerifier.Request calldata request) internal {
VerifierStorage storage s = _getVerifierStorage();
uint256 nullifierSessionID = request
Expand Down Expand Up @@ -729,6 +755,14 @@ abstract contract Verifier is IVerifier, ContextUpgradeable {
return address(_getVerifierStorage()._state);
}

/**
* @dev Gets the verifierID of the verifier contract
* @return uint256 verifierID of the verifier contract
*/
function getVerifierID() public view virtual returns (uint256) {
return _getVerifierStorage()._verifierID;
}

/**
* @dev Checks the proof status for a given user and request ID
* @param sender The sender's address
Expand Down
125 changes: 66 additions & 59 deletions test/verifier/universal-verifier-multi-query.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,65 +47,11 @@ describe("Universal Verifier Multi-request", function () {
"20376033832371109177683048456014525905119173674985843915445634726167450989630";
const [merklized, isRevocationChecked, valueArrSize] = [1, 1, 1];
const nullifierSessionId = "0";
const verifierId = "1";
const queryHash = calculateQueryHashV3(
value,
schema,
slotIndex,
operator,
claimPathKey,
valueArrSize,
merklized,
isRevocationChecked,
verifierId,
nullifierSessionId,
);

const requestQuery1 = {
schema,
claimPathKey,
operator,
slotIndex,
value,
// we can use the same offchain circuit id because now an auth request is used for authentication
circuitIds: [CircuitId.AuthV2],
skipClaimRevocationCheck: false,
queryHash,
groupID: 0,
nullifierSessionID: nullifierSessionId, // for ethereum based user
proofType: 1, // 1 for BJJ
verifierID: verifierId,
};

const requestQuery2 = {
schema,
claimPathKey,
operator,
slotIndex,
value,
circuitIds: [CircuitId.AtomicQueryV3],
skipClaimRevocationCheck: false,
queryHash,
groupID: 1,
nullifierSessionID: nullifierSessionId, // for ethereum based user
proofType: 1, // 1 for BJJ
verifierID: verifierId,
};

const requestQuery3 = {
schema,
claimPathKey,
operator,
slotIndex,
value,
circuitIds: [CircuitId.AtomicQueryV3],
skipClaimRevocationCheck: false,
queryHash,
groupID: 1,
nullifierSessionID: nullifierSessionId, // for ethereum based user
proofType: 1, // 1 for BJJ
verifierID: verifierId,
};
let verifierId;
let queryHash: any;
let requestQuery1: any;
let requestQuery2: any;
let requestQuery3: any;

const storageFields = [
{
Expand Down Expand Up @@ -144,6 +90,67 @@ describe("Universal Verifier Multi-request", function () {
await verifierLib.getAddress(),
);

verifierId = await verifier.getVerifierID();

queryHash = calculateQueryHashV3(
value,
schema,
slotIndex,
operator,
claimPathKey,
valueArrSize,
merklized,
isRevocationChecked,
verifierId,
nullifierSessionId,
);

requestQuery1 = {
schema,
claimPathKey,
operator,
slotIndex,
value,
// we can use the same offchain circuit id because now an auth request is used for authentication
circuitIds: [CircuitId.AuthV2],
skipClaimRevocationCheck: false,
queryHash,
groupID: 0,
nullifierSessionID: nullifierSessionId, // for ethereum based user
proofType: 1, // 1 for BJJ
verifierID: verifierId,
};

requestQuery2 = {
schema,
claimPathKey,
operator,
slotIndex,
value,
circuitIds: [CircuitId.AtomicQueryV3],
skipClaimRevocationCheck: false,
queryHash,
groupID: 1,
nullifierSessionID: nullifierSessionId, // for ethereum based user
proofType: 1, // 1 for BJJ
verifierID: verifierId,
};

requestQuery3 = {
schema,
claimPathKey,
operator,
slotIndex,
value,
circuitIds: [CircuitId.AtomicQueryV3],
skipClaimRevocationCheck: false,
queryHash,
groupID: 1,
nullifierSessionID: nullifierSessionId, // for ethereum based user
proofType: 1, // 1 for BJJ
verifierID: verifierId,
};

v3Validator = await deployHelper.deployValidatorStub("RequestValidatorV3Stub");
v3_2Validator = await deployHelper.deployValidatorStub("RequestValidatorV3_2Stub");
authV2Validator = await deployHelper.deployValidatorStub("AuthValidatorStub");
Expand Down
33 changes: 33 additions & 0 deletions test/verifier/universal-verifier.v3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ describe("Universal Verifier V3 validator", function () {
await stateContract.getAddress(),
await verifierLib.getAddress(),
);
// set the verifierID of the proof for the test
await universalVerifier.setVerifierID(verifierId);
await universalVerifier.addValidatorToWhitelist(await v3Validator.getAddress());
await universalVerifier.connect();

Expand Down Expand Up @@ -559,4 +561,35 @@ describe("Universal Verifier V3 validator", function () {
]),
).to.be.rejectedWith(`NullifierSessionIDAlreadyExists(${query2.nullifierSessionID})`);
});

it("Test set request fails with VerifierIDIsNotValid", async () => {
({
ethSigner: signer,
ethSigner2: signer2,
stateContract: state,
v3Validator: v3Validator,
universalVerifier: verifier,
} = await loadFixture(deployContractsFixture));

await verifier.setVerifierID(1);

const query2 = {
...query,
};
query2.groupID = 0;
const params = packV3ValidatorParams(query2);
const requestId = 40;
await expect(
verifier.setRequests([
{
requestId: requestId,
metadata: "metadata",
validator: await v3Validator.getAddress(),
params: params,
},
]),
).to.be.rejectedWith(
`VerifierIDIsNotValid(21929109382993718606847853573861987353620810345503358891473103689157378049, ${await verifier.getVerifierID()})`,
);
});
});

0 comments on commit 848e609

Please sign in to comment.