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
| Contract | Address |
|---|---|
DIDRegistry | 0xC68ceB726DDB898E899080021A0B9e7994f63A73 |
Groth16Verifier | 0x58258bf549D8E8694b22B12410F24583D16e1aA4 |
On-chain verification is available on Starter plans and above.
DIDRegistry
Purpose:
- store
SHA-256(biometricTemplate)as abytes32key, - map that key to a DID string,
- support registration lookup and revocation,
- keep ownership on the contract writer side.
Important functions
| Function | Purpose |
|---|---|
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:
| Function | Purpose |
|---|---|
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:
Poseidon(biometricSecret, salt) == commitmentPoseidon(biometricSecret, didHash) == identityBinding
Inputs
| Visibility | Name | Meaning |
|---|---|---|
| Private | biometricSecret | Secret derived from the hashed biometric and salt. |
| Private | salt | Random value created during registration. |
| Public | commitment | Poseidon commitment binding the secret to the registration event. |
| Public | didHash | Poseidon-compatible DID hash. |
| Public | identityBinding | Poseidon 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 WebAssemblycircuit_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
bytes32value, - 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.circomcircuit_final.zkeyverification_key.jsonVerifier.sol- deployed verifier contract address
If any one of them changes, rebuild and redeploy the full chain of dependent artifacts.