During encryption, characters towards the bottom of often generate summed indexes that are “out of range” so have no character to map to. To fix this, we adjust the summed value “into range” by looping back to the start of the table to find a character for the Ciphertext. Why does this matter?
When you add or remove characters from the table, decryption of these characters will become corrupted. The cipher relies on the indexes of characters remaining consistent for the encryption and decryption of rows, and also on the total number of rows being unchanged. There are two options here:
Don’t add/remove characters once the system is in use. During initial setup, really consider what will be required, and stick to your decision after launch. Or otherwise you will need to decrypt all secrets first before updating , then re-encrypt them afterwards. Minimizing Impact
You may have noticed that the Latin-1 Supplement Uppercase & Lowercase block is included by default, and may have wondered why (these characters are rarely used in English). I primarily included this block to help minimizing the corruption we’ve discussed.
During encryption, some characters end up “out of range” because the sum of their index and the corresponding character in the key’s index exceeds the available characters in the table. To map them to a character (in order to generate the ciphertext), we loop back to the beginning of the table. When the Count() of the available characters changes, these out of range characters end up decrypting to the wrong characters and we get corrupted text. This Latin-1 Supplement block therefore serves as a kind of “buffer” to help reduce the likelihood of this happening often when changes are made to the character mapping table.