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-poly1305“libsodium 实现了 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 年编写。
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-poly1305“libsodium 实现了 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 年编写。