onchato · companion to the specification

How onchato works

Four steps take two people from a public key to a conversation nobody else can read, and no server holds anything in between. This page explains the mechanisms. SPEC.md specifies them.

This page explains; it does not specify. Where it and docs/SPEC.md disagree, the specification is right and this page is the bug. Nothing here is a wire format, a field layout or a key schedule you should build against — each section names the numbered section that is.


1

An identity is a key you cannot copy

Your identity is one X25519 key pair. On the intended deployment the private half lives inside a hardware security module and never comes out: the app asks the device to perform one Diffie-Hellman and gets back a shared secret, never the key. Copying the identity means stealing the device.

There is a second tier for people without hardware — a software profile, a key pair sealed in the browser under a password. It is the same identity contract and interoperates with hardware identities; what it gives up is that a copied profile can be attacked offline forever, which is why the password has a floor rather than a warning.

Specified in §4, software profiles in §4.5.

2

Finding each other without a directory

There is no lookup, no registry, and no server that knows who talks to whom. Two people who hold each other's public key both compute the same shared secret, and that secret names the place they meet. Each derives it from the opposite direction and arrives at the same answer, which is the one piece of arithmetic the whole design rests on.

Nobody else can compute it, because it needs a private key that never left either device. The meeting place also changes every day, and each pair rolls over at its own moment rather than at midnight, so the whole user base does not resubscribe at once.

Alice her private key + Bob's public key Bob his private key + Alice's public key the same secret computed twice, never sent the meeting place for today unguessable, and different tomorrow Somebody holding both PUBLIC keys still cannot compute it the secret needs a private half, and neither private half has ever left its device
The same arithmetic run from two directions lands on one answer. That is what replaces a directory: two people who already hold each other's public key can meet, and nobody else can even name the place. Specified in §5, daily rotation in §5.4.
3

A handshake that assumes the future is hostile

Meeting is not trusting. In the meeting place the two run a handshake that proves each is holding the identity key the other expects, and produces a fresh session key that belongs to this conversation alone.

It mixes in a post-quantum key encapsulation alongside the classical exchange. The reason is not that today's attacker can break X25519; it is that traffic recorded today can be stored until something can. Both have to fall for the session key to fall.

Specified in §6. It takes one and a half round trips and rides the same meeting place, so no separate connection is opened.

4

Every message gets its own key

The session key is not used to encrypt anything. It seeds a ratchet: a chain that steps forward for every message and, periodically, mixes in a fresh exchange from both sides — a Diffie–Hellman, and every so often a post-quantum key alongside it, the same hybrid the handshake uses. Each message is sealed under a key derived once and then thrown away.

The consequence is the point. Compromise a device now and you get what it currently holds. You do not get last week, because those keys are gone and cannot be recomputed. You do not get next week either, because the next exchange heals the chain past the point you saw — and because that exchange is post-quantum too, a future quantum attacker who captured the chain is locked out at the next mix, not merely at the next full handshake.

TIME msg 1 msg 2 msg 3 msg 4 msg 5 msg 6 msg 7 a key captured here earlier stays shut those keys were deleted, not stored this one opens later heals shut again the next exchange mixes in new randomness
This is what "forward secrecy" and "post-compromise security" mean in practice: the blast radius of a stolen key is one message, not a history and not a future. A session is also retired on a timer, so even an undetected compromise expires. Specified in §7; session lifetime in §7.3.

Two ways a message travels, and what each costs

Once a conversation exists there are two routes, and neither is free. Through the node, a message is ciphertext the operator forwards; the operator learns that some topic was busy, when, and how large the frames were. Directly, peer to peer, the node sees nothing at all — but the two devices exchange network addresses to find each other, so each learns roughly where the other is.

There is no setting that costs nothing, which is why the app states the trade rather than choosing quietly. The default is the node, because hiding your address from the person you are talking to is usually worth more than hiding your timing from an operator who cannot read anything anyway.

Alice Bob node ciphertext direct, device to device Through the node, the operator learns that a topic was busy, when, and how big the frames were never the content, never who the people are Directly, the node learns nothing — but the two devices exchange network addresses to connect so each learns roughly where the other is
Neither route is private in every direction at once. The app says which one it is using rather than deciding quietly, and it only claims the direct route once a liveness probe has come back, because a channel that opens and then swallows traffic has lied before. Specified in §13; the metadata picture in §12.

Groups without a group server

A group is a layer over the same one-to-one machinery, not a new service. Each member has a sending chain of their own; the key to read it is handed to the others over their existing encrypted one-to-one channels. Membership lives with the members, so there is nothing to ask and no operator who knows the roster.

Every message also carries a separate authentication tag for each recipient, derived from a secret only that pair shares. A member who holds somebody's sending chain can therefore read their messages but cannot forge one to a third person — and because those tags are shared secrets rather than signatures, nothing anyone receives can later be shown to an outsider as proof of who wrote it.

Removing somebody rotates the group to a new epoch with a new meeting place and fresh keys, distributed only to those who remain.

Specified in §8.


What is deliberately missing

Several things this product does not have are decisions rather than gaps, and each was cheaper to build than to leave out.

No directoryNobody can be looked up. You reach people who handed you their key, and that is the whole address book.
No stored messagesNothing queues anything for later. Two people have to be present at the same time, which is the price of nobody holding a copy.
No historyA transcript dies with the page. What survives a reload is what somebody deliberately pinned, sealed to their own identity.
No link previewsFetching a thumbnail would mean the app contacting a stranger's server for every URL, before anyone clicked.
No read receipts to the operatorDelivery is confirmed between the two people, inside the encryption, not by a server that tracks state.
No accountThere is nothing to sign up for and no password a server can be asked for, because there is no server holding one.