Skip to content

Commit

Permalink
check nullifierSessionID on request creation
Browse files Browse the repository at this point in the history
  • Loading branch information
daveroga committed Jan 10, 2025
1 parent 188bb13 commit ffe4e6e
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 12 deletions.
4 changes: 3 additions & 1 deletion contracts/interfaces/IRequestValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ interface IRequestValidator {
* @dev RequestParams. Information about request params from request query data.
* @param groupID Group ID of the request query params
* @param verifierID Verifier ID of the request query params
* @param nullifierSessionID NullifierSessionID of the request query params
*/
struct RequestParams {
uint256 groupID;
uint256 verifierID;
uint256 nullifierSessionID;
}

/**
Expand All @@ -51,7 +53,7 @@ interface IRequestValidator {
/**
* @dev Get the request params of the request query data.
* @param params Request query data of the credential to verify.
* @return Group ID of the request query data.
* @return RequestParams of the request query data.
*/
function getRequestParams(bytes calldata params) external view returns (RequestParams memory);
}
2 changes: 1 addition & 1 deletion contracts/test-helpers/RequestValidatorAuthV2Stub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ contract RequestValidatorAuthV2Stub is IRequestValidator, ERC165 {
function getRequestParams(
bytes calldata
) external pure override returns (IRequestValidator.RequestParams memory) {
return IRequestValidator.RequestParams({groupID: 0, verifierID: 0});
return IRequestValidator.RequestParams({groupID: 0, verifierID: 0, nullifierSessionID: 0});
}
}
2 changes: 1 addition & 1 deletion contracts/test-helpers/RequestValidatorV2Stub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ contract RequestValidatorV2Stub is IRequestValidator, ERC165 {
function getRequestParams(
bytes calldata
) external pure override returns (IRequestValidator.RequestParams memory) {
return IRequestValidator.RequestParams({groupID: 0, verifierID: 0});
return IRequestValidator.RequestParams({groupID: 0, verifierID: 0, nullifierSessionID: 0});
}
}
3 changes: 2 additions & 1 deletion contracts/test-helpers/RequestValidatorV3Stub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ contract RequestValidatorV3Stub is IRequestValidator, ERC165 {
return
IRequestValidator.RequestParams({
groupID: credAtomicQuery.groupID,
verifierID: credAtomicQuery.verifierID
verifierID: credAtomicQuery.verifierID,
nullifierSessionID: credAtomicQuery.nullifierSessionID
});
}
}
3 changes: 2 additions & 1 deletion contracts/test-helpers/RequestValidatorV3_2Stub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ contract RequestValidatorV3_2Stub is IRequestValidator, ERC165 {
return
IRequestValidator.RequestParams({
groupID: credAtomicQuery.groupID,
verifierID: credAtomicQuery.verifierID
verifierID: credAtomicQuery.verifierID,
nullifierSessionID: credAtomicQuery.nullifierSessionID
});
}
}
2 changes: 1 addition & 1 deletion contracts/validators/AuthV2Validator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ contract AuthV2Validator is CredentialAtomicQueryValidatorBase {
function getRequestParams(
bytes calldata
) external pure override returns (IRequestValidator.RequestParams memory) {
return IRequestValidator.RequestParams({groupID: 0, verifierID: 0});
return IRequestValidator.RequestParams({groupID: 0, verifierID: 0, nullifierSessionID: 0});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ abstract contract CredentialAtomicQueryV2ValidatorBase is CredentialAtomicQueryV
function getRequestParams(
bytes calldata
) external pure override returns (IRequestValidator.RequestParams memory) {
return IRequestValidator.RequestParams({groupID: 0, verifierID: 0});
return IRequestValidator.RequestParams({groupID: 0, verifierID: 0, nullifierSessionID: 0});
}

/**
Expand Down
8 changes: 7 additions & 1 deletion contracts/validators/CredentialAtomicQueryV3Validator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {GenesisUtils} from "../lib/GenesisUtils.sol";
import {IRequestValidator} from "../interfaces/IRequestValidator.sol";
import {IState} from "../interfaces/IState.sol";

error VerifierIDNotSet();

/**
* @dev CredentialAtomicQueryV3 validator
*/
Expand Down Expand Up @@ -154,10 +156,14 @@ contract CredentialAtomicQueryV3Validator is CredentialAtomicQueryValidatorBase
params,
(CredentialAtomicQueryV3)
);

if (credAtomicQuery.verifierID == 0) revert VerifierIDNotSet();

return
IRequestValidator.RequestParams({
groupID: credAtomicQuery.groupID,
verifierID: credAtomicQuery.verifierID
verifierID: credAtomicQuery.verifierID,
nullifierSessionID: credAtomicQuery.nullifierSessionID
});
}

