Hash ratchets with truncating hash function 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.