Skip to main content

ZK Passport smart contracts reference

info

We're in process of migrating from legacy Circom circuits to Noir Ultra Plonk for passport verification during registration. Until the migration is complete, both are supported resulting in existence of ...Noir methods

A set of contracts facilitating self-issued anonymous identities based on the ZK Passport tech.

Currently, there are seven contract sections:

  1. State — main StateKeeper contract and a set of utility contracts. StateKeeper acts as a singleton state instance with which registration contracts interact. StateKeeper does the following:
    • Stores the Sparse Merkle Tree with registered identities;
    • Stores the Sparse Merkle Tree with registered certificates of ICAO members;
    • Stores and manages some passport and identity information;
    • Manages the "Passport <> Identity" bonds.
  2. Registration — primary section with Registration2 contract, that:
    • Allow users registration (with binding of their identity to the passport);
    • Allow revocation of passport-identity binding;
    • Allow re-issuance of previously revoked identity;
    • Allow registration and revocation of ICAO member's certificates (calls StateKeeper);
    • Call one of the verifier contracts, based on the provided passport type, to verify ZKP;
    • Manage different dispatchers.
  3. Verifiers — auto-generated contracts, the main purpose of which is to verify the ZKP.
  4. Dispatchers — acts as a bridge between registration contracts and:
    • authenticators corresponding to different passport types, if it is a passport dispatcher;
    • signers, if it is a certificate dispatcher.
  5. Signers — responsible for verifying the signature of the ICAO member's certificate. It also stores information required for signature verification (e.g. RSA exponent).
  6. Authenticators — perform the passport Active Authentication (AA).
  7. Utilities — some utility contracts, such as X509, SHA1, RSA implementations in solidity language and other.

Deployments

NameAddress
StateKeeper0x61aa5b68D811884dA4FEC2De4a7AA0464df166E1
RegistrationSMT0x479F84502Db545FA8d2275372E0582425204A879
CertificatesSMT0xA8b350d699632569D5351B20ffC1b31202AcEDD8
Registration20x11BB4B14AA6e4b836580F3DBBa741dD89423B971

Registration2

Interface

contract Registration2 is Initializable, TSSUpgradeable {

StateKeeper public stateKeeper;
mapping(bytes32 => address) public certificateDispatchers;
mapping(bytes32 => address) public passportDispatchers;
mapping(bytes32 => address) public passportVerifiers;

function registerCertificate(
Certificate memory certificate_,
ICAOMember memory icaoMember_,
bytes32[] memory icaoMerkleProof_
) external virtual {
/* ... */
}


function revokeCertificate(bytes32 certificateKey_) external virtual {
stateKeeper.removeCertificate(certificateKey_);
}


function register(
bytes32 certificatesRoot_,
uint256 identityKey_,
uint256 dgCommit_,
Passport memory passport_,
VerifierHelper.ProofPoints memory zkPoints_
) external virtual {
/* ... */
}

function registerViaNoir(
bytes32 certificatesRoot_,
uint256 identityKey_,
uint256 dgCommit_,
Passport memory passport_,
bytes memory zkPoints_
) external virtual {
/* ... */
}

function revoke(uint256 identityKey_, Passport memory passport_) external virtual {
/* ... */
}

function reissueIdentity(
bytes32 certificatesRoot_,
uint256 identityKey_,
uint256 dgCommit_,
Passport memory passport_,
VerifierHelper.ProofPoints memory zkPoints_
) external virtual {
/* ... */
}

function reissueIdentityViaNoir(
bytes32 certificatesRoot_,
uint256 identityKey_,
uint256 dgCommit_,
Passport memory passport_,
bytes memory zkPoints_
) external virtual {
/* ... */
}

function updateDependency(
MethodId methodId_,
bytes calldata data_,
bytes calldata proof_
) external virtual {
/* ... */
}

}
  • stateKeeper — instance of StateKeeper contract that saves all data about registrations, certificates, etc.;
  • certificateDispatchers — mapping from ICAO member's certificate to its dispatcher;
  • passportDispatchers — mapping from passport type to its dispatcher contract;
  • passportVerifiers — mapping from passport type to its verifier contract;
  • registerCertificate(...) — registers an ICAO member's X509 certificate in the certificates SMT (calls StateKeeper contract);
  • revokeCertificate(...) — revokes an expired ICAO member's X509 certificate (calls StateKeeper contract);
  • register(...) — registers the user (identity) by its passport, technically — issues the identity, calls the dispatcher to verify ZKP, links the identity to its passport by calling StateKeeper;
  • registerViaNoir(...) - the same as register(...) but uses Noir proof instead of Circom;
  • revoke(...) — revokes the identity and its passport by the user's will, marks the passport (and identity) as revoked;
  • reissueIdentity(...) — re-issues previous passport <> identity bond by migration to a new identity;
  • reissueIdentityViaNoir(...) — the same as reissueIdentity(...) but uses Noir proof instead of Circom;
  • updateDependency(...) — adds or removes, depending on the method provided, a dispatcher via Rarimo TSS;

For the full implementation, see Registration2.sol at the GitHub.

Verifiers

Interface

contract ExampleVerifier {

/* some constants */

function verifyProof(
uint[2] calldata _pA,
uint[2][2] calldata _pB,
uint[2] calldata _pC,
uint[4] calldata _pubSignals
) public view returns (bool) {
/* ... */
}
}

