-
Notifications
You must be signed in to change notification settings - Fork 56
Description
Hi, I went through the implementation of the Salsa20 algorithm and I found out, that the table nonce (16 bytes long) is written to the matrix on positions z6, z7, z8 and z9 (in cf_salsa20_core() ):
x6 = z6 = read32_le(nonce + 0),
x7 = z7 = read32_le(nonce + 4),
x8 = z8 = read32_le(nonce + 8),
x9 = z9 = read32_le(nonce + 12),
The first two parts (z6 and z7) are set to zero during the initialization and z8 and z9 contain the nonce from the input:
memset(ctx->nonce, 0, sizeof ctx->nonce);
memcpy(ctx->nonce + 8, nonce, 8);
Later in the algorithm positions z6 and z7 are incremented every 64-byte block of the encrypted message:
incr_le(ctx->nonce, ctx->ncounter);
So as I understand z6 and z7 contain the 64-bit counter and z8 and z9 contain the actual nonce.
The issue I found is that the documentation of Salsa20 says that the 64-bit counter is supposed to be on positions z8 and z9, and the 8-byte nonce on positions z6 and z7. So to me it looks like the positions are switched and the algorithm is not compatible with the standard.
Refs:
https://en.wikipedia.org/wiki/Salsa20
http://www.ecrypt.eu.org/stream/papersdir/2007/010.pdf
If the same algorithm is used on both sides, the message is encrypted and decrypted correctly. However, the problems may occur if the message encrypted with Cifra implementation is decrypted with some other implementation that handles the nonce/pos as it is described in the documents.