/src/libzip/lib/siphash.c
Line | Count | Source |
1 | | /* |
2 | | SipHash reference C implementation |
3 | | |
4 | | Copyright (c) 2012-2022 Jean-Philippe Aumasson |
5 | | <jeanphilippe.aumasson@gmail.com> |
6 | | Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to> |
7 | | |
8 | | To the extent possible under law, the author(s) have dedicated all copyright |
9 | | and related and neighboring rights to this software to the public domain |
10 | | worldwide. This software is distributed without any warranty. |
11 | | |
12 | | You should have received a copy of the CC0 Public Domain Dedication along |
13 | | with |
14 | | this software. If not, see |
15 | | <http://creativecommons.org/publicdomain/zero/1.0/>. |
16 | | */ |
17 | | |
18 | | #include "siphash.h" |
19 | | |
20 | | /* default: SipHash-2-4 */ |
21 | | #ifndef cROUNDS |
22 | 266k | #define cROUNDS 2 |
23 | | #endif |
24 | | #ifndef dROUNDS |
25 | 173k | #define dROUNDS 4 |
26 | | #endif |
27 | | |
28 | 1.90M | #define ROTL(x, b) (zip_uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) |
29 | | |
30 | | #define U32TO8_LE(p, v) \ |
31 | 69.5k | (p)[0] = (zip_uint8_t)((v)); \ |
32 | 69.5k | (p)[1] = (zip_uint8_t)((v) >> 8); \ |
33 | 69.5k | (p)[2] = (zip_uint8_t)((v) >> 16); \ |
34 | 69.5k | (p)[3] = (zip_uint8_t)((v) >> 24); |
35 | | |
36 | | #define U64TO8_LE(p, v) \ |
37 | 34.7k | U32TO8_LE((p), (zip_uint32_t)((v))); \ |
38 | 34.7k | U32TO8_LE((p) + 4, (zip_uint32_t)((v) >> 32)); |
39 | | |
40 | 123k | #define U8TO64_LE(p) (((zip_uint64_t)((p)[0])) | ((zip_uint64_t)((p)[1]) << 8) | ((zip_uint64_t)((p)[2]) << 16) | ((zip_uint64_t)((p)[3]) << 24) | ((zip_uint64_t)((p)[4]) << 32) | ((zip_uint64_t)((p)[5]) << 40) | ((zip_uint64_t)((p)[6]) << 48) | ((zip_uint64_t)((p)[7]) << 56)) |
41 | | |
42 | | #define SIPROUND \ |
43 | 317k | do { \ |
44 | 317k | v0 += v1; \ |
45 | 317k | v1 = ROTL(v1, 13); \ |
46 | 317k | v1 ^= v0; \ |
47 | 317k | v0 = ROTL(v0, 32); \ |
48 | 317k | v2 += v3; \ |
49 | 317k | v3 = ROTL(v3, 16); \ |
50 | 317k | v3 ^= v2; \ |
51 | 317k | v0 += v3; \ |
52 | 317k | v3 = ROTL(v3, 21); \ |
53 | 317k | v3 ^= v0; \ |
54 | 317k | v2 += v1; \ |
55 | 317k | v1 = ROTL(v1, 17); \ |
56 | 317k | v1 ^= v2; \ |
57 | 317k | v2 = ROTL(v2, 32); \ |
58 | 317k | } while (0) |
59 | | |
60 | | /* |
61 | | Computes a SipHash value |
62 | | */ |
63 | 34.7k | zip_uint64_t siphash(const zip_uint8_t *data, const zip_uint8_t *key) { |
64 | 34.7k | const zip_uint8_t *ni = data; |
65 | 34.7k | const zip_uint8_t *kk = key; |
66 | 34.7k | size_t inlen = strlen((const char *)data); |
67 | 34.7k | zip_uint64_t out; |
68 | | |
69 | 34.7k | zip_uint64_t v0 = UINT64_C(0x736f6d6570736575); |
70 | 34.7k | zip_uint64_t v1 = UINT64_C(0x646f72616e646f6d); |
71 | 34.7k | zip_uint64_t v2 = UINT64_C(0x6c7967656e657261); |
72 | 34.7k | zip_uint64_t v3 = UINT64_C(0x7465646279746573); |
73 | 34.7k | zip_uint64_t k0 = U8TO64_LE(kk); |
74 | 34.7k | zip_uint64_t k1 = U8TO64_LE(kk + 8); |
75 | 34.7k | zip_uint64_t m; |
76 | 34.7k | int i; |
77 | 34.7k | const unsigned char *end = ni + inlen - (inlen % sizeof(zip_uint64_t)); |
78 | 34.7k | const int left = inlen & 7; |
79 | 34.7k | zip_uint64_t b = ((zip_uint64_t)inlen) << 56; |
80 | 34.7k | v3 ^= k1; |
81 | 34.7k | v2 ^= k0; |
82 | 34.7k | v1 ^= k1; |
83 | 34.7k | v0 ^= k0; |
84 | | |
85 | 88.9k | for (; ni != end; ni += 8) { |
86 | 54.2k | m = U8TO64_LE(ni); |
87 | 54.2k | v3 ^= m; |
88 | | |
89 | 162k | for (i = 0; i < cROUNDS; ++i) { |
90 | 108k | SIPROUND; |
91 | 108k | } |
92 | | |
93 | 54.2k | v0 ^= m; |
94 | 54.2k | } |
95 | | |
96 | 34.7k | switch (left) { |
97 | 2.55k | case 7: |
98 | 2.55k | b |= ((zip_uint64_t)ni[6]) << 48; |
99 | | /* FALLTHRU */ |
100 | 3.35k | case 6: |
101 | 3.35k | b |= ((zip_uint64_t)ni[5]) << 40; |
102 | | /* FALLTHRU */ |
103 | 8.56k | case 5: |
104 | 8.56k | b |= ((zip_uint64_t)ni[4]) << 32; |
105 | | /* FALLTHRU */ |
106 | 9.30k | case 4: |
107 | 9.30k | b |= ((zip_uint64_t)ni[3]) << 24; |
108 | | /* FALLTHRU */ |
109 | 10.1k | case 3: |
110 | 10.1k | b |= ((zip_uint64_t)ni[2]) << 16; |
111 | | /* FALLTHRU */ |
112 | 11.3k | case 2: |
113 | 11.3k | b |= ((zip_uint64_t)ni[1]) << 8; |
114 | | /* FALLTHRU */ |
115 | 12.1k | case 1: |
116 | 12.1k | b |= ((zip_uint64_t)ni[0]); |
117 | 12.1k | break; |
118 | 22.6k | case 0: |
119 | 22.6k | break; |
120 | 34.7k | } |
121 | | |
122 | 34.7k | v3 ^= b; |
123 | | |
124 | 104k | for (i = 0; i < cROUNDS; ++i) { |
125 | 69.5k | SIPROUND; |
126 | 69.5k | } |
127 | | |
128 | 34.7k | v0 ^= b; |
129 | | |
130 | 34.7k | v2 ^= 0xff; |
131 | | |
132 | 173k | for (i = 0; i < dROUNDS; ++i) { |
133 | 139k | SIPROUND; |
134 | 139k | } |
135 | | |
136 | 34.7k | b = v0 ^ v1 ^ v2 ^ v3; |
137 | 34.7k | U64TO8_LE((zip_uint8_t *)&out, b); |
138 | | |
139 | 34.7k | return out; |
140 | 34.7k | } |