3

RFC 7539 defines its AEAD construction as follows:

chacha20_aead_encrypt(aad, key, iv, constant, plaintext):
   nonce = constant | iv
   otk = poly1305_key_gen(key, nonce)
   ciphertext = chacha20_encrypt(key, 1, nonce, plaintext)
   mac_data = aad | pad16(aad)
   mac_data |= ciphertext | pad16(ciphertext)
   mac_data |= num_to_4_le_bytes(aad.length)
   mac_data |= num_to_4_le_bytes(ciphertext.length)
   tag = poly1305_mac(mac_data, otk)
   return (ciphertext, tag)

On the other hand, libsodium implements it as follows:

chacha20_aead_encrypt(aad, key, iv, constant, plaintext):
   nonce = constant | iv
   otk = poly1305_key_gen(key, nonce)
   ciphertext = chacha20_encrypt(key, 1, nonce, plaintext)
   mac_data = aad
   mac_data |= num_to_8_le_bytes(aad.length)
   mac_data |= ciphertext
   mac_data |= num_to_8_le_bytes(ciphertext.length)
   tag = poly1305_mac(mac_data, otk)
   return (ciphertext, tag)

Basically libsodium does not uses padding and interleaves data and metadata (its length) on its Poly1305 pass. This is very unfriendly for optimization due to block alignment issues: after computing the MAC of additional data, next data does not need to be block aligned, so you can not use a highly optimized and interleaved Chacha20-Poly1305 construct.

What is the reason behind this decision?

Community
  • 1
  • 1
user3368561
  • 779
  • 6
  • 18
  • 2
    Why not ask the author? A well phrased quesetion is generally answered. The nice thing about crypto is that we have the luxury that most of the cryptographers are still alive :) – Maarten Bodewes Jul 07 '18 at 13:12

1 Answers1

2

Quoting https://download.libsodium.org/doc/secret-key_cryptography/aead/chacha20-poly1305 "libsodium implements three versions of the ChaCha20-Poly1305 construction". The first two are as follows:

  • The original construction can safely encrypt up to 2^64 messages with the same key (even more with most protocols), without any practical limit to the size of a message (up to 2^64 bytes for a 128-bit tag).
  • The IETF variant. It can safely encrypt a pratically unlimited number of messages, but individual messages cannot exceed 64*(2^32)-64 bytes (approximatively 256 GB).

The one you describe is the "original construction". The nonces supported by the original construction are smaller than the IETF version (64-bits vs 96-bits) and the AEAD construction is different, as well, as you observed.

My guess: the "original construction" was developed before the IETF RFC was written. libsodium is based on https://en.wikipedia.org/wiki/NaCl_(software) which was initially released in 2008. The IETF RFC was written in 2015.

neubert
  • 15,947
  • 24
  • 120
  • 212