The registration flow is staged for reliability: selfie and liveness first, then ID capture, local verification, proof generation, and finally registration with the backend.
Registration Steps
- Selfie and face presence: The front camera captures a selfie and ML Kit confirms a face is present with sufficient confidence.
- Active liveness challenges: Two random challenges are selected from a pool of four (blink, nod up, nod down, smile). Each is captured after a three-second countdown. ML Kit evaluates eye-openness, head Euler angles, and smile probability against threshold values.
- ID capture and OCR: The back camera captures the HKID card. OCR extracts the HKID number, name, and date of birth locally on the device.
- HKID validation: The on-device parser validates the HKID structure and mod-11 checksum before any proving takes place.
- Face matching: Geometric landmark similarity compares the registration selfie to the ID card photograph.
- Anti-spoofing analysis: A six-layer pipeline (MRZ cross-validation, Moire pattern detection, paper printout detection, hologram analysis, AI-generated fake detection, and edge sharpness analysis) produces an advisory recommendation of accept, review, or reject.
- ZK proof generation: Three Circom circuits (HKID, Age, Liveness) generate independent Groth16 proofs via a hidden WebView bridge running snarkjs.
- Backend registration: The proof payload (commitments, public signals, and metadata) is submitted to the backend. Commitments are stored on the private chain and batched for public anchoring.
What does the ZK proof proves?
| Proven Claim | Not Revealed |
|---|---|
| HKID checksum and structural validity | Full HKID number in plaintext |
| Age is at or above threshold (e.g. 18+) | Exact date of birth |
| Liveness score thresholds satisfied | Raw facial data and challenge video frames |
| Commitment exists in registered state | Any identity preimage data |
Subsequent Website Authentication
When a user visits a website that integrates the zKYC API, they scan a QR code (or tap a link on mobile) to open the app. The app prompts for facial verification via the device’s biometric authentication (Face ID or equivalent), generates a fresh ZK proof from the locally stored private inputs, and submits it to the API server. The server checks the proof against the stored commitment on the private chain and returns a boolean result to the website. The entire flow is designed to complete in a few seconds.