What we can prove,
and what we cannot yet
This page states DChat's threat model, the security properties its cryptography does and does not provide, and where the gaps are. It is written to be checked, not to reassure.
Where DChat actually stands
Security claims are worth exactly as much as the evidence behind them. Here is the evidence, and its absence, stated plainly.
| Status | |
|---|---|
| Published cryptographic specification | Yes - read it |
| Documented threat model and non-goals | Yes - this page |
| Vulnerability disclosure policy | Yes - below |
| Build transparency (toolchain + release hashes) | Partial - below |
| Independent third-party audit | No |
| Formal verification of the protocol | No |
| Paid bug bounty | No - reports are still welcomed and credited |
| Fully reproducible builds | No - requires public source first |
What DChat is built to resist
A threat model is only meaningful if it names the adversary. These are the ones DChat's architecture is designed to defeat.
The operator, meaning us
DChat holds no message-decryption keys and runs no server that stores plaintext. We cannot read your messages, cannot hand them over, and cannot suspend an account we do not control. This is enforced by key custody, not by policy, which is the only version of the promise worth making.
A compromised relay or validator
Relays forward ciphertext. Validators process identity registrations, username records and group membership. Neither ever holds a message-decryption key, so compromising one yields envelopes and routing data, not conversations.
A passive network observer
Every message and call payload is encrypted end-to-end before it leaves the device. An observer on the wire sees ciphertext, and the envelope metadata described in the limits section.
Server seizure or legal compulsion
Message history exists only on participants' devices. There is no server-side archive to seize or subpoena. What can be compelled is what is already public on-chain: addresses, optional usernames, group membership records.
A stolen but locked device
Keys live in platform secure storage backed by hardware where the device provides it. At-rest blobs are wrapped with ChaCha20-Poly1305 under a PBKDF2-derived key. An attacker with the locked device and no unlock credential does not get your keys.
What DChat does not protect against
These are real limitations of the current design, not hypotheticals. If your safety depends on any of them, DChat is the wrong tool today.
- Per-message forward secrecy. DChat does not implement a Double Ratchet. Chat keys rotate on a policy - by default every 10,000 messages or 30 days, whichever comes first - not on every message. Compromise of a chat key exposes the messages in that generation's window, not just one message.
- Post-compromise security. There is no ratchet that automatically heals a session after a key compromise. Recovery requires a key rotation.
- Deniability. Messages are signed with your identity key. DChat does not provide the cryptographic deniability that off-the-record designs aim for.
- Metadata privacy at the envelope layer. The wire envelope carries the sender DID, the sender's public key, the chat id and a key generation number in the clear. That is pseudonymous, not anonymous: a relay can see that address A is talking to chat C, and can link messages from the same sender over time.
- Network-level anonymity. DChat does not bundle onion routing. Your IP is visible to the peers and relays you connect to. Run it over Tor or a VPN if network-layer anonymity matters.
- Protection from a compromised device. Malware with your unlocked device reads your messages, because at that point it is you. No messenger solves this.
- Traffic analysis resistance. There is no cover traffic and no fixed-size padding. Message timing and size are observable.
- End-to-end confidentiality and integrity of message content, using ChaCha20-Poly1305 with a 256-bit key and a 128-bit authentication tag.
- Authenticated sender identity, via secp256k1 signatures over a key pair that never leaves the device.
- Bounded key lifetime, through the rotation policy described in the specification.
- Group confidentiality with per-member sender keys. The DChat client rotates them when someone is removed or leaves, so a departed member cannot read what follows - though that step is the client's job, not the SDK's (8.7).
- No operator access to plaintext, no server-side message archive, no account suspension.
- Self-custodied recovery, with the trade-off that a lost recovery phrase is unrecoverable by design.
The primitives, in one paragraph
Identity is a secp256k1 key pair derived from a BIP-39 mnemonic along the Cosmos BIP-44 path. Direct messages derive a shared secret by secp256k1 ECDH, run it through HKDF-SHA256, and encrypt with ChaCha20-Poly1305 using a fresh 96-bit random nonce per message. Group messages use per-member sender keys under the same AEAD. Data at rest is wrapped with ChaCha20-Poly1305 under a PBKDF2-HMAC-SHA256 key bound to a device master key held in platform secure storage.
Every parameter, wire format, derivation path and context string is written out in the cryptographic specification, including the parts we consider weaknesses.
Verifying the app you installed
Full reproducible builds require public source, which DChat does not have yet, so we do not claim them. What we can do today is publish exactly how the shipped artifact is produced and let you verify the binary you received matches the one we published.
The release build
-p:AndroidPackageFormat=aab
-p:AndroidKeyStore=true
-p:AndroidEnableProguard=true
Toolchain: .NET 10 with the MAUI Android workload, JDK 21, R8 shrinking enabled. The application id is com.dchat.dmessenger.
Signing keys
Builds distributed through Google Play are re-signed by Google under Play App Signing, so a Play install carries a different certificate than an APK downloaded from this site. The direct-download signing key is published in our Digital Asset Links file:
17:30:A4:16:2D:95:0C:6C:97:9F:62:D2:DD:A2:FE:03:
BF:85:22:A0:A8:6A:F4:95:25:85:77:03:E5:43:1E:9B
The Play App Signing certificate fingerprint is not published yet. Until it is, a Play install cannot be verified against that file, and we would rather say so than let the omission read as coverage.
Verify what you installed with:
Found something? Tell us
Security reports are read by a person, not a queue. Send them through the contact form with "Security" in the subject line, or start a conversation with the official DChat account inside the app.
Useful reports include the version, the platform, what you observed, and enough detail to reproduce it. If you have a proof of concept, include it. If you are not sure whether something is a bug, send it anyway.
Coordinated disclosure
We will acknowledge within 5 business days
If you do not hear back in that window, assume the report did not reach us and send it again through a different channel.
We ask for 90 days before public disclosure
Ninety days from acknowledgement, or until a fix ships, whichever comes first. If a fix will take longer we will say so and explain why rather than let the clock run out quietly.
Credit is yours unless you decline
Reporters are credited by name or handle in the release notes for the fix. There is no paid bounty programme yet, and we are not going to pretend otherwise.
Good-faith research is welcome
Testing against your own accounts and devices, and against our public endpoints at a reasonable rate, is fine. Do not access other people's data, degrade the service for others, or run destructive tests against the live chain.
Read the actual specification
Every primitive, parameter and wire format, including the parts we flag as weaknesses.