23 ms·
It's quite interesting to study why crypto_(secret)box requires zero padding. It's not to avoid memory allocation, as tedu suggests, but to make the implementat
by agwa 12y ago
It's quite interesting to study why crypto_(secret)box requires zero padding. It's not to avoid memory allocation, as tedu suggests, but to make the implementation stupidly simple. For every invocation of crypto_secretbox, NaCl needs to generate a single-use 32 byte key for the Poly1305 MAC. Since the first 32 bytes of the message are zero, NaCl can simply encrypt the entire message with Salsa20, and the first 32 bytes of the resulting ciphertext conveniently become a suitable key for Poly1305. (So when the documentation says the padding has to actually be zero, it's not kidding.)
By making the implementation more complex (some memcpys and special casing of short messages), as libsodium has done for its crypto_secretbox_easy[1], you can avoid the need for this padding.
Personally, I think djb should have avoided exposing this implementation detail in the interface. To simplify the implementation, he could have used the first output block (stream position 0) of Salsa20 only for the Poly1305 key, and then encrypted the message starting with stream position 1, instead of trying to use the first output block for both the Poly1305 key and the message. The implementation would have been only marginally more complex (not as complex as the libsodium implementation, as you wouldn't need special casing). Unfortunately this can't be changed now without breaking interoperability with messages encrypted with the current version of crypto_secretbox.
[1] https://github.com/jedisct1/libsodium/blob/17932c782e5900ac8cee42fe43e3455db85351e0/src/libsodium/crypto_secretbox/crypto_secretbox_easy.c#L18-L65 https://github.com/jedisct1/libsodium/blob/17932c782e5900ac8...