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://api.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.