{
title: The design of Chacha20
description: Chacha20 is a secure, fast, and amazingly simple
encryption algorithm. Let's take a look.
}
January 2017
(Update: thanks Thomas Ptacek for
[pointing out](https://news.ycombinator.com/reply?id=13365580) the
origins of Chacha20.)
The design of Chacha20
======================
Chacha20 is a secure, fast, and amazingly simple encryption algorithm.
It's author Daniel J. Bernstein explains it well in his [Salsa20][]
and [Chacha20][] design papers (which I recommend), but did not dwell
on details experts already know. Filling the gap took me a while.
[Salsa20]: http://cr.yp.to/snuffle/design.pdf
[Chacha20]: http://cr.yp.to/chacha/chacha-20080128.pdf
Quick summary: Chacha20 is ARX-based hash function, keyed, running in
counter mode. It embodies the idea that one can use a hash function
to encrypt data.
Stream ciphers
--------------
While Chacha20 is mainly used for encryption, its core is a
pseudo-random number generator. The cipher text is obtained by
XOR'ing the plain text with a pseudo-random stream:
cipher_text = plain_text XOR chacha_stream(key, nonce)
Provided you never use the same nonce with the same key twice, you can
treat that stream as a [one time pad][OTP]. This makes it very
simple: unlike block ciphers, you don't have to worry about padding,
and decryption is the same operation as encryption:
[OTP]: https://en.wikipedia.org/wiki/One-time_pad (Wikipedia)
plain_text = cipher_text XOR chacha_stream(key, nonce)
Now we just have to get that stream.
The quarter-round
-----------------
Chacha20 works by scrambling the hell out of 512-bit blocks, using 80
applications of the _quarter-round_. The quarter round itself
scrambles 4 32-bit numbers (that's a fourth of a block) thus:
a += b; d ^= a; d > (32 - n))
#define QUARTERROUND(a, b, c, d) \
a += b; d ^= a; ROT_L32(d, 16); \
c += d; b ^= c; ROT_L32(b, 12); \
a += b; d ^= a; ROT_L32(d, 8); \
c += d; b ^= c; ROT_L32(b, 7)
for (int i = 0; i
#include
↧
The design of Chacha20
↧