What the checksum does
Two bytes of every address are a checksum computed from the key itself. When software reads an address it recomputes the checksum and compares. If they disagree, the address is rejected before any attempt is made to reach anything.
The job this does is catching mistakes. A dropped character, a transposed pair, a mistyped letter: almost all of them break the checksum, so instead of a connection attempt to nothing you get a clear rejection. Sixteen bits is not much, so a small proportion of random corruptions will pass by chance, but the common human errors are caught reliably.
What the checksum does not do is the thing people hope it does. It is computed from the key, so any correctly generated address has a correct checksum, including one generated by somebody trying to deceive you. It proves the string is well formed. It says nothing about who made it or where it leads.
What the version byte does
One byte records which generation of the address format this is. For every address currently in use it holds the same value, because there is only one generation in use.
Because that byte sits at the end of the input and base32 encodes left to right in five bit groups, its constant value produces a constant final character in every address. That is why all 12 strings on this site end the same way, and why every version 3 onion address anywhere does. The endings page lays the twelve out to show it.
It is a small thing with a practical consequence. The last character of an onion address carries no information about the address. Anybody comparing eight trailing characters is really comparing seven, and anybody who uses the ending as evidence of anything is using a constant as a fingerprint.
The division of labour
| Part | Size | Varies | What it protects against |
|---|---|---|---|
| Public key | 32 bytes | yes | Impersonation, by requiring the private key |
| Checksum | 2 bytes | yes | Typing and transcription errors |
| Version marker | 1 byte | no | Nothing, it identifies the format |
Only the first row protects you against a person. The second protects you against yourself, and the third protects nobody, which is fine because that is not its job. Confusing the three is how people end up believing an address has been verified when all that happened is that it parsed.
Questions
If the checksum is valid, is the address genuine?
No. A valid checksum means the string is well formed. Every correctly generated address has one, including any produced by somebody trying to pass off a different address as the one you wanted.
What happens if I mistype an onion address?
Almost always the checksum fails and the software rejects it immediately, so nothing is contacted. That is the checksum doing its only real job.