01 The problem with encrypting only the database
For a while, Pixel Dust's database was encrypted and its screenshots were not. The index — every word we had read off your screen, every URL, every window title — sat in an SQLCipher database with a key in your Keychain. Next to it, in a folder called thumbnails, were the screenshots themselves. As plain JPEGs. Hundreds of megabytes of them.
We had encrypted the description of your day and left the photographs on the table. Anyone who copied the folder — a backup, a sync client, another account on the same Mac — got the pictures for free.
The reason was an assumption we never tested: that decrypting an image on every timeline frame would be too slow to ship. Scrubbing through your history has to feel like scrubbing through a video. We assumed a cipher in that path would break it.
02 So we measured it
On an M-series Mac, with a real 625 KB capture from a real library:
| Operation, per frame | Time |
|---|---|
| AES-GCM decrypt | 0.20 ms |
| JPEG decode, full 2560×1663 | 14.8 ms |
| JPEG decode, thumbnail size | 4.9 ms |
Decryption is 1.4% of the decode we were already paying on every frame. At 30 frames per second, scrubbing spends six milliseconds per second on it. Apple gives AES its own silicon; JPEG decoding gets none. The expensive step was never the cipher. We had been protecting the cheap thing and skipping the free one.
The two alternatives we had been circling both rested on the same wrong assumption. Mounting an encrypted disk image so the kernel does the work costs nothing in the app — and nothing over 0.2 ms either, while adding mount lifecycle, crash recovery, and Time Machine interactions. Storing images as blobs inside the encrypted database gets the same AES for free, but puts hundreds of megabytes of binaries into SQLite, which then needs vacuuming. Neither was worth it for a fifth of a millisecond.
03 What we built
Per-file AES-GCM. Each capture is sealed on its way to disk and opened on its way back. GCM authenticates as well as encrypts, so a modified or truncated file fails loudly rather than decoding into something.
One key, derived twice. The image key is derived from the database key with HKDF, using a fixed purpose string. The two keys are unrelated as far as anyone holding one is concerned — an image key cannot be replayed against the database — but one recovery phrase still restores both. Key separation without a second phrase to lose.
thumbnail key = HKDF-SHA256(
input : database key,
info : "pixeldust.thumbnails.v1",
length: 32 bytes
)
A header, so old and new can coexist. A JPEG starts with FF D8 FF. A sealed capture starts with a magic string, a version byte, and a 12-byte nonce. Every reader checks which it is holding. That means an existing library keeps opening the moment the feature ships, and migration can happen in the background.
Migration on idle, on wall power. Pixel Dust already had a background job that walks every thumbnail while you are away — recompressing old captures and pruning near-duplicates — and it already waited for fifteen minutes of idle time, a plugged-in Mac, and enough battery. Encrypting the pre-existing plaintext captures rides on that job. It costs 0.12 ms per file and never runs while you are working.
Every reader had to move. The timeline, search results, and the OCR pipeline each loaded thumbnails their own way. One of them read the file directly through CGImageSourceCreateWithURL, which cannot see past a cipher header. Miss a reader and images fail silently for that surface. We routed all of them through one function.
04 What this changes for you
Before this, losing your recovery phrase cost you the searchable text; the pictures survived. Now it costs you everything. That is the correct behavior for a product claiming encryption — and it is why we rebuilt the recovery kit into a printed page with numbered words, made you confirm it before setup finishes, and will not offer a support path that recovers it. We do not have your key. That is the point.
What it does not change: while Pixel Dust is running, it holds the key, and anything running as you can read what it reads. Encryption at rest protects a copied folder or a stolen disk. It does not protect an unlocked Mac with someone sitting at it. For that there is the Touch ID lock on the timeline, which is a different answer to a different question.
Pixel Dust is free during the beta. Everything stays on your Mac.
Request beta access