summaryrefslogtreecommitdiff
path: root/crypto/hash/siphash.tnsl
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/hash/siphash.tnsl')
-rw-r--r--crypto/hash/siphash.tnsl193
1 files changed, 193 insertions, 0 deletions
diff --git a/crypto/hash/siphash.tnsl b/crypto/hash/siphash.tnsl
new file mode 100644
index 0000000..98be8f8
--- /dev/null
+++ b/crypto/hash/siphash.tnsl
@@ -0,0 +1,193 @@
+
+# This code was naively adapted from siphash.c
+# see https://github.com/veorq/SipHash/blob/master/siphash.c
+# for the original implementation
+
+# SipHash is licenced under CC0, MIT
+# and was created originally by:
+
+# Jean-Philippe Aumasson
+# Daniel J. Bernstein
+
+# This implementation was written by NatCounter for libtnsl
+
+int SIPHASH_CROUNDS = 2
+int SIPHASH_DROUNDS = 4
+
+/; SIPHASH_ROTL (uint64 x, b) [uint64]
+ return (x << b) | (x >> (64 - b))
+;/
+
+/; SIPHASH_U32_TO_8_LE (~uint8 p, uint32 v)
+ p{0} = v
+ p{1} = (v >> 8)
+ p{2} = (v >> 16)
+ p{3} = (v >> 24)
+;/
+
+/; SIPHASH_U64_TO_8_LE (~uint8 p, uint64 v)
+ SIPHASH_U32_TO_8_LE(p, v)
+ SIPHASH_U32_TO_8_LE(p + 4, v >> 32)
+;/
+
+/; SIPHASH_U8_TO_64_LE (~uint8 p) [uint64]
+ uint64 out = p{7}
+ out = (out << 8) | p{6}
+ out = (out << 8) | p{5}
+ out = (out << 8) | p{4}
+ out = (out << 8) | p{3}
+ out = (out << 8) | p{2}
+ out = (out << 8) | p{1}
+ out = (out << 8) | p{0}
+ return out
+;/
+
+/; SIPHASH_TRACE (uint64 v0, v1, v2, v3)
+ _print("TRACE:\n\0")
+ _print_num(" v0: %016lx\n\0", v0)
+ _print_num(" v1: %016lx\n\0", v1)
+ _print_num(" v2: %016lx\n\0", v2)
+ _print_num(" v3: %016lx\n\0", v3)
+;/
+
+/; siphash (~uint8 in, uint64 in_len, ~uint8 k, ~uint8 out, uint64 out_len) [int]
+
+ uint64 v0 = 0x736f6d65
+ v0 = (v0 << 32) | 0x70736575
+ uint64 v1 = 0x646f7261
+ v1 = (v1 << 32) | 0x6e646f6d
+ uint64 v2 = 0x6c796765
+ v2 = (v2 << 32) | 0x6e657261
+ uint64 v3 = 0x74656462
+ v3 = (v3 << 32) | 0x79746573
+
+ uint64 k0 = SIPHASH_U8_TO_64_LE(k)
+ uint64 k1 = SIPHASH_U8_TO_64_LE(k + 8)
+
+ uint64 m
+ int i
+
+ ~uint8 end = in + in_len - (in_len % 8)
+ int left = in_len & 7
+ uint64 b = in_len << 56
+
+ v3 = v3 ^ k1
+ v2 = v2 ^ k0
+ v1 = v1 ^ k1
+ v0 = v0 ^ k0
+
+ /; if (out_len == 16)
+ v1 = v1 ^ 0xee
+ ;/
+
+ /; loop (in !== end) [in = in + 8]
+ m = SIPHASH_U8_TO_64_LE(in)
+ v3 = v3 ^ m
+
+ SIPHASH_TRACE(v0, v1, v2, v3)
+ /; loop (i = 0; i < SIPHASH_CROUNDS ) [i++]
+ v0 = v0 + v1
+ v1 = SIPHASH_ROTL(v1, 13)
+ v1 = v1 ^ v0
+ v0 = SIPHASH_ROTL(v0, 32)
+ v2 = v2 + v3
+ v3 = SIPHASH_ROTL(v3, 16)
+ v3 = v3 ^ v2
+ v0 = v0 + v3
+ v3 = SIPHASH_ROTL(v3, 21)
+ v3 = v3 ^ v0
+ v2 = v2 + v1
+ v1 = SIPHASH_ROTL(v1, 17)
+ v1 = v1 ^ v2
+ v2 = SIPHASH_ROTL(v2, 32)
+ ;/
+
+ v0 = v0 ^ m
+ ;/
+
+ /; loop (left--; left !< 0) [left--]
+ uint64 ii = in{left}
+ _print_num("ii: %08x\n\0", ii)
+ b = b | (ii << (left * 8))
+ ;/
+
+ _print_num("b: %016lx\n\0", b)
+ v3 = v3 ^ b
+
+ SIPHASH_TRACE(v0, v1, v2, v3)
+ /; loop (i = 0; i < SIPHASH_CROUNDS ) [i++]
+ v0 = v0 + v1
+ v1 = SIPHASH_ROTL(v1, 13)
+ v1 = v1 ^ v0
+ v0 = SIPHASH_ROTL(v0, 32)
+ v2 = v2 + v3
+ v3 = SIPHASH_ROTL(v3, 16)
+ v3 = v3 ^ v2
+ v0 = v0 + v3
+ v3 = SIPHASH_ROTL(v3, 21)
+ v3 = v3 ^ v0
+ v2 = v2 + v1
+ v1 = SIPHASH_ROTL(v1, 17)
+ v1 = v1 ^ v2
+ v2 = SIPHASH_ROTL(v2, 32)
+ ;/
+
+ v0 = v0 ^ b
+
+ /; if (out_len == 16)
+ v2 = v2 ^ 0xee
+ ;; else
+ v2 = v2 ^ 0xff
+ ;/
+
+ SIPHASH_TRACE(v0, v1, v2, v3)
+ /; loop (i = 0; i < SIPHASH_DROUNDS ) [i++]
+ v0 = v0 + v1
+ v1 = SIPHASH_ROTL(v1, 13)
+ v1 = v1 ^ v0
+ v0 = SIPHASH_ROTL(v0, 32)
+ v2 = v2 + v3
+ v3 = SIPHASH_ROTL(v3, 16)
+ v3 = v3 ^ v2
+ v0 = v0 + v3
+ v3 = SIPHASH_ROTL(v3, 21)
+ v3 = v3 ^ v0
+ v2 = v2 + v1
+ v1 = SIPHASH_ROTL(v1, 17)
+ v1 = v1 ^ v2
+ v2 = SIPHASH_ROTL(v2, 32)
+ ;/
+
+ b = v0 ^ v1 ^ v2 ^ v3
+ SIPHASH_U64_TO_8_LE(out, b)
+
+ /; if (out_len < 16)
+ return 0
+ ;/
+
+ v1 = v1 ^ 0xdd
+
+ SIPHASH_TRACE(v0, v1, v2, v3)
+ /; loop (i = 0; i < SIPHASH_DROUNDS ) [i++]
+ v0 = v0 + v1
+ v1 = SIPHASH_ROTL(v1, 13)
+ v1 = v1 ^ v0
+ v0 = SIPHASH_ROTL(v0, 32)
+ v2 = v2 + v3
+ v3 = SIPHASH_ROTL(v3, 16)
+ v3 = v3 ^ v2
+ v0 = v0 + v3
+ v3 = SIPHASH_ROTL(v3, 21)
+ v3 = v3 ^ v0
+ v2 = v2 + v1
+ v1 = SIPHASH_ROTL(v1, 17)
+ v1 = v1 ^ v2
+ v2 = SIPHASH_ROTL(v2, 32)
+ ;/
+
+ b = v0 ^ v1 ^ v2 ^ v3
+ SIPHASH_U64_TO_8_LE(out + 8, b)
+
+ return 0
+;/
+