All verifiers are generated contracts that share the same interface. However, each verifier is designed to accept proofs generated by specific ZK schemas. Below is a list of the current verifiers:

  • Circom verifiers — the list of acceptable by Registration2 smart contracts to verify biometric passport;
  • Noir verifiers — the list of acceptable by Registration2 smart contracts to verify biometric passport;
  • PInternalOptVerifier2 — Georgian ID card verifier for Registration2;
  • PInternalVerifier2 — Georgian ID card verifier for Registration2;
  • PMNEOptVerifier2 — Montenegro ID card verifier for Registration2;
  • verifyProof(...) — verifies passport validity ZKP;

For the full implementation, see verifiers for Registration2 at the GitHub.

PECDSASHA1Dispatcher

Interface

contract PECDSASHA1Dispatcher is IPassportDispatcher, Initializable {

address public authenticator;

function authenticate(
bytes memory challenge_,
bytes memory passportSignature_,
bytes memory passportPublicKey_
) external view returns (bool) {
/* ... */
}

}
  • authenticator — address of the ECDSASHA1Authenticator contract for passports;
  • authenticate(...) — authenticates the ECDSASHA1 passport;

For the full implementation, see PECDSASHA1Dispatcher.sol at the GitHub.

PNOAADispatcher

Interface

contract PNOAADispatcher is IPassportDispatcher, Initializable {

function authenticate(
bytes memory,
bytes memory passportSignature_,
bytes memory passportPublicKey_
) external pure returns (bool) {
return passportSignature_.length == 0 && passportPublicKey_.length == 0;
}

}

This is a special dispatcher for passports without Active Authentication.

  • authenticate(...) — authenticates the passport without AA. Just return true;

For the full implementation, see PNOAADispatcher.sol at the GitHub.

PRSASHADispatcher

Interface

contract PRSASHADispatcher is IPassportDispatcher, Initializable {

address public authenticator;

function authenticate(
bytes memory challenge_,
bytes memory passportSignature_,
bytes memory passportPublicKey_
) external view returns (bool) {
return
PRSASHAAuthenticator(authenticator).authenticate(
challenge_,
passportSignature_,
passportPublicKey_
);
}

}
  • authenticator — address of the RSASHAAuthenticator contract for passports;
  • authenticate(...) — authenticates the RSASHA passport;

For the full implementation, see PRSASHADispatcher.sol at the GitHub.

CRSADispatcher

Interface

contract CRSADispatcher is ICertificateDispatcher, Initializable {

address public signer;

function verifyICAOSignature(
bytes memory x509SignedAttributes_,
bytes memory icaoMemberSignature_,
bytes memory icaoMemberKey_
) external view override returns (bool) {
return
ICertificateRSASigner(signer).verifyICAOSignature(
x509SignedAttributes_,
icaoMemberSignature_,
icaoMemberKey_
);
}

}

As for passports, there are authenticators for certificates, and it's one of them.

  • signer — address of the CRSASigner or CRSAPSSSigner contract for certificates;
  • verifyICAOSignature(...) — verifies RSA signature of ICAO member's certificate;

For the full implementation, see CRSADispatcher.sol at the GitHub.

CRSAPSSSigner

Interface

contract CRSAPSSSigner is ICertificateRSASigner, Initializable {
uint256 public exponent;
bool public isSha2;

function verifyICAOSignature(
bytes memory x509SignedAttributes_,
bytes memory icaoMemberSignature_,
bytes memory icaoMemberKey_
) external view override returns (bool) {
return
RSAPSS.verify(
x509SignedAttributes_,
icaoMemberSignature_,
abi.encodePacked(exponent),
icaoMemberKey_,
isSha2
);
}
  • exponent — RSAPSS exponent;
  • isSha2 — hash function switcher, true - sha2, false - sha512;
  • verifyICAOSignature(...) — verifies ICAO member RSAPSS signature of the X509 certificate SA;

For the full implementation, see CRSAPSSSigner.sol at the GitHub.

CRSASigner

Interface

contract CRSASigner is ICertificateRSASigner, Initializable {
uint256 public exponent; // RSA exponent
bool public isSha1; // hash function switcher, true - sha1, false - sha2

function verifyICAOSignature(
bytes memory x509SignedAttributes_,
bytes memory icaoMemberSignature_,
bytes memory icaoMemberKey_
) external view override returns (bool) {
/* ... */
}
}
  • exponent — RSA exponent;
  • isSha2 — hash function switcher, true - sha2, false - sha512;
  • verifyICAOSignature(...) — verifies ICAO member RSA signature of the X509 certificate SA.;

For the full implementation, see CRSASigner.sol at the GitHub.

PECDSASHA1Authenticator

Interface

contract PECDSASHA1Authenticator {

/* brainpool256r1 parameters */

function authenticate(
bytes memory challenge,
uint256 r,
uint256 s,
uint256 x,
uint256 y
) external pure returns (bool) {
/* ... */
}

}
  • authenticate(...) — checks active authentication of a passport (ECDSA signature);

For the full implementation, see PECDSASHA1Authenticator.sol at the GitHub.

PRSASHAAuthenticator

Interface

contract PRSASHAAuthenticator is Initializable {

uint256 public exponent; // RSA exponent

function authenticate(
bytes memory challenge_,
bytes memory s_,
bytes memory n_
) external view returns (bool) {
/* ... */
}
}
  • exponent — RSA exponent;
  • authenticate(...) — checks active authentication of a passport (RSA signature);

For the full implementation, see PRSASHAAuthenticator.sol at the GitHub.