[Cryptography] Evaluating draft-agl-tls-chacha20poly1305

Adam Langley agl at google.com
Wed Sep 11 10:27:40 EDT 2013

[attempt two, because I bounced off the mailing list the first time.]

On Tue, Sep 10, 2013 at 9:35 PM, William Allen Simpson
<william.allen.simpson at gmail.com> wrote:
>    ChaCha20 is run with the given key and nonce and with the two counter
>    words set to zero.  The first 32 bytes of the 64 byte output are
>    saved to become the one-time key for Poly1305.  The remainder of the
>    output is discarded.
> Why generate the ICV key this way, instead of using a longer key blob
> from TLS and dividing it?  Is there a related-key attack?

The keying material from the TLS handshake is per-session information.
However, for a polynomial MAC, a unique key is needed per-record and
must be secret. Using stream cipher output as MAC key material is a
trick taken from [1], although it is likely to have more history than
that. (As another example, UMAC/VMAC runs AES-CTR with a separate key
to generate the per-record keys, as did Poly1305 in its original

>    Authenticated decryption is largely the reverse of the encryption
>    process: the Poly1305 key is generated and the authentication tag
>    calculated.  The calculated tag is compared against the final 16
>    bytes of the authenticated ciphertext in constant time.  If they
>    match, the remaining ciphertext is decrypted to produce the
>    plaintext.
> If AEAD, aren't the ICV and cipher text generated in parallel?  So how do
> you check the ICV first, then decipher?

The Poly1305 key (ICV in your terms?) is taken from a prefix of the
ChaCha20 stream output. Thus the decryption proceeds as:

1) Generate one block of ChaCha20 keystream and use the first 32 bytes
as a Poly1305 key.
2) Feed Poly1305 the additional data and ciphertext, with the length
prefixing as described in the draft.
3) Verify that the Poly1305 authenticator matches the value in the
received record. If not, the record can be rejected immediately.
4) Run ChaCha20, starting with a counter value of one, to decrypt the

An alternative implementation is possible where ChaCha20 is run in one
go on a buffer that consists of 64 zeros followed by the ciphertext.
The advantage of this is that it may be faster because the ChaCha20
blocks can be pipelined. The disadvantage is that it may need memory
copies to setup the input buffer correctly. A moot advantage, in the
case of TLS, of the steps that I outlined is that forgeries are
rejected faster.

> Needs a bit more implementation details.  I assume there's an
> implementation in the works.  (Always helps define things with
> something concrete.)

I currently have Chrome talking to OpenSSL, although the code needs
cleanup of course.

[1] http://cr.yp.to/highspeed/naclcrypto-20090310.pdf



More information about the cryptography mailing list