What is the meaning of the checksum at the end of a mnemonic seed?
Is the checksum always a word found earlier in the mnemonic? what is the purpose of it?
Can a valid mnemonic seed be created without a checksum?
General
The purpose of a checksum is exactly what the word means - to "check" something, and the simplest form of it is to check the sum.
In general, checksum is a way to let you know if you got the right sequence of numbers. Let's say you have to write down 4 numbers, and use an extra 5th digit as a checksum where the 5th number is calculated by summing the first 4 number and taking the last digit of the result.
Example: 63841 (6+3+8+4 = 21)
Now, if I mistype one digit: 63941, the checksum would be invalid (6+3+9+4 = 22) and the mistake would be detected before, for example, sending funds to wrong acct. number or whatever you use the number for.
Monero Mnemonic Seed Checksum
The checksum is well described on https://xmr.llcoins.net/addresstests.html, and it's insightful to download the javascript code and inspect it to find answers.
Mnemonic (Electrum or Deterministic) Style – In this style, the Private View Key is derived from the Private Spend Key, so you only need to remember one thing: the seed, which is actually just a representation of the Private Spend Key itself. This 256-bit scalar can be easily converted to a "24-digit" Base1626 "number" in the form of a mnemonic seed, which is 25 words long with the last word being used as a checksum. Mnemonics convert on a ratio of 4:3 minimum: four bytes creates three words, plus one checksum word; eight bytes creates six words, plus one checksum word; and so on.
So, yes - last word is the checksum, and current implementation won't accept 24-word seed. In theory, one could recover his wallet from 24-word seed, but would need to tweak the code himself to skip the checksum check, or recompute the 25th word before restoring the account.
Looking into the code, we find that the checksum is calculated by concatenating first 3 letters (if English dictionary is used) of each word, calculating CRC32 checksum of the string, and picking the word from the list, corresponding to the checksum result (divide CRC32 by number of words being checksummed, and the result is a 0-based index of the checksum word).
So, checksum word can be unique (i.e. not found earlier in mnemonic), but it will always repeat one of the words found in your mnemonic. And yes, you could, with some tweaking, create a mnemonic without the checksum, but it's not advised to do so.
Monero Mnemonic Seed Checksum Calculation Example
Inspecting the mnemonic.js file found on this site, made by one developer from the core team (Luigi1111), we find the relevant function:
function mn_get_checksum_index(words, prefix_len) {
var trimmed_words = "";
for (var i = 0; i < words.length; i++) {
trimmed_words += words[i].slice(0, prefix_len);
}
var checksum = crc32.run(trimmed_words);
var index = checksum % words.length;
return index;
}
What that function does is: assemble a string of prefixes of each of your 24 words, run a CRC32 on that string and use the resulting number to pick a checksum word. The word is picked from one of the words found in your mnemonic.
For example, if we have the mnemonic:
skirting trash phase buckets apology gags sedan coffee vinegar else fifteen pitched idled gorilla siren cucumber urban junk vastness laboratory rift rhino situated taxi
The string which we feed to CRC32 will be:
skitraphabucapogagsedcofvinelsfifpitidlgorsircucurbjunvaslabrifrhisittax
and the result of CRC32 performed on it will be
1790087523
.
Performing a mod on that number with the number of words in your checksummed data (24 in this case) will give you an index of the checksum word:
3
.
So, the checksum is the 4th (note that index is 0-based) word of your mnemonic:
buckets
.
Why is it good to have?
The main purpose is the error-check. If you're restoring a wallet from backup and make a mistake somewhere, the checksum would tell you that you made a mistake. Of course, you could also check yourself that the resultant address is matching, but this is a lighter check done automatically so that you don't have to compare all those letters.
In addition, it helps with recovery if you lose one or two words. If you know the matching address and have the checksum, it takes about 40 minutes to recover the 2 missing words using one tool written in javascript. Without the checksum it would take roughly 24 times that - 16 hours!