diff options
Diffstat (limited to 'sparkle.c')
-rw-r--r-- | sparkle.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/sparkle.c b/sparkle.c new file mode 100644 index 0000000..55ef0d7 --- /dev/null +++ b/sparkle.c @@ -0,0 +1,60 @@ +#include <linux/kernel.h> +#include <linux/string.h> + +static const u32 r[] = { + 0xB7E15162, 0xBF715880, 0x38B4DA56, 0x324E7738, + 0xBB1185EB, 0x4F7C7B57, 0xCFBFA1C8, 0xC2B3293D +}; + +static inline void sparkle256(u32 *state) +{ + int i, j; + u32 rc, tmpx, tmpy, x0, y0; + + for (i = 0; i < 6; i ++) { + state[1] ^= r[i]; + state[3] ^= i; + for (j = 0; j < 8; j += 2) { + rc = r[j >> 1]; + state[j] += ror32(state[j + 1], 31); + state[j + 1] ^= ror32(state[j], 24); + state[j] ^= rc; + state[j] += ror32(state[j + 1], 17); + state[j + 1] ^= ror32(state[j], 17); + state[j] ^= rc; + state[j] += state[j+1]; + state[j + 1] ^= ror32(state[j], 31); + state[j] ^= rc; + state[j] += ror32(state[j + 1], 24); + state[j + 1] ^= ror32(state[j], 16); + state[j] ^= rc; + } + tmpx = x0 = state[0]; + tmpy = y0 = state[1]; + for (j = 2; j < 4; j += 2) { + tmpx ^= state[j]; + tmpy ^= state[j + 1]; + } + tmpx = ror32((tmpx ^ (tmpx << 16)), 16); + tmpy = ror32((tmpy ^ (tmpy << 16)), 16); + for (j = 2; j < 4; j += 2) { + state[j - 2] = state[j + 4] ^ state[j] ^ tmpy; + state[j + 4] = state[j]; + state[j - 1] = state[j+ 4 + 1] ^ state[j + 1] ^ tmpx; + state[j + 4 + 1] = state[j + 1]; + } + state[4 - 2] = state[4] ^ x0 ^ tmpy; + state[4] = x0; + state[4 - 1] = state[4 + 1] ^ y0 ^ tmpx; + state[4 + 1] = y0; + } +} + +void mix_sparkle(u32 h[4], const u32 v[4]) +{ + u32 s[8]; + memcpy(s, h, sizeof(u32) * 4); + memcpy(s + 4, v, sizeof(u32) * 4); + sparkle256(s); + memcpy(h, s, sizeof(u32) * 4); +} |