1 /* Copyright (C) 2016 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
3 * This file is provided under a dual BSD/GPLv2 license.
5 * SipHash: a fast short-input PRF
6 * https://131002.net/siphash/
8 * This implementation is specifically for SipHash2-4 for a secure PRF
11 #include <libubox/utils.h>
14 static inline uint64_t rol64(uint64_t word
, unsigned int shift
)
16 return (word
<< (shift
& 63)) | (word
>> ((-shift
) & 63));
22 v0 += v1; v1 = rol64(v1, 13); v1 ^= v0; v0 = rol64(v0, 32); \
23 v2 += v3; v3 = rol64(v3, 16); v3 ^= v2; \
24 v0 += v3; v3 = rol64(v3, 21); v3 ^= v0; \
25 v2 += v1; v1 = rol64(v1, 17); v1 ^= v2; v2 = rol64(v2, 32); \
28 #define PREAMBLE(len) \
29 uint64_t v0 = 0x736f6d6570736575ULL; \
30 uint64_t v1 = 0x646f72616e646f6dULL; \
31 uint64_t v2 = 0x6c7967656e657261ULL; \
32 uint64_t v3 = 0x7465646279746573ULL; \
33 uint64_t b = ((uint64_t)(len)) << 56; \
49 return (v0 ^ v1) ^ (v2 ^ v3);
52 uint64_t siphash(const void *data
, size_t len
, const siphash_key_t
*key
)
54 const uint8_t *end
= data
+ len
- (len
% sizeof(uint64_t));
55 const uint8_t left
= len
& (sizeof(uint64_t) - 1);
58 for (; data
!= end
; data
+= sizeof(uint64_t)) {
59 m
= get_unaligned_le64(data
);
66 case 7: b
|= ((uint64_t)end
[6]) << 48; fallthrough
;
67 case 6: b
|= ((uint64_t)end
[5]) << 40; fallthrough
;
68 case 5: b
|= ((uint64_t)end
[4]) << 32; fallthrough
;
69 case 4: b
|= get_unaligned_le32(end
); break;
70 case 3: b
|= ((uint64_t)end
[2]) << 16; fallthrough
;
71 case 2: b
|= get_unaligned_le16(end
); break;