back to work

zkPoke

Period 2025Context NoirHack team projectRole Backend & ZK Developer

A first-place NoirHack prototype where users hold credentials in Aztec private state and disclose only selected identity fields to another user.

Problem

Users needed to prove an Instagram-linked identity and disclose selected fields without exposing the original email or their full credential set.

Contribution

I built the Express verification backend, Noir circuit workflow, and zk-email pipeline from DKIM parsing through UltraHonk proof generation and verification.

Result

1st place at NoirHack.

System

A React application using Aztec private state, an Express proving backend, Noir circuits, UltraHonk proofs, zk-email, and Poseidon2 commitments.

Main challenge

Verifying RSA-backed DKIM data inside the proving workflow while exposing only the outputs required for replay prevention and credential insertion.

Overview

zkPoke is a social prototype built on Aztec that lets a sender disclose selected identity fields inside an encrypted poke. Credentials are stored as private notes, while only a Merkle root is published for membership checks.

Verification pipeline

The user uploads Instagram's DKIM-signed security email. zk-email converts its headers, RSA key, signature, and relevant byte ranges into circuit inputs. The backend builds the witness, generates an UltraHonk proof, verifies it, and returns the resulting credential leaf.

The circuit verifies the DKIM signature, Instagram sender address, claimed recipient hash, and extracted username. Public outputs include the mail-key hash, a replay-prevention nullifier, and the recipient hash. A Poseidon2 leaf binds the verified claim for insertion into Magna's Merkle tree.

Credentials and selective disclosure

Each credential is an encrypted Aztec note; only its Poseidon2 hash enters the user's public Merkle root. Membership is checked inside the contract without exposing other credentials.

A four-bit mask is applied in-circuit before the recipient note is created, so hidden identity fields are absent from the disclosed payload rather than merely hidden by the UI.

Technical deep dive
System topology — app, proving backend, private contractsThe React application uses Aztec's PXE for private state and an Express backend for credential verification. The backend parses the uploaded email, runs the Noir circuit, generates and verifies an UltraHonk proof, and returns the credential leaf committed by the Magna contract.
System topology — app, proving backend, private contractsThe React application uses Aztec's PXE for private state and an Express backend for credential verification. The backend parses the uploaded email, runs the Noir circuit, generates and verifies an UltraHonk proof, and returns the credential leaf committed by the Magna contract.Aztec contracts — private stateemail bytesverify → leaf hashtxs · notesprivate calls.eml uploadDKIM-signed Instagram mailReact appcredential wizard · pokesaztec.jsVerification backendExpress · Noir runtimeUltraHonk prove + verifyAztec PXEprivate execution envZkPokepokes · intentionsselective disclosurePrivateRegister · Magna8 credential note slotspublic Merkle root
Instagram verification — email to private credentialThe backend verifies the DKIM-signed Instagram email in a Noir circuit and derives a Poseidon2 credential leaf. The original email and extracted username remain private inputs.
01Upload.eml → base64
02Parsezk-email · DKIM inputs
03ProveNoir · UltraHonk
04Verifyserver-side check
05LeafPoseidon2 hash
06Credentialnote + Merkle root
Key decisions & why
01

zk-email DKIM as the trust anchor

Instagram security emails already carry an RSA-backed DKIM signature. Verifying it in-circuit turns an existing inbox message into an ownership witness without OAuth or scraping.

02

Server-side proving with UltraHonk

RSA verification over email headers is expensive in a browser. The Express backend builds the circuit inputs, executes Noir, generates the UltraHonk proof, verifies it, and returns only the credential leaf required by the frontend.

03

Private notes, disclosure in-circuit

Publishing only a Merkle root hides which credentials a user holds. Applying the disclosure mask in the private contract ensures the recipient note contains only the fields the sender selected.

Stack
  • TypeScript
  • Node.js
  • Express
  • React
  • Noir
  • Aztec
  • UltraHonk
  • zk-email
  • Poseidon2