Skip to content
ClipHop
Download
6 min read

How ClipHop encrypts your clipboard: X25519, AES-256-GCM, and Ed25519

A complete walkthrough of ClipHop's cryptographic design — X25519 ECDH per reconnect for session keys, AES-256-GCM for authenticated encryption, Ed25519 long-term identity keys in the Keychain / Keystore, and fingerprint verification against MITM.

By

A clipboard is a small, short-lived piece of data that routinely carries passwords, one-time codes, private URLs, diff patches, and half-written messages. That makes end-to-end encryption a baseline requirement, not a marketing bullet — the moment a clipboard touches a third-party server or an untrusted link, it becomes a credential-leak channel.

This post is the complete cryptographic design of ClipHop — the algorithms, the key lifecycle, the storage, what we do to prevent MITM, and what we deliberately don’t do. If you’re evaluating a clipboard manager and “end-to-end encrypted” is the claim, this is the level of detail you should expect to see before trusting it.

Threat model#

The design assumes an attacker who can:

  • Observe the Bluetooth LE radio traffic between your phone and your Mac.
  • Inject or modify packets on that radio.
  • Compromise one of your devices later (post-compromise impact).
  • Be physically present during pairing (proximity attack).

The design does not try to defend against:

  • An attacker who has full arbitrary code execution on one of your already-paired devices. At that point they have the session keys and the clipboard itself — no transport crypto saves you.
  • Side-channel attacks on the underlying cryptographic libraries (we use platform crypto: CryptoKit on macOS, Tink / Keystore-backed primitives on Android).

Everything below is about keeping the two trusted endpoints (your phone, your Mac) the only devices that can read your clipboard traffic, and catching any attempt to insert a third.

Long-term identity: Ed25519#

The first time ClipHop launches on a device, it generates an Ed25519 keypair. Ed25519 is a modern elliptic-curve signature scheme (Curve25519 in the Edwards form) that’s fast, standards-based, and widely attacked-and-survived.

  • On macOS, the private key is stored in the Keychain with access limited to the ClipHop app bundle.
  • On Android, the private key is stored in the Keystore with StrongBox / TEE-backed storage where the hardware supports it.

The private key never leaves the device. It isn’t transmitted during pairing, isn’t backed up to any cloud, and doesn’t exist in any form outside the hardware-backed store on the device that generated it.

The public key is what gets exchanged with paired peers. That’s what your peer means when it says “I trust device X”: X’s Ed25519 public key.

Pairing: authenticating the first exchange#

Pairing is the trust-establishment step. You do it once per pair. ClipHop offers two methods:

  • QR code — the Mac renders a QR containing its device ID and Ed25519 public key (base64url-encoded, prefixed with a version tag). The phone decodes it, storing the Mac’s public key as the identity of this pair.
  • 6-digit code — the Mac displays a 6-digit number derived from its public key and the current UTC minute. The phone scans nearby Macs and connects to the one whose code matches. Codes rotate every minute so a stolen code has a small replay window.

In both methods, the phone ends up with one specific Ed25519 public key it trusts for this pair. Any future connection must be cryptographically authenticated as coming from the holder of the corresponding private key.

Session keys: X25519 ECDH + HKDF#

Once pairing is complete, every subsequent connection derives a fresh session key. The steps:

  1. Both devices generate ephemeral X25519 keypairs for this session. X25519 is Curve25519 in Montgomery form, used specifically for Elliptic-Curve Diffie-Hellman (ECDH) key agreement.
  2. They exchange ephemeral public keys over the already-connected BLE link.
  3. Each device signs its ephemeral public key with its long-term Ed25519 identity key. The peer verifies the signature against the Ed25519 public key it stored during pairing.
  4. Both sides compute the X25519 ECDH shared secret.
  5. HKDF (HMAC-based Key Derivation Function, RFC 5869) derives the actual session key from the ECDH shared secret plus a context string.

The result is an AES-256-GCM session key that exists only in memory, is scoped to this connection, and is unrelated to the keys from the previous session.

