This document explains how KENI encrypts your data, where the keys live, what our server can and cannot see, and the deliberate trade-offs we made. We wrote it for people who actually read whitepapers — concise, no marketing.
1. Threat model
We assume the network is hostile and our infrastructure is assumed-breached. The goal is: even an attacker with full read access to our database, plus traffic capture between client and server, cannot read your 1:1 message text. (Group messages and the media you send in 1:1 are server-readable by design — see §5.)
We do not defend against malware on your own device, a compromised peer (your friend's phone), or a lawful subpoena against our compliance archive (see §5). If your threat model requires defending against state-level actors with subpoena power, Signal is the right answer — KENI made a different choice and we'll explain it honestly.
2. Key generation
On first install the client generates two key pairs on-device:
- Identity key: X25519, used for long-term peer identification. Public half uploaded to the server; private half lives device-locally in iOS Keychain (kSecAttrAccessibleAfterFirstUnlock, iCloud sync disabled) or Android EncryptedSharedPreferences (allowBackup excluded). It is never replicated to iCloud or Google cloud backup.
- Prekey: X25519, rotated. Used for asynchronous session setup so a peer who's offline can still receive your first message.
Private keys are never transmitted to our servers. The optional passphrase backup (§4) is the only way private keys leave the device, and that copy is encrypted with a key derived from a passphrase we never see.
3. Per-room session
When two users start a 1-on-1 chat:
- Client A fetches B's identity public key from server.
- Both clients run X25519 ECDH locally to derive a 32-byte shared secret.
- Shared secret seeds AES-256-GCM. Each message uses a fresh 12-byte random nonce; ciphertext + nonce are transmitted.
- Group chats default to server-side encryption with a compliance copy (see §5). An optional end-to-end group mode using the Sender Keys protocol (a rotating per-sender key distributed over each member's pairwise session) is implemented but not yet enabled by default.
We are not implementing the full Signal Double Ratchet yet. We use static-X25519-ECDH derived session keys with random per-message nonces. This gives us confidentiality + integrity via AES-GCM, but does not give post-compromise security or forward secrecy at the message level — if a peer's identity key is later stolen, historical ciphertexts remain decryptable to whoever has it. Ratchet is on the roadmap.
4. Identity backup (zero knowledge)
Losing your phone shouldn't lose your message history. Users can opt into a passphrase-backed key escrow:
- User types a passphrase (≥ 8 chars), entered only on-device.
- Client generates a random 16-byte salt.
- Client runs PBKDF2-SHA256, 100k iterations, salt + passphrase → 256-bit KEK.
- Client encrypts { identity_priv, identity_pub, prekey_priv, prekey_pub } as JSON with AES-256-GCM under KEK, fresh nonce.
- Client uploads { version, salt, ciphertext } to server.
Server stores opaque ciphertext. Without the passphrase we can't derive the KEK; without the KEK we can't decrypt. Lost passphrase = permanently lost backup. We will not "reset" your identity for you because we can't.
5. Compliance archive (be aware)
1:1 message text is end-to-end encrypted only — no compliance copy, nothing we can decrypt, not even us. Group messages keep a compliance copy encrypted with KENI's platform public key (group chats are server-readable by design; an optional end-to-end group mode is in development and not yet enabled). The group compliance copy exists for two reasons:
- Lawful disclosure orders. Without it, we cannot comply with a subpoena even if legally required. Some apps choose not to comply by design — that's a defensible position; we made a different one.
- CSAM detection. Images are hashed with Microsoft PhotoDNA against the known-CSAM corpus before delivery (see /safety). This requires the server to see image bytes briefly.
The platform private key is held in HSM-grade storage. Access is gated on multi-party authorization with logged justification. We do not mine the archive for product analytics, advertising, or training data. If this trade-off doesn't fit your threat model, please use Signal — we won't be offended.
6. AI features (what leaves your device)
AI features (the KENI assistant, intent routing, summarization) are not E2EE. The cloud LLM has to read your prompt to answer. What we do:
- PII auto-scrub before egress: regex-based replacement of phone numbers, emails, credit cards, national IDs, IPs with placeholders; restored in the LLM response.
- One-time consent dialog the first time you open any AI surface. Revocable in Settings → Privacy, which disables all AI features.
- Optional local mode: download Qwen2.5-0.5B GGUF (~280MB) to run a small model on-device; switch STT to Whisper for fully offline transcription. Neither path sends audio or prompts to anyone.
7. TURN / WebRTC media
Voice/video uses WebRTC. Signaling goes through our WS gateway (the SDPs themselves are not message content). Media flows peer-to-peer when NAT allows; behind symmetric NAT we relay through our coturn server (currently at 8.210.91.228, TLS on 5349). The relay sees encrypted SRTP packets — it cannot decrypt media. Each session uses HMAC-SHA1 short-term TURN credentials (24h TTL) signed by the gateway with a server-only secret; users never see permanent TURN passwords.
8. What we deliberately did NOT do
- No analytics SDKs that profile users (no Mixpanel, no Amplitude). Crash reporting via Firebase Crashlytics only, scoped to stack traces.
- No third-party ad SDKs. No IDFA / GAID collection.
- No contact list upload. Contact discovery hashes phone numbers client-side (SHA-256 over E.164) and uploads only the hash list; we never see your raw contacts.
- No background location. Live-location is an explicit per-room opt-in with auto-expiry.
9. Open issues & roadmap
- Double Ratchet for forward secrecy + post-compromise security at message level (current static-ECDH is the gap).
- Multi-device key sync via a documented "device linking" flow. Today, moving to a new device relies on the passphrase-encrypted identity backup (§4) — identity keys are not auto-synced through iCloud Keychain.
- NCMEC ESP registration pending; until live, CSAM matches are
queued in
ncmec_reportswith status=pending_retry. - Compliance-archive third-party audit. We're a small team
and haven't done one yet. The code (
backend/handlers/ecdh.go,handlers/moderation.go) is the source of truth in the meantime.
10. Contact
Found a bug in our crypto? Want to argue with a trade-off above? Email safety@hikeni.com. We read every report and reply within 5 working days.