+/*----------------------------------------------------------------------------*
+ * SipHash-2-4 *
+ *----------------------------------------------------------------------------*/
+
+/*
+ * Reference: "SipHash: a fast short-input PRF"
+ * https://cr.yp.to/siphash/siphash-20120918.pdf
+ */
+
+#define SIPROUND \
+ do { \
+ v0 += v1; v2 += v3; \
+ v1 = rol64(v1, 13); v3 = rol64(v3, 16); \
+ v1 ^= v0; v3 ^= v2; \
+ v0 = rol64(v0, 32); \
+ v2 += v1; v0 += v3; \
+ v1 = rol64(v1, 17); v3 = rol64(v3, 21); \
+ v1 ^= v2; v3 ^= v0; \
+ v2 = rol64(v2, 32); \
+ } while (0)
+
+/* Compute the SipHash-2-4 of a 64-bit number when formatted as little endian */
+static u64 siphash_1u64(const u64 key[2], u64 data)
+{
+ u64 v0 = key[0] ^ 0x736f6d6570736575ULL;
+ u64 v1 = key[1] ^ 0x646f72616e646f6dULL;
+ u64 v2 = key[0] ^ 0x6c7967656e657261ULL;
+ u64 v3 = key[1] ^ 0x7465646279746573ULL;
+ u64 m[2] = {data, (u64)sizeof(data) << 56};
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(m); i++) {
+ v3 ^= m[i];
+ SIPROUND;
+ SIPROUND;
+ v0 ^= m[i];
+ }
+
+ v2 ^= 0xff;
+ for (i = 0; i < 4; i++)
+ SIPROUND;
+ return v0 ^ v1 ^ v2 ^ v3;
+}
+