1 #include "crypto_shorthash_siphash24.h"
2 #include "private/common.h"
3 #include "shorthash_siphash_ref.h"
4 
5 int
crypto_shorthash_siphashx24(unsigned char * out,const unsigned char * in,unsigned long long inlen,const unsigned char * k)6 crypto_shorthash_siphashx24(unsigned char *out, const unsigned char *in,
7                             unsigned long long inlen, const unsigned char *k)
8 {
9     uint64_t       v0 = 0x736f6d6570736575ULL;
10     uint64_t       v1 = 0x646f72616e646f83ULL;
11     uint64_t       v2 = 0x6c7967656e657261ULL;
12     uint64_t       v3 = 0x7465646279746573ULL;
13     uint64_t       b;
14     uint64_t       k0 = LOAD64_LE(k);
15     uint64_t       k1 = LOAD64_LE(k + 8);
16     uint64_t       m;
17     const uint8_t *end  = in + inlen - (inlen % sizeof(uint64_t));
18     const int      left = inlen & 7;
19 
20     b = ((uint64_t) inlen) << 56;
21     v3 ^= k1;
22     v2 ^= k0;
23     v1 ^= k1;
24     v0 ^= k0;
25     for (; in != end; in += 8) {
26         m = LOAD64_LE(in);
27         v3 ^= m;
28         SIPROUND;
29         SIPROUND;
30         v0 ^= m;
31     }
32     switch (left) {
33     case 7:
34         b |= ((uint64_t) in[6]) << 48;
35     case 6:
36         b |= ((uint64_t) in[5]) << 40;
37     case 5:
38         b |= ((uint64_t) in[4]) << 32;
39     case 4:
40         b |= ((uint64_t) in[3]) << 24;
41     case 3:
42         b |= ((uint64_t) in[2]) << 16;
43     case 2:
44         b |= ((uint64_t) in[1]) << 8;
45     case 1:
46         b |= ((uint64_t) in[0]);
47         break;
48     case 0:
49         break;
50     }
51     v3 ^= b;
52     SIPROUND;
53     SIPROUND;
54     v0 ^= b;
55     v2 ^= 0xee;
56     SIPROUND;
57     SIPROUND;
58     SIPROUND;
59     SIPROUND;
60     b = v0 ^ v1 ^ v2 ^ v3;
61     STORE64_LE(out, b);
62     v1 ^= 0xdd;
63     SIPROUND;
64     SIPROUND;
65     SIPROUND;
66     SIPROUND;
67     b = v0 ^ v1 ^ v2 ^ v3;
68     STORE64_LE(out + 8, b);
69 
70     return 0;
71 }
72