Skip to content

Commit

Permalink
compiled
Browse files Browse the repository at this point in the history
  • Loading branch information
motemotech committed Jan 29, 2025
1 parent a0fa5e2 commit 0fec7dc
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 84 deletions.
76 changes: 44 additions & 32 deletions contracts/contracts/IdentityVerificationHubImplV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ contract IdentityVerificationHubImplV1 is
IdentityVerificationHubStorageV1,
IIdentityVerificationHubV1
{
using Formatter for uint256;

uint256 constant MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH = 10;

// Events
event HubInitialized(
address registry,
Expand Down Expand Up @@ -82,7 +86,7 @@ contract IdentityVerificationHubImplV1 is
error INVALID_DSC_PROOF();
error INVALID_VC_AND_DISCLOSE_PROOF();

error INVALID_IDENTITY_COMMITMENT_ROOT();
error INVALID_COMMITMENT_ROOT();
error INVALID_OFAC_ROOT();
error INVALID_CSCA_ROOT();

Expand Down Expand Up @@ -213,10 +217,20 @@ contract IdentityVerificationHubImplV1 is
return attrs;
}

function getReadableForbiddenCountries(
uint256 forbiddenCountriesListPacked
)
external
view
returns (bytes3[MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH] memory)
{
return Formatter.extractForbiddenCountriesFromPacked(forbiddenCountriesListPacked);
}

// verify and view

function verifyVcAndDisclose(
IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory proof
VcAndDiscloseHubProof memory proof
)
external
view
Expand All @@ -227,13 +241,13 @@ contract IdentityVerificationHubImplV1 is

VcAndDiscloseVerificationResult memory result;
for (uint256 i = 0; i < 3; i++) {
result.revealedDataPacked[i] = proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_REVEALED_DATA_PACKED_INDEX + i];
result.revealedDataPacked[i] = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_REVEALED_DATA_PACKED_INDEX + i];
}
result.forbiddenCountriesListPacked = proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_FORBIDDEN_COUNTRIES_LIST_PACKED_INDEX];
result.nullifier = proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_NULLIFIER_INDEX];
result.attestationId = proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_ATTESTATION_ID_INDEX];
result.userIdentifier = proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_USER_IDENTIFIER_INDEX];
result.scope = proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_SCOPE_INDEX];
result.forbiddenCountriesListPacked = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_FORBIDDEN_COUNTRIES_LIST_PACKED_INDEX];
result.nullifier = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_NULLIFIER_INDEX];
result.attestationId = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_ATTESTATION_ID_INDEX];
result.userIdentifier = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_USER_IDENTIFIER_INDEX];
result.scope = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_SCOPE_INDEX];
return result;
}

Expand Down Expand Up @@ -353,27 +367,25 @@ contract IdentityVerificationHubImplV1 is

// Functions for vc and disclose circuit
function verifyVcAndDiscloseProof(
bool checkOlderThan,
uint256 expectedOlderThan,
bool checkOfac,
bool checkForbiddenCountries,
uint256 expectedForbiddenCountriesListPacked,
IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory proof
VcAndDiscloseHubProof memory proof
)
internal
view
{
if (!IIdentityRegistryV1(_registry).checkIdentityCommitmentRoot(proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_MERKLE_ROOT_INDEX])) {
revert INVALID_IDENTITY_COMMITMENT_ROOT();
// verify identity commitment root
if (!IIdentityRegistryV1(_registry).checkIdentityCommitmentRoot(proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_MERKLE_ROOT_INDEX])) {
revert INVALID_COMMITMENT_ROOT();
}

if (!IIdentityRegistryV1(_registry).checkOfacRoot(proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_SMT_ROOT_INDEX])) {
// verify ofac root
if (!IIdentityRegistryV1(_registry).checkOfacRoot(proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_SMT_ROOT_INDEX])) {
revert INVALID_OFAC_ROOT();
}

// verify current date
uint[6] memory dateNum;
for (uint256 i = 0; i < 6; i++) {
dateNum[i] = proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_CURRENT_DATE_INDEX + i];
dateNum[i] = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_CURRENT_DATE_INDEX + i];
}
uint currentTimestamp = Formatter.proofDateToUnixTimestamp(dateNum);
if(
Expand All @@ -383,33 +395,29 @@ contract IdentityVerificationHubImplV1 is
revert CURRENT_DATE_NOT_IN_VALID_RANGE();
}

// verify attributes
uint256[3] memory revealedDataPacked;
for (uint256 i = 0; i < 3; i++) {
revealedDataPacked[i] = proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_REVEALED_DATA_PACKED_INDEX + i];
revealedDataPacked[i] = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_REVEALED_DATA_PACKED_INDEX + i];
}

