Anatomy of an onion address
Four of the statements in the ALWAYS section are about the address. They all come out of the same structure, so it is worth setting the structure out once.
The parts
| Part | Size | What it is |
|---|---|---|
| Public key | 32 bytes | The service identity |
| Checksum | 2 bytes | Catches accidental corruption |
| Version | 1 byte | Which address format this is |
| Total | 35 bytes | Encoded as 56 base32 characters |
Then a dot and the fixed suffix, which carries no information about the service.
Why 35 bytes becomes 56 characters
Base32 packs 5 bits into each character. Eight characters therefore carry 40 bits, which is 5 bytes. Thirty five bytes divided by five is seven groups, and seven times eight is 56. No padding is needed because the division came out even, which is one reason this size was convenient.
The public key
This is the whole point of the format. The key is not referenced by the address, it is contained in it. Your client can decode the address and use the key directly to look the service up and to authenticate it, without asking anyone.
Thirty two bytes is a large space. Large enough that generating a key which encodes to a chosen full address is not a thing anybody can do, and the entire model rests on that.
The checksum
Two bytes derived from the key and the version. Its job is to fail fast when a character got mangled by a chat client, a line wrap or a bad copy. It saves your client from attempting a lookup that could not succeed.
It does not protect against a deliberately generated lookalike address. Whoever generated that address computed a correct checksum along with everything else, because the checksum is part of the format rather than a secret. See the prefix page.
The version byte
One byte saying which address format this is. Present so that a future format can be introduced without ambiguity. The previous format, the sixteen character one, had no version byte and was replaced wholesale rather than upgraded.
What you can check by hand
- The length. Fifty six before the dot. See the length statement.
- The alphabet. No 0, 1, 8 or 9, no punctuation. See the alphabet statement.
- The whole string against a trusted copy, mechanically rather than by eye.
You cannot check the checksum by hand, and you would gain nothing if you could, because your client already does it and a valid checksum tells you nothing about correctness.
The suffix carries nothing
Everything after the dot is fixed and identical for every onion service in existence. It is not a domain in any ordinary sense, there is no registry behind it, and it tells you only that the string in front of it should be interpreted as an onion address.
People sometimes count it into the length and get confused. It is also why an address written without the suffix is still complete information, since the suffix can be added back by anyone.
What the structure implies
That there is no registry, no expiry, no ownership record and nobody to appeal to. Everything the format gives you is contained in the string itself. Everything it does not give you has to come from somewhere else, and there is no somewhere else built in.
That is why so much of this site is about the discipline of handling a string correctly. The format hands you a strong guarantee on the condition that you have the right 56 characters, and it offers no help at all with that condition.