Expand Down
15 changes: 13 additions & 2 deletions contracts/verifiers/Verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ error UserIDNotLinkedToAddress(uint256 userID, address userAddress);
error UserNotAuthenticated();
error MetadataNotSupportedYet();
error GroupMustHaveAtLeastTwoRequests(uint256 groupID);
error NullifierSessionIDAlreadyExists(uint256 nullifierSessionID);

abstract contract Verifier is IVerifier, ContextUpgradeable {
/// @dev Key to retrieve the linkID from the proof storage
Expand Down Expand Up @@ -62,6 +63,7 @@ abstract contract Verifier is IVerifier, ContextUpgradeable {
// Information about auth types and validators
string[] _authTypes;
mapping(string authType => AuthTypeData) _authMethods;
mapping(uint256 nullifierSessionID => uint256 requestId) _nullifierSessionIDs;
}

// solhint-disable-next-line
Expand Down Expand Up @@ -240,9 +242,10 @@ abstract contract Verifier is IVerifier, ContextUpgradeable {
uint256[] memory newGroupsGroupID = new uint256[](requests.length);
uint256[] memory newGroupsRequestCount = new uint256[](requests.length);

// 1. Check first that groupIds don't exist and keep the number of requests per group
// 1. Check first that groupIds don't exist and keep the number of requests per group.
for (uint256 i = 0; i < requests.length; i++) {
uint256 groupID = requests[i].validator.getRequestParams(requests[i].params).groupID;

Check failure on line 248 in contracts/verifiers/Verifier.sol

View workflow job for this annotation

GitHub Actions / solhint

Delete ············⏎

if (groupID != 0) {
if (groupIdExists(groupID)) {
Expand All @@ -267,8 +270,16 @@ abstract contract Verifier is IVerifier, ContextUpgradeable {

_checkGroupsRequestsCount(newGroupsGroupID, newGroupsRequestCount, newGroupsCount);

// 2. Set requests checking groups
// 2. Set requests checking groups and nullifierSessionID uniqueness
for (uint256 i = 0; i < requests.length; i++) {
uint256 nullifierSessionID = requests[i].validator.getRequestParams(requests[i].params).nullifierSessionID;

Check failure on line 275 in contracts/verifiers/Verifier.sol

View workflow job for this annotation

GitHub Actions / solhint

Replace .validator.getRequestParams(requests[i].params) with ⏎················.validator⏎················.getRequestParams(requests[i].params)⏎················
if (nullifierSessionID != 0) {
if (s._nullifierSessionIDs[nullifierSessionID] != 0) {
revert NullifierSessionIDAlreadyExists(nullifierSessionID);
}
s._nullifierSessionIDs[nullifierSessionID] = requests[i].requestId;
}

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

// request without group
Expand Down
50 changes: 48 additions & 2 deletions test/verifier/universal-verifier.v3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,15 @@ describe("Universal Verifier V3 validator", function () {
query2.groupID = 4;
const requestId = 36;
const params = packV3ValidatorParams(query2);

const query3 = {
...query,
};
query3.nullifierSessionID = "3";
query3.groupID = 4;
const requestId2 = 46;
const params2 = packV3ValidatorParams(query3);

await verifier.setRequests([
{
requestId: requestId,
Expand All @@ -378,10 +387,10 @@ describe("Universal Verifier V3 validator", function () {
params: params,
},
{
requestId: requestId + 10,
requestId: requestId2,
metadata: "metadata",
validator: await v3Validator.getAddress(),
params: params,
params: params2,
},
]);

Expand Down Expand Up @@ -513,4 +522,41 @@ describe("Universal Verifier V3 validator", function () {
),
).to.be.rejectedWith("Generated proof is outdated");
});

it("Test set request fails with NullifierSessionID already exists", async () => {
const query2 = {
...query,
};
query2.groupID = 0;
query2.nullifierSessionID = "1";
const requestId = 38;
const params = packV3ValidatorParams(query2);
await verifier.setRequests([
{
requestId: requestId,
metadata: "metadata",
validator: await v3Validator.getAddress(),
params: params,
},
]);

const query3 = {
...query,
};
query3.groupID = 0;
query3.nullifierSessionID = "1";
const requestId2 = 39;
const params2 = packV3ValidatorParams(query3);

await expect(
verifier.setRequests([
{
requestId: requestId2,
metadata: "metadata",
validator: await v3Validator.getAddress(),
params: params2,
},
]),
).to.be.rejectedWith(`NullifierSessionIDAlreadyExists(${query2.nullifierSessionID})`);
});
});

0 comments on commit ffe4e6e

Please sign in to comment.