Cryptography LIBAEAD实施背后的决策

Cryptography LIBAEAD实施背后的决策,cryptography,libsodium,Cryptography,Libsodium,将其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

将其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)
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)
另一方面,它的实现如下所示:

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)
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)
基本上,libnaude在Poly1305过程中不使用填充和交错数据和元数据(其长度)。由于块对齐问题,这对优化非常不友好:在计算附加数据的MAC后,下一个数据不需要块对齐,因此不能使用高度优化和交错的CHA20-Poly1305构造

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

引用“LibNaudio实现了ChaCha20-Poly1305构造的三个版本”。前两项是:

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)
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)
  • 原始构造可以使用相同的密码安全加密多达2^64条消息 密钥(在大多数协议中甚至更多),对大小没有任何实际限制 消息的长度(128位标记最多2^64字节)
  • IETF变体。它可以安全地加密实际数量不限的 消息,但单个消息不能超过64*(2^32)-64字节 (大约256 GB)
你所描述的是“原始结构”。正如您所观察到的,原始构造支持的nonce小于IETF版本(64位vs 96位),AEAD构造也不同


我猜,“原始结构”是在编写IETF RFC之前开发的。LibNadium是基于2008年首次发布的LibNadium。IETF RFC编写于2015年。

为什么不问问作者?措词恰当的问题通常会得到回答。加密技术的好处在于,我们拥有大多数密码学家还活着的奢侈品:)