/builds/xfbs/passgen/src/util/siphash.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | SipHash reference C implementation |
3 | | Copyright (c) 2012-2021 Jean-Philippe Aumasson |
4 | | <jeanphilippe.aumasson@gmail.com> |
5 | | Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to> |
6 | | To the extent possible under law, the author(s) have dedicated all copyright |
7 | | and related and neighboring rights to this software to the public domain |
8 | | worldwide. This software is distributed without any warranty. |
9 | | You should have received a copy of the CC0 Public Domain Dedication along |
10 | | with |
11 | | this software. If not, see |
12 | | <http://creativecommons.org/publicdomain/zero/1.0/>. |
13 | | */ |
14 | | |
15 | | #include "passgen/util/siphash.h" |
16 | | #include <assert.h> |
17 | | #include <stdint.h> |
18 | | #include <stdio.h> |
19 | | |
20 | | /* default: SipHash-2-4 */ |
21 | | #ifndef cROUNDS |
22 | 116k | #define cROUNDS 2 |
23 | | #endif |
24 | | #ifndef dROUNDS |
25 | 193k | #define dROUNDS 4 |
26 | | #endif |
27 | | |
28 | 1.39M | #define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) |
29 | | |
30 | | #define U32TO8_LE(p, v) \ |
31 | 77.3k | (p)[0] = (uint8_t) ((v)); \ |
32 | 77.3k | (p)[1] = (uint8_t) ((v) >> 8); \ |
33 | 77.3k | (p)[2] = (uint8_t) ((v) >> 16); \ |
34 | 77.3k | (p)[3] = (uint8_t) ((v) >> 24); |
35 | | |
36 | | #define U64TO8_LE(p, v) \ |
37 | 38.6k | U32TO8_LE((p), (uint32_t) ((v))); \ |
38 | 38.6k | U32TO8_LE((p) + 4, (uint32_t) ((v) >> 32)); |
39 | | |
40 | | #define U8TO64_LE(p) \ |
41 | 77.3k | (((uint64_t) ((p)[0])) | ((uint64_t) ((p)[1]) << 8) | \ |
42 | 77.3k | ((uint64_t) ((p)[2]) << 16) | ((uint64_t) ((p)[3]) << 24) | \ |
43 | 77.3k | ((uint64_t) ((p)[4]) << 32) | ((uint64_t) ((p)[5]) << 40) | \ |
44 | 77.3k | ((uint64_t) ((p)[6]) << 48) | ((uint64_t) ((p)[7]) << 56)) |
45 | | |
46 | | #define SIPROUND \ |
47 | 232k | do { \ |
48 | 232k | v0 += v1; \ |
49 | 232k | v1 = ROTL(v1, 13); \ |
50 | 232k | v1 ^= v0; \ |
51 | 232k | v0 = ROTL(v0, 32); \ |
52 | 232k | v2 += v3; \ |
53 | 232k | v3 = ROTL(v3, 16); \ |
54 | 232k | v3 ^= v2; \ |
55 | 232k | v0 += v3; \ |
56 | 232k | v3 = ROTL(v3, 21); \ |
57 | 232k | v3 ^= v0; \ |
58 | 232k | v2 += v1; \ |
59 | 232k | v1 = ROTL(v1, 17); \ |
60 | 232k | v1 ^= v2; \ |
61 | 232k | v2 = ROTL(v2, 32); \ |
62 | 232k | } while(0) |
63 | | |
64 | | #ifdef DEBUG |
65 | | #define TRACE \ |
66 | | do { \ |
67 | | printf("(%3zu) v0 %016" PRIx64 "\n", inlen, v0); \ |
68 | | printf("(%3zu) v1 %016" PRIx64 "\n", inlen, v1); \ |
69 | | printf("(%3zu) v2 %016" PRIx64 "\n", inlen, v2); \ |
70 | | printf("(%3zu) v3 %016" PRIx64 "\n", inlen, v3); \ |
71 | | } while(0) |
72 | | #else |
73 | | #define TRACE |
74 | | #endif |
75 | | |
76 | | int passgen_siphash( |
77 | | const void *in, |
78 | | const size_t inlen, |
79 | | const void *k, |
80 | | uint8_t *out, |
81 | 38.6k | const size_t outlen) { |
82 | 38.6k | const unsigned char *ni = (const unsigned char *) in; |
83 | 38.6k | const unsigned char *kk = (const unsigned char *) k; |
84 | 38.6k | |
85 | 38.6k | assert((outlen == 8) || (outlen == 16)); |
86 | 38.6k | uint64_t v0 = UINT64_C(0x736f6d6570736575); |
87 | 38.6k | uint64_t v1 = UINT64_C(0x646f72616e646f6d); |
88 | 38.6k | uint64_t v2 = UINT64_C(0x6c7967656e657261); |
89 | 38.6k | uint64_t v3 = UINT64_C(0x7465646279746573); |
90 | 38.6k | uint64_t k0 = U8TO64_LE(kk); |
91 | 38.6k | uint64_t k1 = U8TO64_LE(kk + 8); |
92 | 38.6k | uint64_t m; |
93 | 38.6k | int i; |
94 | 38.6k | const unsigned char *end = ni + inlen - (inlen % sizeof(uint64_t)); |
95 | 38.6k | const int left = inlen & 7; |
96 | 38.6k | uint64_t b = ((uint64_t) inlen) << 56; |
97 | 38.6k | v3 ^= k1; |
98 | 38.6k | v2 ^= k0; |
99 | 38.6k | v1 ^= k1; |
100 | 38.6k | v0 ^= k0; |
101 | 38.6k | |
102 | 38.6k | if(outlen == 16) v1 ^= 0xee8 ; |
103 | 38.6k | |
104 | 38.6k | for(; ni != end; ni += 82 ) { |
105 | 2 | m = U8TO64_LE(ni); |
106 | 2 | v3 ^= m; |
107 | 2 | |
108 | 2 | TRACE; |
109 | 6 | for(i = 0; i < cROUNDS; ++i4 ) SIPROUND4 ; |
110 | 2 | |
111 | 2 | v0 ^= m; |
112 | 2 | } |
113 | 38.6k | |
114 | 38.6k | switch(left) { |
115 | 5 | case 7: |
116 | 5 | b |= ((uint64_t) ni[6]) << 48; |
117 | 5 | // fall through |
118 | 5 | case 6: |
119 | 5 | b |= ((uint64_t) ni[5]) << 40; |
120 | 5 | // fall through |
121 | 57 | case 5: |
122 | 57 | b |= ((uint64_t) ni[4]) << 32; |
123 | 57 | // fall through |
124 | 29.2k | case 4: |
125 | 29.2k | b |= ((uint64_t) ni[3]) << 24; |
126 | 29.2k | // fall through |
127 | 37.0k | case 3: |
128 | 37.0k | b |= ((uint64_t) ni[2]) << 16; |
129 | 37.0k | // fall through |
130 | 38.4k | case 2: |
131 | 38.4k | b |= ((uint64_t) ni[1]) << 8; |
132 | 38.4k | // fall through |
133 | 38.6k | case 1: |
134 | 38.6k | b |= ((uint64_t) ni[0]); |
135 | 38.6k | break; |
136 | 38.4k | case 0: |
137 | 2 | break; |
138 | 38.6k | } |
139 | 38.6k | |
140 | 38.6k | v3 ^= b; |
141 | 38.6k | |
142 | 38.6k | TRACE; |
143 | 116k | for(i = 0; i < cROUNDS; ++i77.3k ) SIPROUND77.3k ; |
144 | 38.6k | |
145 | 38.6k | v0 ^= b; |
146 | 38.6k | |
147 | 38.6k | if(outlen == 16) |
148 | 8 | v2 ^= 0xee; |
149 | 38.6k | else |
150 | 38.6k | v2 ^= 0xff; |
151 | 38.6k | |
152 | 38.6k | TRACE; |
153 | 193k | for(i = 0; i < dROUNDS; ++i154k ) SIPROUND154k ; |
154 | 38.6k | |
155 | 38.6k | b = v0 ^ v1 ^ v2 ^ v3; |
156 | 38.6k | U64TO8_LE(out, b); |
157 | 38.6k | |
158 | 38.6k | if(outlen == 8) return 038.6k ; |
159 | 8 | |
160 | 8 | v1 ^= 0xdd; |
161 | 8 | |
162 | 8 | TRACE; |
163 | 40 | for(i = 0; i < dROUNDS; ++i32 ) SIPROUND32 ; |
164 | 8 | |
165 | 8 | b = v0 ^ v1 ^ v2 ^ v3; |
166 | 8 | U64TO8_LE(out + 8, b); |
167 | 8 | |
168 | 8 | return 0; |
169 | 8 | } |