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