Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decision behind libsodium AEAD implementation

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?

like image 395
user3368561 Avatar asked Mar 15 '26 16:03

user3368561


1 Answers

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.

like image 72
neubert Avatar answered Mar 17 '26 13:03

neubert



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!