libsodium AEAD 实施背后的决定

Decision behind libsodium AEAD implementation

RFC 7539 定义其 AEAD 构造如下:

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)

另一方面,libsodium实现如下:

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)

基本上 libsodium 在其 Poly1305 通道上不使用填充和交错数据和元数据(其长度)。由于块对齐问题,这对优化非常不友好:计算附加数据的 MAC 后,下一个数据不需要块对齐,因此不能使用高度优化和交错的 Chacha20-Poly1305 构造。

这个决定背后的原因是什么?

引用 https://download.libsodium.org/doc/secret-key_cryptography/aead/chacha20-poly1305libsodium 实现了 ChaCha20-Poly1305 结构的三个版本”。前两个如下:

  • 原始构造可以安全地加密多达 2^64 条消息 密钥(对于大多数协议甚至更多),对大小没有任何实际限制 消息的长度(128 位标记最多 2^64 个字节)。
  • IETF 变体。它可以安全地加密实际上无限数量的 消息,但单个消息不能超过 64*(2^32)-64 字节 (大约 256 GB)。

您描述的是"original construction"。原始构造支持的随机数小于 IETF 版本(64 位与 96 位),并且 AEAD 构造也不同,如您所见。

我的猜测:"original construction" 是在编写 IETF RFC 之前开发的。 libsodium 基于 https://en.wikipedia.org/wiki/NaCl_(software),最初于 2008 年发布。IETF RFC 于 2015 年编写。