Skip to content

Mobile Synchronization

mzchat allows users to connect new mobile devices to their existing identity without exposing their Root Identity ($K_{id}$) secret key to the mobile OS. This is achieved through an E2EE handshake facilitated by a temporary server-side mailbox.

When a user connects a mobile device from their existing desktop/web client, the following flow occurs:

  • The Authorized Device (Web/Desktop) generates a unique session_id.
  • It displays a QR code containing a unified URL: https://<homeserver>/qr/login/<session_id>.
  • The Authorized Device then calls SyncMailbox(wait_for_data: true) and waits for the new device to respond.
  • The New Device (Mobile) scans the QR code and extracts the homeserver and session_id.
  • It generates its own ephemeral Device Identity ($K_{dev}$) and a unique device_id.
  • It sends its Public Key and device_id to the homeserver via SyncMailbox(payload: <mobile_keys>).
  • The Authorized Device receives the mobile keys from the mailbox.
  • It uses its local $K_{id}$ secret key to sign a new Device Certificate for the mobile device.
  • It sends the signed certificate along with the user’s profile metadata (ID, username) back to the mailbox via SyncMailbox(payload: <signed_cert_and_profile>).
  • The New Device receives the certificate and profile.
  • It stores the $K_{dev}$ secret key and the signed certificate in secure storage.
  • It immediately performs a Login RPC using the new certificate.
  • Isolation: $K_{id}$ never leaves the original device. The mobile device only ever holds its own $K_{dev}$.
  • E2EE Handshake: While the server facilitates the exchange, the mailbox is intended for short-lived, single-use payloads. In future iterations, payloads can be further encrypted using a shared secret derived from the QR code.
  • Revocability: Since the Authorized Device issued the certificate, it can also sign a revocation statement for that specific device_id if the phone is lost.

The SyncMailbox RPC provides a simple, ephemeral relay mechanism:

  • session_id: A unique key for the handshake session.
  • payload: Raw bytes containing JSON-encoded handshake data.
  • long-polling: Support for wait_for_data allows clients to wait for a peer’s response without constant polling.
  • TTL: Mailbox sessions automatically expire after 5 minutes.