Here is arc4random.c from the LibreSSL pseudorandom generator as used in OpenBSD.
It works as follows:
- Take 40 "truly random" bytes from OS (PRG seed);
- Use the seed as key and IV to generate 1024 bytes of ChaCha keystream;
- Use the last 984 bytes of the keystream as a PRG output, and the first 40 bytes as the key and IV to generate the next 1024 of ChaCha keystream;
- Repeat until the total number of keystream bytes exceed the limit; after that reseed (go to the step 1).
I don't quite understand the purpose of the step 3 (see the lines 135-138 of the linked code):
/* immediately reinit for backtracking resistance */ _rs_init(rsx->rs_buf, KEYSZ + IVSZ); memset(rsx->rs_buf, 0, KEYSZ + IVSZ); rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
Why isn’t the whole keystream as a PRG output used? Why does the "rekeying" step make the PRG more secure?