1#include "crypto_shorthash_siphash24.h"
2#include "private/common.h"
3#include "shorthash_siphash_ref.h"
4
5int
6crypto_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        /* FALLTHRU */
37    case 6:
38        b |= ((uint64_t) in[5]) << 40;
39        /* FALLTHRU */
40    case 5:
41        b |= ((uint64_t) in[4]) << 32;
42        /* FALLTHRU */
43    case 4:
44        b |= ((uint64_t) in[3]) << 24;
45        /* FALLTHRU */
46    case 3:
47        b |= ((uint64_t) in[2]) << 16;
48        /* FALLTHRU */
49    case 2:
50        b |= ((uint64_t) in[1]) << 8;
51        /* FALLTHRU */
52    case 1:
53        b |= ((uint64_t) in[0]);
54        break;
55    case 0:
56        break;
57    }
58    v3 ^= b;
59    SIPROUND;
60    SIPROUND;
61    v0 ^= b;
62    v2 ^= 0xff;
63    SIPROUND;
64    SIPROUND;
65    SIPROUND;
66    SIPROUND;
67    b = v0 ^ v1 ^ v2 ^ v3;
68    STORE64_LE(out, b);
69
70    return 0;
71}
72