]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/siphash24.c
2 SipHash reference C implementation
5 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
6 Daniel J. Bernstein <djb@cr.yp.to>
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.
12 You should have received a copy of the CC0 Public Domain Dedication along with
13 this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
15 (Minimal changes made by Lennart Poettering, to make clean for inclusion in systemd)
16 (Refactored by Tom Gundersen to split up in several functions and follow systemd
23 #include "siphash24.h"
24 #include "unaligned.h"
26 static inline uint64_t rotate_left(uint64_t x
, uint8_t b
) {
29 return (x
<< b
) | (x
>> (64 - b
));
32 static inline void sipround(struct siphash
*state
) {
35 state
->v0
+= state
->v1
;
36 state
->v1
= rotate_left(state
->v1
, 13);
37 state
->v1
^= state
->v0
;
38 state
->v0
= rotate_left(state
->v0
, 32);
39 state
->v2
+= state
->v3
;
40 state
->v3
= rotate_left(state
->v3
, 16);
41 state
->v3
^= state
->v2
;
42 state
->v0
+= state
->v3
;
43 state
->v3
= rotate_left(state
->v3
, 21);
44 state
->v3
^= state
->v0
;
45 state
->v2
+= state
->v1
;
46 state
->v1
= rotate_left(state
->v1
, 17);
47 state
->v1
^= state
->v2
;
48 state
->v2
= rotate_left(state
->v2
, 32);
51 void siphash24_init(struct siphash
*state
, const uint8_t k
[16]) {
57 k0
= unaligned_read_le64(k
);
58 k1
= unaligned_read_le64(k
+ 8);
60 *state
= (struct siphash
) {
61 /* "somepseudorandomlygeneratedbytes" */
62 .v0
= 0x736f6d6570736575ULL
^ k0
,
63 .v1
= 0x646f72616e646f6dULL
^ k1
,
64 .v2
= 0x6c7967656e657261ULL
^ k0
,
65 .v3
= 0x7465646279746573ULL
^ k1
,
71 void siphash24_compress(const void *_in
, size_t inlen
, struct siphash
*state
) {
73 const uint8_t *in
= _in
;
74 const uint8_t *end
= in
+ inlen
;
75 size_t left
= state
->inlen
& 7;
81 /* Update total length */
82 state
->inlen
+= inlen
;
84 /* If padding exists, fill it out */
86 for ( ; in
< end
&& left
< 8; in
++, left
++)
87 state
->padding
|= ((uint64_t) *in
) << (left
* 8);
89 if (in
== end
&& left
< 8)
90 /* We did not have enough input to fill out the padding completely */
94 printf("(%3zu) v0 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v0
>> 32), (uint32_t) state
->v0
);
95 printf("(%3zu) v1 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v1
>> 32), (uint32_t) state
->v1
);
96 printf("(%3zu) v2 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v2
>> 32), (uint32_t) state
->v2
);
97 printf("(%3zu) v3 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v3
>> 32), (uint32_t) state
->v3
);
98 printf("(%3zu) compress padding %08x %08x\n", state
->inlen
, (uint32_t) (state
->padding
>> 32), (uint32_t)state
->padding
);
101 state
->v3
^= state
->padding
;
104 state
->v0
^= state
->padding
;
109 end
-= (state
->inlen
% sizeof(uint64_t));
111 for ( ; in
< end
; in
+= 8) {
112 m
= unaligned_read_le64(in
);
114 printf("(%3zu) v0 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v0
>> 32), (uint32_t) state
->v0
);
115 printf("(%3zu) v1 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v1
>> 32), (uint32_t) state
->v1
);
116 printf("(%3zu) v2 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v2
>> 32), (uint32_t) state
->v2
);
117 printf("(%3zu) v3 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v3
>> 32), (uint32_t) state
->v3
);
118 printf("(%3zu) compress %08x %08x\n", state
->inlen
, (uint32_t) (m
>> 32), (uint32_t) m
);
126 left
= state
->inlen
& 7;
129 state
->padding
|= ((uint64_t) in
[6]) << 48;
131 state
->padding
|= ((uint64_t) in
[5]) << 40;
133 state
->padding
|= ((uint64_t) in
[4]) << 32;
135 state
->padding
|= ((uint64_t) in
[3]) << 24;
137 state
->padding
|= ((uint64_t) in
[2]) << 16;
139 state
->padding
|= ((uint64_t) in
[1]) << 8;
141 state
->padding
|= ((uint64_t) in
[0]);
147 uint64_t siphash24_finalize(struct siphash
*state
) {
152 b
= state
->padding
| (((uint64_t) state
->inlen
) << 56);
155 printf("(%3zu) v0 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v0
>> 32), (uint32_t) state
->v0
);
156 printf("(%3zu) v1 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v1
>> 32), (uint32_t) state
->v1
);
157 printf("(%3zu) v2 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v2
>> 32), (uint32_t) state
->v2
);
158 printf("(%3zu) v3 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v3
>> 32), (uint32_t) state
->v3
);
159 printf("(%3zu) padding %08x %08x\n", state
->inlen
, (uint32_t) (state
->padding
>> 32), (uint32_t) state
->padding
);
168 printf("(%3zu) v0 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v0
>> 32), (uint32_t) state
->v0
);
169 printf("(%3zu) v1 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v1
>> 32), (uint32_t) state
->v1
);
170 printf("(%3zu) v2 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v2
>> 32), (uint32_t) state
->v2
);
171 printf("(%3zu) v3 %08x %08x\n", state
->inlen
, (uint32_t) (state
->v3
>> 32), (uint32_t) state
->v3
);
180 return state
->v0
^ state
->v1
^ state
->v2
^ state
->v3
;
183 uint64_t siphash24(const void *in
, size_t inlen
, const uint8_t k
[16]) {
184 struct siphash state
;
189 siphash24_init(&state
, k
);
190 siphash24_compress(in
, inlen
, &state
);
192 return siphash24_finalize(&state
);