# Salsa20 / ChaCha with 128 bit keys

According to wikipedia both Salsa20 and ChaCha support both 128 and 256-bit keys.

The initial state for each has 8 words of key, where each word is 32 bits. 32*8 = 256. My question is... how is one supposed to expand a 128-bit key to fill in the 256-bits needed for the initial state?

The most obvious way would be to just append the 128-bit key to itself but in some ciphers, like RC2 or RC4 or Blowfish or the key goes through a key expansion step to expand the key to whatever size is ultimately needed - a key expansion step that doesn't simply append the orig key to itself.

• Page 8 of the spec. If you're this curious about Salsa20 and ChaCha don't mess around with Wikipedia, just go straight to DJB's pages on Salsa and ChaCha and read the papers. They're short. This generalizes to other algorithms; looking up the papers usually answers your questions quicker and better than reading most third-party summaries thereof. – Luis Casillas Jan 24 '19 at 0:57

As Luis Casillas said in his comment, the spec of Salsa is short and well explained. Namely, if you are interested in the expansion function, you can find a description with two examples (one with a 32-byte key, and one with a 16-byte key).

Short answer: when dealing with a 16-byte key, you only have to change a constant and append the key to itself.

More details bellow.

Salsa keystream generator, noted $$Salsa20_k(n)$$ for a key $$k$$ and a nonce $$n$$, is based on a hash function : $$hSalsa20$$ (called $$Salsa20$$ in the spec). This hash function works as follow : if $$x$$ is a 64-byte sequence, $$hSalsa20(x)$$ is a 64-byte sequence.

Now, let's see the role of the key and how it is managed. Whether you're using a 32-byte key or a 16-byte key, there is no real key expansion as you can find in Blowfish. Instead, the key $$k$$ is divided in two 16-bytes subkeys $$k_0$$ and $$k_1$$ (if $$k$$ is 16 bytes long, $$k_1 = k_0$$). Then, a 16-byte constant is added to the state, and that's where there is a difference : the value is not the same depending on the key size:

• for a 16-byte key, this constant is "expand 16-byte k"
• for a 32-byte key, this constant is "expand 32-byte k"

This constant is divided into 4 equal part, let's call them $$\sigma_0,\sigma_1,\sigma_2$$ and $$\sigma_3$$, 4-byte each.

The keystream is produced as follow : $$Salsa20_k(n) = hSalsa20(\sigma_0\ ||\ k_0\ ||\ \sigma_1\ ||\ n\ ||\ \sigma_2\ ||\ k_1 || \sigma_3)$$ where $$||$$ denotes the concatenation.

Notice that in both case, the argument of $$hSalsa20$$ is 64-byte, so 64-byte of keystream is produced. You only have to increment the nonce, and start over to generate more keystream.