6.1 Zero-Knowledge Proofs for KYC (zk-KYC)

zk-KYC allows users to prove to the agreement: "I am a legitimate, unsanctioned, real user" without revealing "who I am".

6.1.1 Circuit Design for Identity Verification

Our ZK circuit (written based on Circom or Halo2) is designed to prove a specific arithmetic statement.

1. Certificate Issuance (Credential Issuance - Off-chain)

First, the user presents physical credentials on their local device to a trusted third-party issuer (such as Synaps or Binance). Once the issuer verifies the credentials, they digitally sign the user's decentralized identifier (DID) to generate a credential $C$.

C=SignIssuer(DIDuser,Attributes)C = \text{Sign}_{Issuer}(DID_{user}, \text{Attributes})

2. Circuit Statement

When a user wants to interact with OmniPact (e.g., to deposit a large sum of money), a Proof $\pi$ must be generated.

A zero-knowledge circuit $C_{kyc}$ contains the following constraints:

  • Inputs:

    • Private Inputs: User's private key ,certificate , the Merkle Path of the credentials.

    • Public Inputs: Issuer public key,Merkle Root on the compliance list ,Merkle Root on the sanctions list

Constraints:

  • Signature verification: Proves that $C$ is indeed a valid credential issued by $PK_{Issuer}$.

VerifySig(PKIssuer,C)==true\text{VerifySig}(PK_{Issuer}, C) == \text{true}
  • Proof of Ownership: Proof of user ownership of the credentials Bound private key

  • Membership: Proof that the credential exists in the valid user tree middle.

  • Non-Membership: Proof that the user is not on the OFAC sanctions list middle.

  • Attribute assertion: (Optional) Proof Attributes.Age >= 18Attributes.Country != "North Korea",However, the specific values ​​are not disclosed.

3. Output

Circuit output proof $\pi$. Smart contract verification.

Verify(π,PublicInputs)\text{Verify}(\pi, PublicInputs)

If true, the transaction is allowed. No user names or identification numbers are stored on the blockchain throughout the entire process.

6.1.2 Nullifier Implementation for Anonymity

While protecting privacy, we must prevent "identity double-spending," which means that the same compliant user can re-enter under a different alias after being banned, or the same user can claim "newcomer rewards" multiple times. To address this, we have introduced a nullifier mechanism.

1. Deterministic and irreversible identifiers

The nullifier is a hash value that is unique to the same user within the same scope, but it cannot be used to deduce the user's identity.

Nullifier calculation formula:

Nullifier=PoseidonHash(skuser,Scope,Salt)Nullifier = \text{PoseidonHash}(sk_{user}, \text{Scope}, \text{Salt})
  • :The user's secret private key (which is also the private input of the ZK circuit).

  • Scope: Scope parameter.

    • If it is a global ban list, the scope is PROTOCOL_ID

    • If it is a single voting activity, the scope is ELECTION_ID

  • PoseidonHash: A hash algorithm that is friendly to ZK circuits.

2. Mechanism

  1. Generation: Each time a user submits zk-KYC proof, the circuit will calculate as a byproduct NullifierNullifier And it is made public as Public Output.

  2. Record: Smart contracts maintain a mapping(bytes32 => bool) usedNullifiers

  3. Anti-replay:

    • If the goal is "limited to one per person", contract review usedNullifiers[Nullifier] Is it true.If so, then refuse.

    • If the purpose is "blacklist tracking," when a nullifier is marked as malicious by the OmniPact governance committee, that nullifier will be permanently added to the blacklistBlacklist

  4. Anonymity: due to Only the user knows that what an external observer sees is a string of random gibberish. Even if the user uses the OmniPact protocol in different DApps, the generated nullifier will be completely different as long as the scope is different, thus preventing cross-application linkability attacks.


circle-check

Last updated