This gives us forward secrecy: if today’s session key is compromised, yesterday’s clipboard traffic is still undecryptable because the ephemeral X25519 key that produced yesterday’s session key was discarded when yesterday’s connection ended.

Data encryption: AES-256-GCM#

Every clipboard payload and control message is wrapped in AES-256-GCM:

  • 256-bit key (the session key from the step above).
  • 96-bit nonce, unique per message.
  • Authenticated associated data (AAD) includes the message type and a monotonically increasing sequence number.
  • 128-bit authentication tag.

GCM is authenticated encryption — if a single bit of the ciphertext, nonce, or AAD is modified, the receiver rejects the message. The sequence number in the AAD prevents replay attacks: if an attacker re-sends a previously-captured packet, the receiver’s sequence tracking rejects it.

Fingerprint verification: MITM defense#

The identity fingerprint you see in the app (two groups of hex codes: “Your phone” and “Paired Mac”) is derived from the peer’s Ed25519 public key using a keyed hash, truncated to a human-verifiable length.

At pair time, both devices show their view of the fingerprint. If they match, the identity public keys each side has are genuine — no MITM occurred during pairing.

Crucially, you can re-check the fingerprint at any time — not just at pair time:

  • On Android: Paired Devices → tap the paired Mac.
  • On Mac: Preferences → Security.

If the fingerprint ever changes for an already-paired peer, something is wrong — you should unpair and re-pair. This is why we treat fingerprint verification as ongoing MITM detection, not a one-shot check.

What we deliberately don’t do#

A few things that are common in other encrypted messaging / sync tools but deliberately absent here:

  • No cloud key escrow. Nothing in your keychain ever goes to a server. There’s no recovery flow that restores keys from a cloud backup, because there’s no cloud backup.
  • No shared long-term session key. Some older “paired” systems use a single symmetric key that never rotates. We derive fresh session keys per reconnect via ECDH so compromising one session doesn’t compromise the rest.
  • No username/password. There’s no account. The only credential is your Ed25519 identity keypair, held in the local secure store.
  • No clipboard logs on our servers. We don’t operate servers. There are no logs to breach.
  • No telemetry. No crash reports, no analytics, no “which features did you use” beacons.

Storage on each device#

What’s in your device’s secure store after you’ve paired:

  • Your device’s Ed25519 private + public keypair (identity).
  • One entry per paired peer: the peer’s Ed25519 public key, a friendly name, a timestamp.

What’s on disk in app-support storage (not in the secure store):

  • Your local clipboard history. Plain local storage, protected by biometric lock on Android.

That’s the full inventory. There is no other persisted secret, no session log, no forwarded-message queue.

Known limitations#

  • Not yet independently audited. We want to commission a third-party review of the crypto and BLE stack before calling the product 1.0. That’s on the roadmap, not done yet.
  • BLE link-layer security is in addition to, not relied on for, our E2E layer. Some BLE implementations have had bugs at the link layer (KNOB, BIAS, BLUFFS); our E2E encryption is designed to hold even if the BLE link-layer security is compromised, but we can’t guarantee that posture without the audit.
  • Ed25519 and X25519 are classical-curve cryptography. If and when practical quantum computers arrive, they’ll be vulnerable. We’re watching the post-quantum key-exchange work (Kyber / ML-KEM specifically) and expect to migrate at some point after NIST’s recommendations stabilize.

The short version#

  • Identity: Ed25519 keypair per device, stored in Keychain / Keystore, never transmitted.
  • Session: X25519 ECDH per reconnect, signed with Ed25519 to prevent MITM.
  • Bulk encryption: AES-256-GCM with per-message nonces and sequence numbers.
  • Trust: fingerprint comparison at pair time and on demand.
  • Infrastructure: none. No server, no cloud, no account.

If you want the transport-layer rationale — why Bluetooth LE instead of WiFi, iCloud, or LAN — that’s in Why we chose Bluetooth LE for clipboard sync. For the setup flow, see How to sync your clipboard between Android and Mac. To install, head to the download page.