Connection & deployment

Not connected - disconnected
Connected account-
Network-
Chain ID-
Balance-
IdentityRegistryNot deployed
RevocationRegistryNot deployed
LightweightVerifierNot deployed
Last tx-

Simulate Deploy works without a wallet, using purely in-memory chain state. Deploy (Live) requires MetaMask and uses your selected network & account; transactions are broadcast through your wallet (state still tracked in-memory since the contracts aren't pre-deployed).

Issuer

A regulated authority (a bank, a regulator, a government registrar) issues digital credentials with a post-quantum key. The issuer's identity and the credential's revocation status are anchored on a public trust registry, so any verifier worldwide can confirm both without contacting the issuer's database or moving holder data across borders.

Step 1 · Generate keys & register DID

Cryptographic key pairs

Two post-quantum key pairs: ML-DSA-65 for signing credentials, ML-KEM-768 for the encrypted PII handoff scenario.

Issuer DID-
ML-DSA keygen-
ML-KEM keygen-
Technical details
ML-DSA-65 pk- bytes
ML-DSA-65 sk- bytes
Signature size3,309 bytes
ML-KEM-768 pk- bytes
ML-KEM-768 sk- bytes
KEM ciphertext1,088 bytes
Generate to begin
-
-
-

Register DID on-chain

Anchors the issuer's public keys to a verifiable chain of authority. Subsequent credentials issued under this DID can be verified against these on-chain keys.

StatusNot submitted
Tx hash-
Technical details
FunctionregisterIssuer(string,bytes,bytes)
Selector-
Calldata size-
Gas estimate~310,000 gas
Generate keys to preview calldata
-

Step 2 · Issue Fatima's credential & anchor root

Sign credential & build Merkle tree

The issuer constructs a credential header containing all of Fatima's claims, builds a Merkle tree of the claim leaves, signs the resulting root with ML-DSA-65.

Credential ID-
Sign time-
Technical details
Tree leaves-
Merkle root preview-
Signature size-
-
-

Each leaf: RPO256(key) ‖ RPO256(value). Tree padded to next power of 2 with domain-separated empty leaves.

Anchor Merkle root on-chain

Publishes the current Merkle root with a timestamp. Verifiers check this is the issuer's latest authoritative root (revocation-aware).

StatusNot anchored
Technical details
FunctionupdateRoot(string,bytes32)
Selector-
Gas estimate~62,000 gas
Tx hash-
Gas used-
Block-
Epoch-

Holder

Fatima Al-Hassan controls her credential and decides what to disclose. She can prove specific claims to a verifier without revealing the others; undisclosed values stay private even from the verifier.

Selective disclosure

Choose claims to share

Fatima's credential contains 7 claims. Click each to toggle disclosure - hidden claims stay private, only Merkle paths are revealed.

No claims selected

Build presentation

For each disclosed claim, generate a Merkle inclusion proof against the issuer-signed root. Send proofs + signature to the verifier.

Presentation size-
Build time-
Proof generation log

For most regulated identity flows (mDL, EUDIW, this demo), Merkle-inclusion selective disclosure of issuer-signed leaves is the production approach. ZK predicate proofs ("DOB < 2007-01-01" without revealing DOB) are on the roadmap - see How does it work?

Verifier

The verifier can be another person checking a counterparty's credential in person, a DeFi protocol gating a regulated pool, a centralised exchange running KYC at onboarding, a bank validating a wire counterparty, or any other regulated venue, anywhere in the world. The cryptographic check is the same in every case: validate the issuer's ML-DSA signature, walk the Merkle inclusion proofs for each disclosed claim, read the on-chain trust + revocation state, then grant or deny in milliseconds.

Verify presentation

End-to-end verification pipeline

Three checks run in sequence: ML-DSA signature on the credential header, Merkle inclusion proof for each disclosed leaf, on-chain reads for issuer registration and revocation status. Composite outcome determines access.

Show individual sub-checks

1. ML-DSA-65 signature

Opml_dsa65.verify
Library@noble/post-quantum
Verify time-
Run pipeline first

2. Merkle inclusion

OpverifyMerklePath × N
HashRPO-256
Proof depth-
Run pipeline first

3. On-chain checks

Opeth_call × 3
Gas0 (read-only)
FunctionsisRegistered · isRevoked · currentRoot
Run pipeline first

Tamper test

The verifier rejects corrupted presentations

If the signature, a leaf, or the Merkle root is modified - even by a single bit between Fatima sending and the verifier checking - the verification fails. This is real cryptography, not animation.

Choose specific tamper

After tampering, click Verify Presentation above to see the rejection.

Secondary flows

Issuer admin (revocation) and full-KYC scenarios (encrypted PII handoff for cases where selective disclosure isn't sufficient under regulation).

Issuer admin · revocation

Revoke credential

Only the registered issuer of a DID can revoke its credentials - enforced on-chain by the onlyIssuer(did) modifier. A non-issuer transaction reverts. The revocation registry maintains an append-only epoch log for audit.

Issuer DID-
Credential ID-
StatusACTIVE
Technical details
Functionrevoke(string,bytes32)
Selector-
ModifieronlyIssuer(did)
EffectAll future isRevoked() return true
Gas estimate~32,000 gas
Tx hash-
Gas used-
Status-

Transaction history

Connect MetaMask or Simulate Deploy to see transactions...

Encrypted PII handoff

Where regulation requires full PII to reach the verifier (for example, sophisticated-investor onboarding at a regulated fund) and selective disclosure isn't sufficient: the holder encapsulates a quantum-safe shared secret to the verifier's ML-KEM-768 public key, then encrypts the PII payload with AES-256-GCM. The wire is protected against a future "harvest now, decrypt later" adversary.

1 · Verifier's KEM keypair

The verifier publishes an ML-KEM-768 public key. Holders encrypt PII to this key.

Keygen time-
Technical details
AlgorithmML-KEM-768 / FIPS 203
pk size1,184 bytes
sk size2,400 bytes
-

2 · Holder encapsulates & encrypts

Holder runs (ct, k) ← Encap(pk_v), then encrypts PII with k as AES-256-GCM key.

Encap + AES-GCM-
PII size-
Technical details
KEM ciphertext1,088 bytes
Shared secret32 bytes (AES-256 key)
-

3 · Verifier decrypts

Verifier runs k ← Decap(sk_v, ct), decrypts PII with AES-256-GCM, runs KYC.

Decap + AES-GCM-
Result-
Decrypted payload & tamper test
-

Tampering the ciphertext fails AES-GCM authentication; the verifier rejects the payload.