if (checkOlderThan) {
uint256 olderThanInProof = CircuitAttributeHandler.getOlderThan(Formatter.fieldElementsToBytes(revealedDataPacked));
if (olderThanInProof != expectedOlderThan) {
if (proof.olderThanEnabled) {
if (!CircuitAttributeHandler.compareOlderThan(Formatter.fieldElementsToBytes(revealedDataPacked), proof.olderThan)) {
revert INVALID_OLDER_THAN();
}
}

if (checkOfac) {
uint256 ofacInProof = CircuitAttributeHandler.getOfac(Formatter.fieldElementsToBytes(proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_REVEALED_DATA_PACKED_INDEX]));
if (ofacInProof != 1) {
if (proof.ofacEnabled) {
if (!CircuitAttributeHandler.compareOfac(Formatter.fieldElementsToBytes(revealedDataPacked))) {
revert INVALID_OFAC();
}
}

if (checkForbiddenCountries) {
uint256 forbiddenCountriesListPackedInProof = proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_FORBIDDEN_COUNTRIES_LIST_PACKED_INDEX];
if (forbiddenCountriesListPackedInProof != expectedForbiddenCountriesListPacked) {
if (proof.forbiddenCountriesEnabled) {
if (proof.forbiddenCountriesListPacked != proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_FORBIDDEN_COUNTRIES_LIST_PACKED_INDEX]) {
revert INVALID_FORBIDDEN_COUNTRIES();
}
}

if (!IVcAndDiscloseCircuitVerifier(_vcAndDiscloseCircuitVerifier).verifyProof(proof.a, proof.b, proof.c, proof.pubSignals)) {
// verify the proof
if (!IVcAndDiscloseCircuitVerifier(_vcAndDiscloseCircuitVerifier).verifyProof(proof.vcAndDiscloseProof.a, proof.vcAndDiscloseProof.b, proof.vcAndDiscloseProof.c, proof.vcAndDiscloseProof.pubSignals)) {
revert INVALID_VC_AND_DISCLOSE_PROOF();
}
}
Expand All @@ -428,6 +436,10 @@ contract IdentityVerificationHubImplV1 is
revert NO_VERIFIER_SET();
}

if (!IIdentityRegistryV1(_registry).checkIdentityCommitmentRoot(registerCircuitProof.pubSignals[CircuitConstants.REGISTER_MERKLE_ROOT_INDEX])) {
revert INVALID_COMMITMENT_ROOT();
}

result = IRegisterCircuitVerifier(verifier).verifyProof(
registerCircuitProof.a,
registerCircuitProof.b,
Expand Down
9 changes: 4 additions & 5 deletions contracts/contracts/abstract/passportAirdropRoot.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity ^0.8.28;

import {IIdentityVerificationHubV1} from "../interfaces/IIdentityVerificationHubV1.sol";
import {IVcAndDiscloseCircuitVerifier} from "../interfaces/IVcAndDiscloseCircuitVerifier.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {CircuitConstants} from "../constants/CircuitConstants.sol";

Expand Down Expand Up @@ -36,7 +35,7 @@ abstract contract PassportAirdropRoot is Ownable {

function _registerAddress(
address addressToRegister,
IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory proof
IIdentityVerificationHubV1.VcAndDiscloseHubProof memory proof
)
internal
returns (address registeredAddress)
Expand All @@ -45,15 +44,15 @@ abstract contract PassportAirdropRoot is Ownable {
revert RegistrationNotOpen();
}

if (scope != proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_SCOPE_INDEX]) {
if (scope != proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_SCOPE_INDEX]) {
revert InvalidScope();
}

if (nullifiers[proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_NULLIFIER_INDEX]] != address(0)) {
if (nullifiers[proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_NULLIFIER_INDEX]] != address(0)) {
revert AlreadyRegistered();
}

if(attestationId != proof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_ATTESTATION_ID_INDEX]) {
if(attestationId != proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_ATTESTATION_ID_INDEX]) {
revert InvalidAttestationId();
}

Expand Down
1 change: 1 addition & 0 deletions contracts/contracts/constants/CircuitConstants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.28;
library CircuitConstants {
uint256 constant REGISTER_NULLIFIER_INDEX = 0;
uint256 constant REGISTER_COMMITMENT_INDEX = 1;
uint256 constant REGISTER_MERKLE_ROOT_INDEX = 2;

uint256 constant DSC_TREE_LEAF_INDEX = 0;
uint256 constant DSC_CSCA_ROOT_INDEX = 1;
Expand Down
4 changes: 2 additions & 2 deletions contracts/contracts/example/airdrop.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.28;

import {IERC20, SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import {PassportAirdropRoot} from "../abstract/airdropRoot.sol";
import {PassportAirdropRoot} from "../abstract/passportAirdropRoot.sol";
import {IIdentityVerificationHubV1} from "../interfaces/IIdentityVerificationHubV1.sol";
import {IVcAndDiscloseCircuitVerifier} from "../interfaces/IVcAndDiscloseCircuitVerifier.sol";

Expand Down Expand Up @@ -47,7 +47,7 @@ contract Airdrop is PassportAirdropRoot {
}

function registeredAddress(
IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory proof
IIdentityVerificationHubV1.VcAndDiscloseHubProof memory proof
)
external
{
Expand Down
2 changes: 2 additions & 0 deletions contracts/contracts/interfaces/IIdentityRegistryV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ interface IIdentityRegistryV1 {
function getIdentityCommitmentMerkleTreeSize() external view returns (uint256);
function getIdentityCommitmentMerkleRoot() external view returns (uint256);
function getIdentityCommitmentIndex(uint256 commitment) external view returns (uint256);
function getDscKeyCommitmentTreeRoot() external view returns (uint256);
function checkDscKeyCommitmentTreeRoot(uint256 root) external view returns (bool);
function getOfacRoot() external view returns (uint256);
function getCscaRoot() external view returns (uint256);
function checkOfacRoot(uint256 root) external view returns (bool);
Expand Down
12 changes: 11 additions & 1 deletion contracts/contracts/interfaces/IIdentityVerificationHubV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,18 @@ interface IIdentityVerificationHubV1 {
uint256 ofac;
}


struct VcAndDiscloseHubProof {
bool olderThanEnabled;
uint256 olderThan;
bool forbiddenCountriesEnabled;
uint256 forbiddenCountriesListPacked;
bool ofacEnabled;
IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof vcAndDiscloseProof;
}

function verifyVcAndDisclose(
IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof memory proof
VcAndDiscloseHubProof memory proof
)
external
view
Expand Down
21 changes: 5 additions & 16 deletions contracts/contracts/libraries/CircuitAttributeHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,25 @@ library CircuitAttributeHandler {
}

function getOlderThan(bytes memory charcodes) internal pure returns (uint256) {
return extractOlderThan(charcodes);
return Formatter.numAsciiToUint(uint8(charcodes[OLDER_THAN_START]))*10
+ Formatter.numAsciiToUint(uint8(charcodes[OLDER_THAN_START + 1]));
}

function getOfac(bytes memory charcodes) internal pure returns (uint256) {
return extractOfac(charcodes);
return uint8(charcodes[OFAC_START]);
}

function compareOlderThan(
bytes memory charcodes,
uint256 olderThan
) internal pure returns (bool) {
return extractOlderThan(charcodes) >= olderThan;
return getOlderThan(charcodes) >= olderThan;
}

function compareOfac(
bytes memory charcodes
) internal pure returns (bool) {
return extractOfac(charcodes) == 1;
return getOfac(charcodes) == 1;
}

function extractStringAttribute(bytes memory charcodes, uint256 start, uint256 end) internal pure returns (string memory) {
Expand All @@ -97,16 +98,4 @@ library CircuitAttributeHandler {
return string(attributeBytes);
}

function extractOlderThan(
bytes memory charcodes
) internal pure returns (uint256) {
return Formatter.numAsciiToUint(uint8(charcodes[OLDER_THAN_START]))*10
+ Formatter.numAsciiToUint(uint8(charcodes[OLDER_THAN_START + 1]));
}

function extractOfac(
bytes memory charcodes
) internal pure returns (uint256) {
return uint8(charcodes[OFAC_START]);
}
}
34 changes: 6 additions & 28 deletions contracts/contracts/libraries/Formatter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ library Formatter {
error InvalidDateLength();
error InvalidAsciiCode();

uint256 constant MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH = 20;
uint256 constant MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH = 10;

function formatName(
string memory input
Expand Down Expand Up @@ -86,7 +86,7 @@ library Formatter {
}

function extractForbiddenCountriesFromPacked(
uint256[2] memory publicSignals
uint256 publicSignal
)
internal
pure
Expand All @@ -98,32 +98,10 @@ library Formatter {
for (uint256 j = 0; j < MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH; j++) {
uint256 byteIndex = j * 3;

if (byteIndex + 2 < 32) {
uint256 shift = byteIndex * 8;
uint256 mask = 0xFFFFFF;
uint256 packedData = (publicSignals[0] >> shift) & mask;
forbiddenCountries[j] = bytes3(uint24(packedData));
} else if (byteIndex < 32) {
uint256 bytesFrom0 = 32 - byteIndex;
uint256 bytesTo1 = 3 - bytesFrom0;

uint256 shift0 = byteIndex * 8;
uint256 mask0 = (1 << (bytesFrom0 * 8)) - 1;
uint256 part0 = (publicSignals[0] >> shift0) & mask0;

uint256 shift1 = 0;
uint256 mask1 = (1 << (bytesTo1 * 8)) - 1;
uint256 part1 = (publicSignals[1] >> shift1) & mask1;

uint256 combined = (part1 << (bytesFrom0 * 8)) | part0;
forbiddenCountries[j] = bytes3(uint24(combined));
} else {
uint256 byteIndexIn1 = byteIndex - 32;
uint256 shift = byteIndexIn1 * 8;
uint256 mask = 0xFFFFFF;
uint256 packedData = (publicSignals[1] >> shift) & mask;
forbiddenCountries[j] = bytes3(uint24(packedData));
}
uint256 shift = byteIndex * 8;
uint256 mask = 0xFFFFFF;
uint256 packedData = (publicSignal >> shift) & mask;
forbiddenCountries[j] = bytes3(uint24(packedData));
}

return forbiddenCountries;
Expand Down

0 comments on commit 0fec7dc

Please sign in to comment.