aboutsummaryrefslogtreecommitdiffstats
path: root/sparkle.c
diff options
context:
space:
mode:
Diffstat (limited to 'sparkle.c')
-rw-r--r--sparkle.c60
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);
+}