Skip to main content

Contracts and Circuit

ZeroAuth's cryptographic and blockchain layer is built from one Circom circuit and two Solidity contracts deployed on Base Sepolia L2.

Base Sepolia Deployment

ContractAddress
DIDRegistry0xC68ceB726DDB898E899080021A0B9e7994f63A73
Groth16Verifier0x58258bf549D8E8694b22B12410F24583D16e1aA4

On-chain verification is available on Starter plans and above.

DIDRegistry

Purpose:

  • store SHA-256(biometricTemplate) as a bytes32 key,
  • map that key to a DID string,
  • support registration lookup and revocation,
  • keep ownership on the contract writer side.

Important functions

FunctionPurpose
registerIdentity(bytes32 biometricIDHash, string did)Stores a new biometric hash to DID mapping.
verifyIdentity(bytes32 biometricIDHash)Returns the DID for a registered biometric hash.
isRegistered(bytes32 biometricIDHash)Checks whether a mapping exists.
revokeIdentity(bytes32 biometricIDHash)Removes a mapping.
identityCount()Returns total active identities.
transferOwnership(address newOwner)Transfers contract ownership.

Access model

  • writes require onlyOwner
  • reads are public

Stored data

  • bytes32 biometricIDHash — irreversible SHA-256 hash (not raw biometric data)
  • string did — decentralized identifier
  • registration status flag
  • identity counter

Groth16Verifier

Purpose:

  • verify the Groth16 proof tuple against three public signals on chain.

This contract is generated by snarkjs from the circuit and proving setup.

Primary function:

FunctionPurpose
verifyProof(uint[2] _pA, uint[2][2] _pB, uint[2] _pC, uint[3] _pubSignals)Returns true when the proof is valid.

Circom Circuit

The circuit proves knowledge of a biometricSecret and salt such that:

  1. Poseidon(biometricSecret, salt) == commitment
  2. Poseidon(biometricSecret, didHash) == identityBinding

Inputs

VisibilityNameMeaning
PrivatebiometricSecretSecret derived from the hashed biometric and salt.
PrivatesaltRandom value created during registration.
PubliccommitmentPoseidon commitment binding the secret to the registration event.
PublicdidHashPoseidon-compatible DID hash.
PublicidentityBindingPoseidon binding proving the secret is tied to the DID hash.

Client-Side Proof Generation

The circuit artifacts needed for client-side proof generation:

  • identity_proof.wasm — circuit compiled to WebAssembly
  • circuit_final.zkey — proving key

Fetch circuit metadata from the API:

curl https://zeroauth.dev/v1/auth/zkp/circuit-info \
-H "Authorization: Bearer za_live_YOUR_KEY"

See ZKP Biometric Authentication for the full client-side integration guide.

How ZeroAuth Uses These On-Chain

During registration

The API:

  • computes SHA-256(biometricTemplate),
  • converts it to a bytes32 value,
  • calls DIDRegistry.registerIdentity(...),
  • returns the resulting transaction hash and block number.

During proof verification

The API:

  • verifies the proof off-chain first using snarkjs,
  • optionally calls Groth16Verifier.verifyProof(...) for on-chain verification.

Versioning Guidance

Keep these artifacts aligned:

  • identity_proof.circom
  • circuit_final.zkey
  • verification_key.json
  • Verifier.sol
  • deployed verifier contract address

If any one of them changes, rebuild and redeploy the full chain of dependent artifacts.