Stop dumping match count before update, users can get it if they want
[flowspec-xdp] / siphash.h
1 /*
2    SipHash reference C implementation
3
4    Copyright (c) 2012-2021 Jean-Philippe Aumasson
5    <jeanphilippe.aumasson@gmail.com>
6    Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
7    Slightly tweaked by the git author.
8
9    To the extent possible under law, the author(s) have dedicated all copyright
10    and related and neighboring rights to this software to the public domain
11    worldwide. This software is distributed without any warranty.
12
13    You should have received a copy of the CC0 Public Domain Dedication along
14    with
15    this software. If not, see
16    <http://creativecommons.org/publicdomain/zero/1.0/>.
17  */
18
19 #include <stddef.h>
20 #include <stdint.h>
21
22 /* default: SipHash-2-4 */
23 #ifndef cROUNDS
24 #define cROUNDS 1
25 #endif
26 #ifndef dROUNDS
27 #define dROUNDS 3
28 #endif
29
30 #define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
31
32 #define U32TO8_LE(p, v)                                                        \
33     (p)[0] = (uint8_t)((v));                                                   \
34     (p)[1] = (uint8_t)((v) >> 8);                                              \
35     (p)[2] = (uint8_t)((v) >> 16);                                             \
36     (p)[3] = (uint8_t)((v) >> 24);
37
38 #define U8TO64_LE(p)                                                           \
39     (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) |                        \
40      ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) |                 \
41      ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) |                 \
42      ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
43
44 #define SIPROUND                                                               \
45     do {                                                                       \
46         v0 += v1;                                                              \
47         v1 = ROTL(v1, 13);                                                     \
48         v1 ^= v0;                                                              \
49         v0 = ROTL(v0, 32);                                                     \
50         v2 += v3;                                                              \
51         v3 = ROTL(v3, 16);                                                     \
52         v3 ^= v2;                                                              \
53         v0 += v3;                                                              \
54         v3 = ROTL(v3, 21);                                                     \
55         v3 ^= v0;                                                              \
56         v2 += v1;                                                              \
57         v1 = ROTL(v1, 17);                                                     \
58         v1 ^= v2;                                                              \
59         v2 = ROTL(v2, 32);                                                     \
60     } while (0)
61
62 #ifdef DEBUG
63 #include <stdio.h>
64 #define TRACE                                                                  \
65     do {                                                                       \
66         printf("(%3zu) v0 %016" PRIx64 "\n", inlen, v0);                       \
67         printf("(%3zu) v1 %016" PRIx64 "\n", inlen, v1);                       \
68         printf("(%3zu) v2 %016" PRIx64 "\n", inlen, v2);                       \
69         printf("(%3zu) v3 %016" PRIx64 "\n", inlen, v3);                       \
70     } while (0)
71 #else
72 #define TRACE
73 #endif
74
75 __attribute__((always_inline))
76 static inline uint64_t siphash(const void *in, const size_t inlen, const uint8_t k[16]) {
77     const unsigned char *ni = (const unsigned char *)in;
78     const unsigned char *kk = (const unsigned char *)k;
79
80     uint64_t v0 = UINT64_C(0x736f6d6570736575);
81     uint64_t v1 = UINT64_C(0x646f72616e646f6d);
82     uint64_t v2 = UINT64_C(0x6c7967656e657261);
83     uint64_t v3 = UINT64_C(0x7465646279746573);
84     uint64_t k0 = U8TO64_LE(kk);
85     uint64_t k1 = U8TO64_LE(kk + 8);
86     uint64_t m;
87     int i;
88     const unsigned char *end = ni + inlen - (inlen % sizeof(uint64_t));
89     const int left = inlen & 7;
90     uint64_t b = ((uint64_t)inlen) << 56;
91     v3 ^= k1;
92     v2 ^= k0;
93     v1 ^= k1;
94     v0 ^= k0;
95
96     for (; ni != end; ni += 8) {
97         m = U8TO64_LE(ni);
98         v3 ^= m;
99
100         TRACE;
101         for (i = 0; i < cROUNDS; ++i)
102             SIPROUND;
103
104         v0 ^= m;
105     }
106
107     switch (left) {
108     case 7:
109         b |= ((uint64_t)ni[6]) << 48;
110     case 6:
111         b |= ((uint64_t)ni[5]) << 40;
112     case 5:
113         b |= ((uint64_t)ni[4]) << 32;
114     case 4:
115         b |= ((uint64_t)ni[3]) << 24;
116     case 3:
117         b |= ((uint64_t)ni[2]) << 16;
118     case 2:
119         b |= ((uint64_t)ni[1]) << 8;
120     case 1:
121         b |= ((uint64_t)ni[0]);
122         break;
123     case 0:
124         break;
125     }
126
127     v3 ^= b;
128
129     TRACE;
130     for (i = 0; i < cROUNDS; ++i)
131         SIPROUND;
132
133     v0 ^= b;
134     v2 ^= 0xff;
135
136     TRACE;
137     for (i = 0; i < dROUNDS; ++i)
138         SIPROUND;
139
140     b = v0 ^ v1 ^ v2 ^ v3;
141     return b;
142 }
143
144 #include "rand.h"
145 static uint64_t siphash_uint64_t(const uint64_t in) {
146         return siphash(&in, sizeof(uint64_t), COMPILE_TIME_RAND);
147 }
148 __attribute__((always_inline))
149 static inline uint64_t siphash_uint32_t(const uint32_t in) {
150         return siphash_uint64_t(in);
151 }
152 static uint64_t siphash_uint128_t(const __uint128_t in) {
153         return siphash(&in, sizeof(__uint128_t), COMPILE_TIME_RAND);
154 }