Add ZK email offchain token transfer example#35
Open
critesjosh wants to merge 11 commits intonextfrom
Open
Conversation
Noir circuit verifies DKIM-signed emails from icloud.com and an Aztec contract verifies the proof on-chain using verify_honk_proof. Includes testnet deployment scripts, integration tests, and proof generation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nullifier, and freshness checks Rework the circuit and contract from a simple domain-verification demo into a full email-based authorization flow: recipient binding via to-address hash, intent binding via subject hash, single-use nullifiers from the DKIM signature, and timestamp freshness checks. Update README to document the security model, contract API (including view functions), and fix Poseidon2 references. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The contract now stores trusted DKIM public key hashes and verifies them against proof outputs, preventing forgery with self-generated keypairs. Update the security model (4 → 5 constraints), constructor signature (3 → 5 params), verify_email steps, diagram, and troubleshooting to match the actual contract code. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Store trusted DKIM public key hashes at deployment and verify them against proof outputs in verify_email, preventing forgery with self-generated keypairs. Tighten timestamp extraction to ensure the t= tag falls strictly within the DKIM-Signature header field. Make header field parsing case-insensitive per RFC 5322. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Address review comments: [P2] Revert case-insensitive header field matching in generate_data.ts. The header input is DKIM-canonicalized (c=relaxed), so field names are always lowercase — case-insensitive matching was unnecessary and masked the real requirement. Update circuit and script comments to state the canonicalization requirement definitively. [P3] Rewrite DKIM key mismatch troubleshooting to direct operators to a trusted DNS source rather than the rejected proof's own public inputs, which are prover-controlled. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… partial notes Renames ZKEmailVerifier to EmailClaim and integrates the offchain transfer tutorial pattern: Bob deposits tokens mapped to his email address hash, Carol creates a partial note and completes it by submitting a verified zkEmail proof. The circuit now outputs 7 public inputs (adds from_address_hash for sender identification), the contract manages token balances and partial note completion, and the security model expands from 5 to 6 points. Also hardens timestamp parsing to reject empty t= values. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace testWallet.setPublicAuthWit().send() with the explicit SetPublicAuthwitContractInteraction.create() API, which is the correct way to set public authwits on EmbeddedWallet. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Clarify what stays private (email content, Carol's identity) vs. what is public (deposit amounts, email address hash linkability, claim amounts, deposit-to-claim linkage). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…artial notes
Replaces UintNote::partial() with manual partial note creation that
accepts a randomness parameter, allowing Carol to compute the commitment
offchain before the transaction lands. Updates scripts and tests to
compute commitments client-side via poseidon2HashWithSeparator and pass
{ commitment } to claim_with_email.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
EmailClaimcontract mapped to his email address hash. Carol creates a partial note, gets Bob's email authorization, generates a zkEmail proof offchain, and submits it to claim her tokensicloud.com, extracts sender/recipient addresses, subject, and timestamp, and outputs 7 public fieldsverify_honk_proof, enforces a 6-point security model (DKIM key binding, sender identification, recipient binding, intent binding, single-use nullifier, freshness), deducts from the depositor's balance, and completes the recipient's partial noteSecurity model
Test plan
yarn installandnargo compileincircuit/yarn cccto compile contract and generate bindingsyarn datato generate proof datayarn testagainst local network (deploys token + EmailClaim, deposits, creates claim, verifies proof, checks balances)yarn testnetfor testnet deployment🤖 Generated with Claude Code