Privacy / ZK
What privacy means on EDMA
We keep evidence provable and people private. Facts that move money are public as hashes (PoV hash, burn hash, Locked→Unlocked deltas); sensitive documents and PII stay in role-gated vaults with signed URLs and redaction commitments. Where a program needs to “see enough without seeing everything,” we add zero-knowledge proofs (ZK) so the Gate can check a statement without revealing the raw value.
Two laws never change: the dossier must still pass the checklist, and money never moves early—No EMT, no funds.
Privacy model
Evidence files (COAs, BL + seal photo, temp logs) live off-chain; the chain anchors hashes. The canonical dossier omits any PII the schema marks as redactable and commits to a salted hash instead. Authorized parties fetch files via short-lived signed URLs; auditors can verify redactions offline with the salt. For fields that don’t need raw disclosure, the submitter can attach a ZK proof that a condition holds (e.g., “temperature stayed between 2–8 °C” or “shelf-life ≥ 180 days”) while binding the proof to the same PoV hash the Gate is evaluating.
On-chain: PoV hash, EMT ids, Locked→Unlocked EDSD deltas, fee & EDM burn lines, One-Claim updates.
Off-chain: PDFs/photos/CSVs/EDI + signed URLs; redaction salts in a Salt Vault (KMS/HSM).
Commitments: sha256(file_bytes) for files; sha256(canonical_json_bytes) for the dossier; salted redaction hashes for PII.
Access: role-based; every fetch is audit-logged; no files in webhooks.
What ZK is for here
ZK proves statements about data without showing the data. It never replaces PoV and never overrides the schema.
Range: “temperature ∈ [2,8] °C” over a Merkle-committed log.
Threshold / inequality: “shelf-life ≥ 180 days” computed from redacted MFG/EXP dates.
Membership / region: “origin ∈ {CN-Anhui, CN-Shanghai}”, “route ∈ approved corridors”.
Format / checksum: “serial conforms to program checksum and set X”.
Aggregate: “≤ 1% carton damage” from a blinded count vector.
Identity-light: “KYC passed & not on sanctions list” via a third-party verifiable credential.
ZK is not for suppressing required documents, bypassing attestor roles, or weakening One-Claim. If the schema says the BL and seal photo/number are required, you provide them; ZK can add checks, not remove them.
How ZK plugs into the Gate
Bind: the proof statement references the PoV hash (sha256 of canonical bytes) and the specific schema field(s).
Verify: On-chain verification for succinct circuits (range/membership). The schema lists the verifying-key hash; the Gate calls the verifier precompile/library. Attested verification for heavy circuits (large Merkle logs). The Inspector/Temperature-OEM verifies off-chain and signs a role attestation that includes the proof hash; the Gate counts that signature via the Attestor Registry.
Decide: the Gate enforces the same checklist: quorum, equality, freshness, One-Claim, must-fund. A ZK pass simply satisfies fields the schema marked as “zk-acceptable”.
Performance rule: if verifying on-chain would make the business clock miss seconds-level targets, we use attested verification and keep the PoV hash as the anchor.
Supported statements
temp_in_range(root, interval, min, max) — Merkle root + inclusion proofs.
shelf_life_ge(mfg_hash, exp_hash, min_days) — redacted dates + salted commitments.
origin_in_set(code, set_root) — set membership via Merkle/accumulator.
serial_in_program(serial_hash, program_root) — checksum + set membership.
kyc_ok(vc_hash, issuer_key) — verifiable-credential signature (no personal data).
If a statement isn’t in the schema, it doesn’t count toward PASS.
Governance knobs
Approve statement templates, publish verifying-key hashes, set max proof age, and designate attesting roles for off-chain verification.
Rotate verifying keys with a timelock; anchor new hashes in the schema registry.
Set gas/latency budgets for on-chain verification; if a proof exceeds, the Gate rejects with E_ZK_BUDGET_EXCEEDED.
Foundations unchanged: No EMT, no funds, One-Claim, must-fund, 50% burn.
Developer surface
GET /v1/zk/statements: discover templates and verifying-key hashes per schema.
POST /v1/zk/proofs: submit { statement_id, pov_hash, proof_bytes | attestor_sig }; receive a proof_id.
POST /v1/trade/proof/{order}/{stage} or /v1/tokens/mint|settle: reference proof_id for fields marked “zk-acceptable”.
Errors: E_ZK_BAD_BINDING — proof not bound to this pov_hash/schema. E_ZK_VERIFY_FAIL — invalid proof/signature. E_ZK_STALE — proof older than allowed window. E_ZK_BUDGET_EXCEEDED — exceeds on-chain gas/latency limit (use attested mode).
Show “ZK-verified” chips next to fields; link to the statement template.
Never show raw values when a ZK statement satisfied the field.
Privacy recipes
Cold-chain: commit the full temp log as a Merkle root; prove each segment was in range. Public sees “in range” and the root; regulators can fetch segments by inclusion proof.
Shelf-life: redact MFG/EXP; prove “≥ 180 days” and bind to the PoV hash.
Brand auth: brand issues a signed auth VC; schema accepts kyc_ok-style proof from the brand key—no letters uploaded publicly.
Route membership: origin/port codes proven against an allowlist accumulator; no need to disclose intermediate nodes.
Security & pitfalls
Mis-binding: every proof must include the PoV hash; otherwise, it can be replayed.
Key drift: verifying-key hashes pinned in schemas; rotations timelocked and visible in the Explorer.
Over-use: don’t “ZK everything.” Only fields the schema marks as zk-acceptable should use it; everything else remains explicit files + hashes.
Attested verification trust: when proofs are verified off-chain, the attesting role and its SLA/bond carry accountability; governance can slash/rotate.
Compliance mapping
GDPR/PII: keep PII off-chain; use redactions + salted commitments; ZK to prove relationships without disclosure.
Audit: proof pages link the PoV hash, statement ids, verifying-key hashes, and (when used) attestor signatures. Auditors can re-verify with the same code and keys.
Export controls/sanctions: kyc_ok-style proofs keep documents private while proving status from a trusted issuer.
Plain recap
Last updated