README.md

LS47 hand-computable cipher

This is a slight improvement of the ElsieFour cipher as described by Alan
Kaminsky [1]. We use 7x7 characters instead of original (barely fitting) 6x6,
to be able to encrypt some structured information. We also describe a simple
key-expansion algorithm, because remembering passwords is popular. Similar
security considerations as with ElsieFour hold.

There’s also a 3D-printable SCAD model of the whole thing. Yay!

We suggest printing the model using more than one filament color to make the
letters easily recognizable. Thanks go to Martin Ptasek for providing the
picture.

If you trust your computer, there is now a very simple python implementation in
ls47.py. A much better version usuable as an actual binary (also supporting
several versions of padding and the original ElsieFour cipher) was supplied by
Bernhard Esslinger from the CrypTool project, available in lc4.py.

Character board

We have added some real punctuation, basic stuff for writing expressions,
punctuation and quotes. The letters of the board now look like this:

at least around 61 decimal digits if made only from random decimal digits

at least around 44 letters if made only from completely random letters

at least around 40 alphanumeric characters if made randomly only from them

To have the “standard” 128 bits of entropy, the numbers reduce to roughly 39,
28 and 25, respectively.

Note that you can save the expanded tile board for later if you don’t want to
expand the passwords before each encryption/decryption.

The actual expansion can be as simple as this:

initialize I:=0, put the tiles on the board sorted by their numbers (i.e. as on the picture above)

Take the first letter of the password and see the numbers on its tile; mark them Px, Py.

Rotate I-th row Px positions right

Rotate Ith column Py positions down

I := I + 1 mod 7, repeat from 2 with next letter of the password.

Resulting tile positions are the expanded key

Undistinguishable ciphertexts

To get a different ciphertext even if the same plaintext is encrypted
repeatedly; prepend it with a nonce. A nonce is a completely random sequence of
letters of a pre-negotiated length (e.g. N tiles drawn randomly from a bag,
adviseable value of N is at least 10).

You may also want to add a random number of spaces to the end of the ciphertext
-- it prevents the enemy from seeing the difference between ciphertexts of ‘yes
please’ and ‘no’, which would otherwise encrypt to gibberish that is easily
distinguishable by length, like qwc3w_cs'( and +v.

Authenticated encryption

Because ciphertext may be altered in the transfer or during the error-prone
human processing, it is advised to append a simple “signature” to the end of
the message; which may look as simple as __YourHonorableNameHere. If the
signature doesn’t match expectations (which happens with overwhelming
probability if there was any error in the process), either try again to see if
you didn’t make a mistake, or discard the message and ask the sender to
re-transmit.

This works because the cipher output is message-dependent: Having a wrong bit
somewhere in the middle causes avalanche effect and erases any meaning from the
text after several characters.