Skip to main content

Proof of KYC

Introduction

Purpose

This document is a technical guide for implementing verifiable Proof of KYC (Know Your Customer), usable both on-chain by smart contracts and off-chain by APIs, relayers, and traditional services.

It outlines several methods for proving that a wallet, identifier, or credential holder has successfully completed a KYC process. Smart contract developers can consume the on-chain variants directly; backend developers, identity wallets, and compliance services can verify the same artifacts off-chain. Both consumers can build custom business logic on top of the verified identity data while preserving compliance and user privacy.

Overview

The Proof of KYC solution provides a privacy-preserving way to verify a user's KYC status without exposing the underlying identity attributes, neither on a public ledger nor to off-chain verifiers that don't need them.

Zyphe offers five distinct methods, each with different privacy properties, integration complexity, and verification surface:

MethodVerifiable on-chainVerifiable off-chain
KYC Soulbound Token issuance-
Signed KYC Mint Voucher
Ethereum Attestation Issuance
W3C Verifiable Credentials✓*
Zero-Knowledge Proofs derived from a Verifiable Credential
* W3C VCs are typically verified off-chain, but signed presentations can also be checked on-chain via verifier contracts.

Key Components

Verifiable Credentials (VCs)

Verifiable Credentials represent identity information issued by Zyphe after the KYC verification process. These credentials are cryptographically signed and attest that the user has undergone a KYC process. Each VC is associated with metadata, such as the issuer, date of issuance, and the type of verification performed (e.g., identity verification, proof of address, etc.).

Attestations

An attestation is a cryptographic statement that Zyphe has validated a user's identity. It can be persisted on-chain (as a smart-contract event or attestation registry entry) or held off-chain as a signed message, JWT, or JSON-LD document. In both cases, the verification surface is public while the underlying KYC data remains off-chain and minimized.

Cryptographic Signatures

Cryptographic signatures verify the integrity and authenticity of verifiable credentials and attestations. When Zyphe issues a credential, it signs it with its private key. Smart contracts can verify these signatures on-chain using the corresponding Zyphe public key (registered in an issuer registry), and off-chain verifiers (backends, wallets, relayers) can do the same with standard cryptographic libraries. Only artifacts from trusted issuers are accepted.

KYC Tokens

To ensure easy interaction with decentralized applications (dApps) and marketplaces, users who pass the KYC process can be issued a non-transferable token (e.g., a soulbound token). This token acts as a proof-of-KYC that is stored on the blockchain. While the token itself does not reveal any sensitive details, dApps can verify its existence to ensure the user has been KYC-verified by Zyphe.

Smart Contracts

For on-chain consumption, the Proof of KYC solution is backed by smart contracts that validate signatures, attestations, and zk-proofs. These contracts define the logic for:

  • Issuing attestations or soulbound tokens upon verification.
  • Validating cryptographic proofs when requested by another contract or a dApp.
  • Managing the lifecycle of issued credentials, including issuance and revocation.

Off-chain integrations replace these contracts with equivalent verifier libraries running inside backends, wallets, or compliance services, using the same issuer keys and revocation state.

Signed KYC Mint Voucher

It’s a cryptographically signed message that a protocol can utilize within its smart contract. It provides smart contract developers with full flexibility to implement custom business logic on their side, such as issuing tokens, adding wallet addresses to a whitelist, or other actions based on the KYC verification.

KYC Soulbound Token issuance

In the KYC Soulbound Token Issuance solution, the user first connects and authenticates their wallet. Upon successful completion of the KYC process, our backend service issues a non-transferable Soulbound Token directly to the authenticated wallet. This token acts as an immutable on-chain representation that the KYC process has been completed, allowing decentralized applications (dApps) to verify the user’s KYC status without exposing any sensitive information.

Flow

KYC Soulbound Token issuanceSigned KYC Mint Voucher

In the Signed KYC Mint Voucher solution, the user first connects and authenticates their wallet. After successfully completing the KYC process, our backend service generates and signs a message that attests to the completion of the KYC. This signed message, similar to a JWT but using EVM-compatible data types, can be consumed by a smart contract on-chain. This approach provides developers with the flexibility to implement their own business logic, such as issuing tokens, whitelisting addresses, or other custom workflows.

Zero-Knowledge Proofs from a Verifiable Credential

In the zk-Proof from VC solution, Zyphe issues a W3C Verifiable Credential signed under a ZKP-friendly scheme (BBS+ over BLS12-381, or CL signatures for AnonCreds-style flows). The holder then derives a zero-knowledge proof that attests to specific predicates over the credential, without revealing the underlying attributes, the credential identifier, or the issuer signature itself.

The same proof artifact is verifiable both on-chain and off-chain under identical cryptographic guarantees. This makes it the most flexible primitive in the Zyphe stack: a single VC can serve a Solidity verifier contract on an EVM L1, an aggregator inside an ERC-4337 paymaster, and an off-chain compliance API, with no re-issuance and no PII leakage.

Flow

The lifecycle splits into two phases: issuance of the VC after KYC (one-time, off-chain), and presentation of a derived zk-proof against a verifier (per-request, on- or off-chain).

