Security
Honest assessment of what ZChat protects and what it does not.
Threat Model
ZChat protects against
- Servers reading your messages. In Shielded mode no server of ours is involved. In Tunnel and Open modes a relay holds a gift-wrapped envelope it cannot decrypt; keys never leave your device.
- On-chain metadata analysis. In Shielded mode, Zcash's zero-knowledge proofs hide sender, receiver, and amount.
- Message content exposure. End-to-end encryption is always on, in every mode.
- Account seizure and enumeration. Your identity is a Zcash address. There is no phone number, email, or account to disable, subpoena, or look you up by.
ZChat does NOT protect against
- Network-level surveillance. Your IP is visible to your lightwalletd server, to the relays you connect to, and to our backend. Tor is available but off by default, and some paths still bypass it when it is on.
- Compromised device. If your phone is compromised, messages are readable.
- Zcash protocol vulnerabilities. If Zcash's cryptography were broken.
- Application-layer bugs. No third-party audit has been performed.
- Later compromise of past messages. Our ratchet keeps a persistent root, so there is no per-message forward secrecy: a stolen key re-derives old messages. A full double ratchet is designed but not shipped.
- An attacker in position at first contact. First contact is trust on first use, not an authenticated exchange. Compare safety numbers out of band before you rely on a conversation.
Metadata Analysis
What is hidden depends on which of the three transport modes a conversation uses. Shielded puts the message on-chain and involves no server of ours. Tunnel and Open carry it over NOSTR relays, which is what makes them free. Tunnel or Open is the default for a new conversation, not Shielded.
| Data Point | Mode | Hidden? | How |
|---|---|---|---|
| Message content | All modes | Yes | Shielded: an encrypted memo inside the transaction. Tunnel and Open: NIP-17 gift wrap over our own AES-256-GCM layer. Encryption and decryption happen only on your device. |
| Sender address | Shielded | Yes | Zcash shielded pool (Orchard). Zero-knowledge proofs hide the sender. |
| Receiver address | Shielded | Yes | Zcash shielded pool (Orchard). |
| Transaction amount | Shielded | Yes | Zcash shielded pool. Each on-chain message also carries a fixed 1000-zatoshi (0.00001 ZEC) output to a project address. |
| Sender identity | Tunnel / Open | Partial | Every message is published under a fresh ephemeral author key: in our own relay data, 400 messages arrived under 372 distinct keys. Whether those keys are unlinkable across sessions is unverified, and it is in the audit scope we asked for. |
| Recipient key | Tunnel / Open | No | A relay sees which key an envelope is addressed to, and when it arrived. Our relay (relay.zsend.xyz) keeps events for 30 days. relay.damus.io and nos.lol are also used by default and cannot be turned off in the app. |
| Message timestamp | All modes | Partial | Shielded: block time only (~75s resolution), exact send time hidden. Tunnel and Open: the relay carrying the message sees arrival time directly. |
| Message frequency | All modes | Partial | On-chain transaction counts are public but not linkable to specific users. Relay traffic volume and timing are visible to whichever relay carries the conversation. |
| IP address | All modes | No | Visible to your lightwalletd server, to every relay you connect to, and to api.zsend.xyz. Tor is available but off by default, and some paths still bypass it. |
| Device fingerprint | All modes | No | Standard Android HTTP headers reach lightwalletd, and our API backend sees an update check from each install. |
| Call metadata | Voice / video | No | Media is encrypted with DTLS-SRTP, but our TURN server relays it by design and therefore observes who is in a call and for how long. |
| Contact list | All modes | Yes | Stored locally only, never transmitted |
| AI assistant prompts | AI tab (opt-in) | No | Separate from messaging and off unless you turn it on. Prompt text passes through our backend to Venice, a third-party provider, in plaintext. |
Encryption Stack
Transport Layer
Three modes, chosen per conversation. Shielded: a memo inside a Zcash shielded transaction (Orchard pool, Halo2 proving system). Tunnel: a shielded on-chain handshake, then NOSTR. Open: NOSTR from the first message. NOSTR traffic uses NIP-17 private DMs, with NIP-59 gift wrap over NIP-44.
Application E2E
secp256r1 (P-256) ECDH key agreement + AES-256-GCM, over the ZChat ratchet layer. The ratchet retains a persistent root, so there is no per-message forward secrecy today.
Key Derivation
HKDF (RFC 5869) with V1/V2 versioning
Group Encryption
ECIES per-recipient key wrapping, with epoch rotation on membership change and signed admin control messages.
Key Exchange
ECDSA-signed KEX. The signature binds a key to the address the sender reports; it does not prove who that sender is. First contact is trust on first use, backed by safety numbers and key-change alerts.
Memo Limit
512 bytes per shielded memo, a Zcash protocol limit; ZMSG v4c chunks longer messages. Applies to Shielded mode only. ZIP-231 memo bundles would raise it and are still under review.
Voice and Video
WebRTC with DTLS-SRTP. Media is encrypted end to end, but a TURN server we run relays it when a direct path is unavailable and sees call metadata.
Key Management
- BIP39 seed phrase generates Zcash keys.
- Android: EncryptedSharedPreferences (AES-256-GCM, hardware-backed keystore where available).
- Message keys come from ECDH + HKDF, not from the wallet seed. In the shipped release your E2E identity keypair is generated on the device, so restoring a wallet from seed does not restore chat history. Deterministic seed-derived identity is implemented on our hardening branch and lands with the September 2026 release.
- No key escrow, no recovery mechanism. Lose your seed, lose your identity.
Backend Transparency
Backend runs
zebrad (full node) and lightwalletd (gRPC interface) for chain data. We also operate relay.zsend.xyz (our NOSTR relay), a TURN server on the same host for calls, and api.zsend.xyz, which serves the update check and the optional AI assistant.
Backend stores
Our relay stores gift-wrapped messages it cannot read, on a 30-day retention window set on 2 September 2026, and sees the recipient key and arrival time of each one. api.zsend.xyz logs client IP addresses, rotated daily on a 7-day window, set the same day. The optional AI assistant binds a server-side account to a SHA-256 hash of your default unified address.
Backend does NOT store
Seed phrases, private keys, readable message content, sender identity, contact lists, phone numbers, email addresses. There is no account to suspend and no address book to hand over.
Third parties in the path: relay.damus.io and nos.lol are used as default NOSTR relays, Cloudflare provides STUN, attachments use Blossom/NIP-96 media hosts, and the opt-in AI tab sends your prompt text in plaintext to Venice. Only the lightwalletd server is configurable in Settings today; relay, TURN, STUN, and media endpoints are hardcoded, with no self-hosting path in the app yet.
Audit Status
- ZChat has NOT received a third-party security audit.
- The Zcash protocol (Orchard, Halo2) has been audited by multiple firms.
- ZChat's application layer (ZMSG protocol, E2E implementation, Android app) is unaudited.
- Internal review is not a substitute for one. In July 2026 two adversarial review passes using different model families, each with read-only shell and device access against a written brief, filed 65 findings; every fix lands behind a regression test committed before it. That is why we think we can act on an audit, not a reason to skip one.
- We have applied to the OTF Security Lab for a third-party audit, targeting Q4 2026; the decision is pending. We will publish the auditor's report in full at the end of a 90-day disclosure window, and remediate critical and high findings within 30 days of delivery. Until that is done, do not use ZChat for high-stakes communications.
Responsible Disclosure
Found a vulnerability? Please report it responsibly. We aim to acknowledge within 72 hours and ask for 90 days before public disclosure. The full policy, scope, and our known open items are in SECURITY.md in the Android repository.
Known Limitations
- No third-party security audit yet (requested, Q4 2026 target)
- No per-message forward secrecy — the ratchet keeps a persistent root, so a compromised key re-derives past messages. A full double ratchet is designed but not shipped
- First contact is trust on first use — verify safety numbers out of band
- Tor is supported but off by default, and some network paths bypass it when it is on
- Relay, TURN, STUN, and media endpoints are hardcoded; only lightwalletd is user-configurable
- Message frequency patterns potentially observable on-chain, and to whichever relay carries a Tunnel or Open conversation
- 512-byte memo limit in Shielded mode requires chunking for longer messages
- Android only. There is no iOS build and no web client. Distribution is a direct signed APK from GitHub Releases, not an app store
- Single developer team
- Beta software -- expect bugs