/* Based on corrpcg.c, written in 2018 by Sebastiano Vigna (vigna@acm.org)
   adapted for Xorwow by Melissa O'Neill (oneill@acm.org)

Generates two correlated sets of outputs using Xorwow generators.

See <http://creativecommons.org/publicdomain/zero/1.0/>. */


#include <stdio.h>
#include <inttypes.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>


/* Code taken from https://en.wikipedia.org/wiki/Xorshift#xorwow */

/* The state array must be initialized to not be all zero in the first four 
   words */
uint32_t xorwow(uint32_t state[static 5])
{
	/* Algorithm "xorwow" from p. 5 of Marsaglia, "Xorshift RNGs" */
	uint32_t s, t = state[3];
	t ^= t >> 2;
	t ^= t << 1;
	state[3] = state[2]; state[2] = state[1]; state[1] = s = state[0];
	t ^= s;
	t ^= s << 4;
	state[0] = t;
	return t + (state[4] += 362437);
}


int main(int argc, char* argv[]) {
	// Seed data fresh from /dev/random	
	uint32_t xw1[5] = { 0x2d2aafcb, 0xe1326aed, 0x7e1c8606, 0xa7133796,
			    0xfb5f3bc5 };
	// More random-looking seed data
	uint32_t xw2[5] = { 0x831cb49f, 0x34bd87c9, 0x7e167366, 0xe6b3d661,
			    0xe58205af };

	for(;;) {
	        uint32_t out = xorwow(xw1);
		fwrite(&out, sizeof out, 1, stdout);
		//printf("%016llx\n", out);
		out = xorwow(xw2);
		fwrite(&out, sizeof out, 1, stdout);
		//printf("%016llx\n", out);
	}
}