forked from rurban/smhasher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtsip.c
75 lines (61 loc) · 1.75 KB
/
tsip.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <stdint.h>
static uint64_t inline U8TO64_LE(const unsigned char *p) {
return *(const uint64_t *)p;
}
static uint64_t rotl64(uint64_t x, int k) {
return (((x) << (k)) | ((x) >> (64 - k)));
}
uint64_t tsip(const unsigned char *seed, const unsigned char *m, uint64_t len) {
uint64_t v0, v1;
uint64_t mi, k0, k1;
uint64_t last7;
k0 = U8TO64_LE(seed);
k1 = U8TO64_LE(seed + 8);
v0 = k0 ^ 0x736f6d6570736575ull;
v1 = k1 ^ 0x646f72616e646f6dull;
last7 = (uint64_t)(len & 0xff) << 56;
#define sipcompress() \
do { \
v0 += v1; \
v1 = rotl64(v1, 13) ^ v0; \
v0 = rotl64(v0, 35) + v1; \
v1 = rotl64(v1, 17) ^ v0; \
v0 = rotl64(v0, 21); \
} while (0)
const unsigned char *end = m + (len & ~7);
while (m < end) {
mi = U8TO64_LE(m);
v1 ^= mi;
sipcompress();
v0 ^= mi;
m += 8;
}
switch (len & 7) {
case 7:
last7 |= (uint64_t)m[6] << 48;
case 6:
last7 |= (uint64_t)m[5] << 40;
case 5:
last7 |= (uint64_t)m[4] << 32;
case 4:
last7 |= (uint64_t)m[3] << 24;
case 3:
last7 |= (uint64_t)m[2] << 16;
case 2:
last7 |= (uint64_t)m[1] << 8;
case 1:
last7 |= (uint64_t)m[0];
case 0:
default:;
};
v1 ^= last7;
sipcompress();
v0 ^= last7;
// finalization
v1 ^= 0xff;
sipcompress();
v1 = rotl64(v1, 32);
sipcompress();
v1 = rotl64(v1, 32);
return v0 ^ v1;
}