#include 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]; static struct { u16 add_ptr; u16 input_rotate; } input_pool = { 0 }; void mix_crc32loop(const void *in, int nbytes) { unsigned long i, j; 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 */ for (j = 0; j < 3; ++j) w = (w >> 1) ^ (0xedb88320 & -(w & 1)); input_pool_data[i] = w; /* * 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; }