Cryptographic primitives

  • Issuer signature: BBS+ over BLS12-381. Multi-message signatures allow the holder to selectively disclose or blind individual credential attributes.
  • Proof system: Groth16, PLONK, or STARK circuits encode (a) the BBS verification relation, (b) the requested predicates (range proofs, set membership / non-membership, hash equality), and (c) holder binding.
  • Holder binding: a link_secret bound at issuance is committed inside every proof and signed against the wallet challenge, preventing credential pooling, rental, or transfer.
  • Nullifiers: a deterministic nullifier = H(link_secret, contextId) is published with each proof. Verifiers track nullifiers per-context to prevent replay while preserving cross-context unlinkability.
  • Revocation: handled out-of-band via BitstringStatusList (W3C) or a Merkle / RSA accumulator, with the current root mirrored on-chain for trustless checks.

What can be proved

The same VC satisfies many predicates without re-issuance:

  • kyc_level >= L2: KYC tier threshold
  • age >= 18 (or any threshold): range proof over date-of-birth
  • country ∈ allowlist / country ∉ sanctioned_set: set membership / non-membership
  • risk_score < threshold: numeric bound when AML scoring is bound into the credential
  • wallet == msg.sender: binding the proof to the calling EOA / smart account
  • issuer == zyphe_did ∧ not_expired(now): issuance authority and validity window

On-chain verification

A verifier contract is generated from the circuit and consumes a calldata-friendly proof. A typical EVM entrypoint:

function verifyKyc(
uint256[8] calldata proof,
uint256[] calldata publicInputs, // [issuerKeyId, predicateHash, nullifier, contextId, expiry]
bytes32 nullifier
) external returns (bool);

The contract enforces:

  1. Verifier.verify(proof, publicInputs) == true
  2. publicInputs.issuerKeyId is registered in the on-chain IssuerRegistry
  3. publicInputs.expiry > block.timestamp
  4. usedNullifiers[contextId][nullifier] == false, then marks it used
  5. (Optional) credential is unrevoked against the mirrored revocation root

Gas cost is dominated by the pairing check: roughly 230k gas for a Groth16 verifier on BN254 via the ecPairing precompile (EIP-197), and single-digit-millisecond verification off-chain.

Off-chain verification

The same proof verifies under snarkjs, arkworks, rapidsnark, or risc0, enabling hybrid flows:

  • Rollups / L2: cheap on-chain verification, or batched verification at the sequencer.
  • Account abstraction (ERC-4337): validate the proof inside validateUserOp (paymaster or signature aggregator) to gate UserOps without leaking PII.
  • Off-chain APIs: a backend issues a session token after verifying the proof, with no need to ever hold the underlying VC.

Privacy and threat model

  • Zero-knowledge: only the predicate result and the declared public inputs are revealed; no attribute, signature, or credential identifier leaks.
  • Unlinkability: across distinct contextId values, two presentations of the same VC cannot be correlated by the verifier(s).
  • Per-context Sybil resistance: nullifiers prevent reuse within a context while preserving anonymity across contexts.
  • Issuer compromise: a leaked issuer key enables forgery of new credentials going forward, but does not retroactively deanonymize existing presentations. Keys are rotated via the IssuerRegistry.
  • Trusted setup: Groth16 requires a per-circuit ceremony; PLONK requires a universal setup; STARKs are transparent. Zyphe favors universal or transparent setups to avoid per-circuit ceremonies.

AML compliance proof

AML (Anti-Money Laundering) frameworks function fundamentally as a blacklist: they identify and restrict users or entities associated with high-risk activities. This contrasts with KYC, which confirms an individual's identity but does not assess their transactional history or risk indicators. A user who has successfully completed KYC verification may still be flagged on AML lists if linked to suspicious activities. KYC proves that an individual is known and verified; AML provides a separate compliance layer focused on monitoring and preventing illicit activity, even for KYC-verified users.

  • AML Screening (off-chain)
    The compliance process begins off-chain, where a user's wallet address (and, where applicable, identity attributes) is checked against up-to-date AML lists maintained by trusted providers. These lists flag addresses associated with money laundering, fraud, or sanctions. If the address is clear, a cryptographic attestation is created to certify that the wallet has passed AML checks.
  • Issuing an AML compliance proof
    Once the wallet passes screening, Zyphe issues a cryptographic attestation stating that the address is not blacklisted. This attestation can take the form of a signed message, a JWT, a W3C VC, or a token with an AML status attribute, any of which can be consumed by on-chain or off-chain verifiers.
  • On-chain verification
    The attestation can be persisted on-chain as a smart-contract event or registry entry. Other contracts check its validity without needing access to the full AML database. It acts as a public "AML passport" while the underlying screening data stays private.
  • Off-chain verification
    The same attestation is verifiable off-chain by APIs, custodians, exchanges, or compliance backends using standard signature-verification libraries against Zyphe's published issuer keys.
  • Access control
    When a user interacts with a dApp or service, the verifier checks the attestation's signature against the trusted AML issuer registry. Based on this proof, the verifier can permit or deny access, apply transaction limits, or trigger additional compliance measures.

More coming soon…