jCkvvIaH - Aleph Paste

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/random.h>

typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;

enum poolinfo {
	POOL_WORDS = 128,
	POOL_WORDMASK = POOL_WORDS - 1,
	POOL_BITS = POOL_WORDS * sizeof(u32) * 8,

	/* x^128 + x^104 + x^76 + x^51 +x^25 + x + 1 */
	POOL_TAP1 = 104,
	POOL_TAP2 = 76,
	POOL_TAP3 = 51,
	POOL_TAP4 = 25,
	POOL_TAP5 = 1,
};

static u32 input_pool_data[POOL_WORDS] = {
	0xfe00ff01, 0x03fc01fe, 0xfc07f803, 0x07f80ff0, 0xe00ff01f, 0x3fc01fe0, 0xc07f803f, 0x7f80ff00,
	0x00ff01fe, 0xfc01fe03, 0x07f803fc, 0xf80ff007, 0x0ff01fe0, 0xc01fe03f, 0x7f803fc0, 0x80ff007f,
	0xff01fe00, 0x01fe03fc, 0xf803fc07, 0x0ff007f8, 0xb00dcc9f, 0x1bc02f5e, 0xbde2c065, 0xff247380,
	0xfe00f391, 0x03ffc1e0, 0xc1c7fc03, 0x07dc0ff0, 0xe00f0f1f, 0x3fc01e1e, 0x3c7f803c, 0x7878ff00,
	0x00f0f1fe, 0xfc01e1e3, 0xc7f803c3, 0x878ff007, 0x0f0f1fe0, 0xc01e1e3f, 0x7f803c3c, 0x78ff0078,
	0xf0f1fe00, 0x01e1e3fc, 0xf803c3c7, 0x8ff00787, 0x4f0dc09f, 0x9a3e2f42, 0xdc613c65, 0xff007478,
	0x4e01ff0e, 0x183fcdc2, 0xbc253c1b, 0x36e87c70, 0x1e3b701e, 0x3c3ce760, 0x407879f5, 0xec80f0f3,
	0xe73b01e1, 0xc3ce9e03, 0x078799ec, 0xd80f0f3a, 0x67b01e1e, 0x3cef203c, 0x7879f340, 0x80f0f3d6,
	0xaf01e1e6, 0xcc7e03c3, 0x879c7c07, 0x0f0f3a78, 0xf00c3ee6, 0x5dc02cbe, 0x25ffc062, 0xf0f39780,
	0xfe0c340f, 0x03ffee00, 0x1b87fc60, 0xf42ee360, 0xe01fe1b1, 0xfc03d9b0, 0xdfe78408, 0x177ff800,
	0x00cdfef0, 0xe00173fd, 0xfbc00637, 0x6ff78005, 0x18dfef00, 0x0011ffde, 0xbc000eff, 0xff78002d,
	0x59fef001, 0x0393fde0, 0xc003a7fb, 0xf78005cf, 0x9f3d2099, 0xa31fce82, 0x5c027fa6, 0x78006cff,
	0x030ff369, 0x280bf1dd, 0xdc24f8a3, 0x06cc57f2, 0xeafa09b0, 0x0bde2713, 0x557f0c32, 0x1f706572,
	0x1ad179e8, 0xe0356c73, 0x0fe47730, 0x60c7f0d5, 0xb8238fe1, 0xc350ef29, 0x8533974d, 0xaaff01a8,
	0x4239fc1b, 0x378432fc, 0x306ba567, 0xa384ccf9, 0xf742e138, 0xe0ef07c1, 0x5a811e3f, 0x012b7d3e,
	0xe9c5d0f0, 0xcd3401fb, 0x6c0af1d3, 0xfa5303d8, 0x7fc111b8, 0x183ff688, 0x9da075d1, 0x56582a3f,
};

static struct {
	u16 add_ptr;
	u16 input_rotate;
} input_pool = { 0 };

static const u32 twist_table[8] = {
	0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
	0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278
};

static u32 rol32(u32 word, unsigned int shift)
{
	return (word << (shift & 31)) | (word >> ((-shift) & 31));
}

static void mix_pool_bytes(const void *in, int nbytes)
{
	unsigned long i;
	int input_rotate;
	const u8 *bytes = in;
	u32 w;

	input_rotate = input_pool.input_rotate;
	i = input_pool.add_ptr;

	/* mix one byte at a time to simplify size handling and churn faster */
	while (nbytes--) {
		w = rol32(*bytes++, input_rotate);
		i = (i - 1) & POOL_WORDMASK;

		/* XOR in the various taps */
		w ^= input_pool_data[i];
		w ^= input_pool_data[(i + POOL_TAP1) & POOL_WORDMASK];
		w ^= input_pool_data[(i + POOL_TAP2) & POOL_WORDMASK];
		w ^= input_pool_data[(i + POOL_TAP3) & POOL_WORDMASK];
		w ^= input_pool_data[(i + POOL_TAP4) & POOL_WORDMASK];
		w ^= input_pool_data[(i + POOL_TAP5) & POOL_WORDMASK];

		/* Mix the result back in with a twist */
		input_pool_data[i] = (w >> 3) ^ twist_table[w & 7];

		/*
		 * Normally, we add 7 bits of rotation to the pool.
		 * At the beginning of the pool, add an extra 7 bits
		 * rotation, so that successive passes spread the
		 * input bits across the pool evenly.
		 */
		input_rotate = (input_rotate + (i ? 7 : 14)) & 31;
	}

	input_pool.input_rotate = input_rotate;
	input_pool.add_ptr = i;
}

static unsigned int measure_ones(void)
{
	unsigned int ones = 0;
	int i;

	for (i = 0; i < POOL_WORDS; ++i)
		ones += __builtin_popcount(input_pool_data[i]);
	return ones;
}

int main(int argc, char *argv[])
{
	int i;

	printf("BEFORE: ones: %f%%\n", 100.0 * measure_ones() / POOL_BITS);
	mix_pool_bytes("\xa6\x9c\x7f\xa3\xfd\xca\x87\x79\x55\xc5\xd2\x09\x6b\x69\x30\x71\x92\xe8\x28\xf0\xf0\xcb\x77\x7b\x1d\x66\x47\x7d\x08\x42\x71\xde\xff\xff\xff\xf9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x24\xbb\xc4\x8d\x02\x30\xec\x33\x18\xc6\xe4\x36\x24\x0c\x9c\xd4\x55\x65\x3f\xbe\x2e\xbe\x24\x1e\x6f\x69\x1e\x84\xcd\xc8\x2b\x80\x24\xc3\x72\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xf0\x00\xff\xcb\xbd\x6e\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe7\x8b\xde\xfb\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x48\xf7\xf0\xc9", 156);
	printf("AFTER: ones: %f%%\n", 100.0 * measure_ones() / POOL_BITS);

	return 0;
}