Contact-based peer-to-peer encrypted messenger for Android. Sub-project #1 of 6 in a phased program toward a KakaoTalk-class messenger with a usage-bound Gene token. Built on Signal Protocol primitives — no homegrown crypto.
[ ANDROID :: A ] [ ANDROID :: B ] │ │ │ (1) WebSocket / TLS 1.3 — auth · prekey upload · signaling │ ├─────────────────────┐ ┌───────────────────┤ ▼ ▼ ┌──────────────────────────────────────────┐ │ SIGNALING / DISCOVERY (Ktor) │ │ · pre-key store (X3DH bootstrap)│ │ · psi-lite discovery (16-bit bucket) │ │ · webrtc sdp / ice relay │ │ · sealed-sender mailbox (offline queue) │ │ · fcm trigger (data-only) │ └──────────────────────────────────────────┘ ▲ │ ┌─────────────────────┘ (both online → switch to direct) │ │ │ (2) WebRTC DataChannel — DTLS-SRTP — Signal layer on top │ ◄═════════════════════════════════════════════════════════════════► │ │ │ (3) FCM data-only — wakes the device, payload is empty {"v":"1"}│ ◄─────────────────────────────────────────────────────────────────┤
WebRTC DataChannel over DTLS, with the Signal Protocol envelope inside it. Transport is treated as untrusted. STUN: Google public; TURN: self-hosted coturn for symmetric NAT and carrier mobile networks.
Sender uploads sealed envelope to mailbox; server triggers FCM data-only push. Recipient wakes, polls, decrypts on device. ACK clears the queue. Unacknowledged envelopes auto-purge after 30 days; per-user cap is 1000 / 100 MB (whichever is lower).
Extended Triple Diffie-Hellman. Bootstraps a fresh session against the recipient's pre-key bundle (signed pre-key + one-time pre-key).
Per-message symmetric ratchet + DH ratchet. Provides forward secrecy and post-compromise security inside a session.
Hides the sender identity in the envelope from the signaling server. Production cert (Ed25519) ships in F-5.
Long-term Curve25519 keypair. Generated on first launch, stored under Android Keystore. Account ID = b64url(sha256(pub))[0:16].
Audited reference implementation. We wrap it; we do not reimplement primitives.
SQLCipher passphrase wrapped by an AES-256 Keystore key. Opaque blob stored in SharedPreferences.
// v1 — bucketed lookup (PSI-lite). Full OPRF ships in F-6. 1. client extracts E.164-normalized numbers from address book 2. for each ↦ SHA-256("messenger:" || E164) — keep top 16 bits as bucket 3. client uploads bucket-set only (NEVER full hashes, NEVER plaintext numbers) 4. server returns candidate routing-tokens whose bucket overlaps 5. client runs OPRF check per candidate — exact match, server learns nothing // known v1 limitation ─ bucket-only matching is not full mathematical PSI; plaintext phone numbers still never reach the server.
| Module | Status | Responsibility |
|---|---|---|
| :shared | implemented | Protocol DTOs — RegisterAccount, PreKeyBundle, Discovery, Relay, Signaling (kotlinx-serialization) |
| :server | implemented | Ktor app · H2/Postgres-mode DB · Exposed schema · identity / prekey / discovery / relay routes · WebSocket signaling hub · JUnit 5 tests |
| :android:core:storage | implemented | Room entities + DAOs · SQLCipher · Keystore-wrapped DB key |
| :android:core:identity | implemented | Account-ID derivation · key lifecycle |
| :android:core:crypto | implemented | libsignal wrappers · Room-backed SignalProtocolStore · X3DH / Double-Ratchet roundtrip test |
| :android:core:discovery | implemented | E.164 normalizer · bucket hasher · lookup HTTP client |
| :android:core:network | implemented | Ktor HTTP / WebSocket clients (identity, prekey, relay, signaling) |
| :android:core:messaging | implemented | MessageSender · MessageReceiver · Outbox · ConversationRepository |
| :android:app | implemented | Compose Material3 nav shell · KakaoTalk-tinted theme |
1:1 text · phone-discovery · E2EE · WebRTC + relay · usable shell
KakaoTalk-grade design pass over the Compose shell
Verifiable activity metrics — prerequisite for the token
Ledger · mining algorithm · time-decay · pre-mine
Master vs. regular flavors · staged rollout
External security audit · public beta · GA release
Build verification was not performed in this session. The terminal that authored the code has JDK 17 but no Android SDK and no Gradle CLI. All sources are written against documented APIs but compile / test passes must be run from Android Studio.
Do not deploy this for real users yet. Sealed Sender is currently a placeholder, the discovery PSI is bucket-only (not full PSI), and there has been no external security audit.
Korean legal review — 가상자산이용자보호법 / 특금법 — is required before sub-project #4 (token mining + ledger). This affects corporate structure and runs as a parallel non-code workstream.
Always points to the latest stable release. Updates after install happen via in-app OTA.
⬇ Download APK (latest)