I'm working on a forward secret messaging system that relies on hash ratchet. I'm using BLAKE2b as the one-way function, which by default produces 512-bit digests. These digests are truncated by my software to 256 bits using the digest_size parameter of the Python implementation before they're used as key in XChaCha20-Poly1305. Using a simplified example, is

key = os.urandom(32)
while True:
    ct = encrypt(key, input('Message: '))
    key = blake2b(key, digest_size=32)

a secure construction, or does the key lose entropy with every ratchet step? If yes, should I use BLAKE2s instead?


Collisions in the hash will make fewer and fewer keys possible based on the number of iterations, resulting in a sort of "entropy loss". (Aside, I don't think "entropy loss" is the correct term as the system is deterministic and the entropy is provided by the original key.)

Importantly, though, the effect will be very small with a 256 bit hash, as covered by this question.

In short, "yes, but not enough to matter from a security perspective".

I would add a 64-bit counter variable to that hash step as is done in some KDF and password-hashing constructions to ensure there is no chance of falling into a short cycle of keys - no matter how unlikely such a cycle would be.

  • $\begingroup$ The counter is a really good idea and easy to implement as the protocol already needs to deliver the ratchet's iteration count to account for dropped messages. As per the top answer of your link, am I right to assume after 2^64 messages, the entropy of an X448-based symmetric key would be about 224 - log2(2^64) = 160 bits? $\endgroup$ – maqp Sep 23 '18 at 21:29
  • $\begingroup$ I think that math is basically correct. But 2^64 messages is totally unrealistic in any messaging application; perhaps 2^48 messages is possible if these are all automated "event" messages of some sort fired from a busy server. If that were the case, I think using public key crypto is the wrong choice; or if you must you'd be better off batching the events and sending hundreds of them as a single message just to reduce your infrastructure costs. $\endgroup$ – rmalayter Sep 24 '18 at 14:42
  • $\begingroup$ I agree 2^64 messages is unrealistic, it just happens to be the size of the hash ratchet counter space so I used it as an example and to confirm that the bit strength of the key never drops to unsafe levels. The software is for instant messaging. Not even the mode that provides traffic flow confidentiality exceeds an average rate of 3 packets / sec. The counter variable you suggested is now implemented. Thank you! $\endgroup$ – maqp Sep 25 '18 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.