**2021-05-02**

## Realizing one general way to construct symmetric ciphers

One of the areas of cryptography that's always seemed magical to me is symmetric ciphers. I believed that they worked, but it felt amazing that people were able to construct functions that produced random-looking output but that could be inverted if and only if you had the key (and perhaps some other information, like a nonce or IV). I recently read Soatok's Understanding Extended-Nonce Constructions, which set off a sudden understanding of a general, straightforward way to construct symmetric ciphers (although not all ciphers are built this way).

A provably secure general encryption technique is the one-time pad. One way to do one-time pad encryption on computers is to have your OTP be a big collection of random bytes (known by both sides) and then use the fact that 'A xor B xor A' is just B. The sender XORs their message with the next section of their OTP, and the receiver just XORs it again with the same section, recovering the original message (this is a form of XOR cipher). However, one-time pads are too big for practical use. What we would like is for each side to generate the one-time pad from a smaller, easier to handle seed.

What we need is a *keystream*,
or more exactly a way to generate a keystream from an encryption
key and probably some other values like a nonce (a one-time pad is
a keystream that requires no generation). The keystream we generate
needs to have a number of security properties like randomness and
unpredictability, but the important thing is that our keystream
generation function doesn't have to be invertible; in fact, it
shouldn't be invertible. There are a lot of ways to do this,
especially since it's sort of what cryptographic hashes do, and
it's easy for me to see how you could possibly create keystream
generation functions.

What I've realized and described is a *stream cipher*, as opposed to a
*block cipher*. While
I'd heard to the two terms before, I hadn't understood the cryptographic
nature of this distinction, vaguely thinking it was only about
whether you had to feed in a fixed size input block or could use
more flexible variable-sized inputs. Now I've learned better in the
process of writing this entry and learned something more about
cryptography.

(I could probably learn and understand more about how it's possible to construct block ciphers if I read more about them, but there's only so far I'm willing to go into cryptography.)

** (Previous day | Next day) **