14 {
15#define SIPROUND \
16 do { \
17 v0 += v1; \
18 v1 = rotl64(v1, 13); \
19 v1 ^= v0; \
20 v0 = rotl64(v0, 32); \
21 v2 += v3; \
22 v3 = rotl64(v3, 16); \
23 v3 ^= v2; \
24 v0 += v3; \
25 v3 = rotl64(v3, 21); \
26 v3 ^= v0; \
27 v2 += v1; \
28 v1 = rotl64(v1, 17); \
29 v1 ^= v2; \
30 v2 = rotl64(v2, 32); \
31 } while (0)
32
33 uint64_t k0;
34 uint64_t k1;
35 if (key == NULL) {
36 k0 = 0;
37 k1 = 0;
38 } else {
39 k0 = key[0];
40 k1 = key[1];
41 }
42
43 uint64_t
v0 = 0x736f6d6570736575ULL ^ k0;
44 uint64_t
v1 = 0x646f72616e646f6dULL ^ k1;
45 uint64_t
v2 = 0x6c7967656e657261ULL ^ k0;
46 uint64_t v3 = 0x7465646279746573ULL ^ k1;
47
48 const uint64_t* data = (const uint64_t*)in;
49 const uint64_t* end = data + inlen;
50
51 const uint64_t* limit = data + (inlen & ~3ULL);
52
53 while (data < limit) {
54 uint64_t m0 = data[0];
55 uint64_t m1 = data[1];
56 uint64_t m2 = data[2];
57 uint64_t m3 = data[3];
58 data += 4;
59
60 v3 ^= m0;
64
65 v3 ^= m1;
69
70 v3 ^= m2;
74
75 v3 ^= m3;
79 }
80
81 while (data < end) {
82 uint64_t m = *data++;
83 v3 ^= m;
87 }
88
89 uint64_t b = ((uint64_t)(inlen *
LIMB_BYTES)) << 56;
90 v3 ^= b;
94
100
102}