// SPDX-License-Identifier: LGPL-3.0-or-later #include "impl.h" #define rotl(v, x) (((v) << (x)) | ((v) >> (64 - (x)))) #define ROUND do { \ v0 += v1; \ v2 += v3; \ v1 = rotl(v1, 13); \ v3 = rotl(v3, 16); \ v1 ^= v0; \ v3 ^= v2; \ v0 = rotl(v0, 32); \ v2 += v1; \ v0 += v3; \ v1 = rotl(v1, 17); \ v3 = rotl(v3, 21); \ v1 ^= v2; \ v3 ^= v0; \ v2 = rotl(v2, 32); \ } while(0) uint64_t hkvs_hash(const char *hk, const char *data, size_t data_size) { uint64_t hk0 = hkvs_read_u64(hk + 0); uint64_t hk1 = hkvs_read_u64(hk + 8); uint64_t v0 = (uint64_t)0x736f6d6570736575 ^ hk0; uint64_t v1 = (uint64_t)0x646f72616e646f6d ^ hk1; uint64_t v2 = (uint64_t)0x6c7967656e657261 ^ hk0; uint64_t v3 = (uint64_t)0x7465646279746573 ^ hk1; uint64_t last = (uint64_t)data_size << 56; while(data_size >= 8) { uint64_t m = hkvs_read_u64(data); v3 ^= m; ROUND; v0 ^= m; data += 8; data_size -= 8; } switch(data_size) { case 7: last |= (uint64_t)(uint8_t)data[6] << 48; HKVS_FALLTHROUGH; case 6: last |= (uint64_t)(uint8_t)data[5] << 40; HKVS_FALLTHROUGH; case 5: last |= (uint64_t)(uint8_t)data[4] << 32; HKVS_FALLTHROUGH; case 4: last |= (uint64_t)(uint8_t)data[3] << 24; HKVS_FALLTHROUGH; case 3: last |= (uint64_t)(uint8_t)data[2] << 16; HKVS_FALLTHROUGH; case 2: last |= (uint64_t)(uint8_t)data[1] << 8; HKVS_FALLTHROUGH; case 1: last |= (uint64_t)(uint8_t)data[0]; HKVS_FALLTHROUGH; case 0: break; default: __builtin_unreachable(); } v3 ^= last; ROUND; v0 ^= last; v2 ^= 0xff; ROUND; ROUND; ROUND; return v0 ^ v1 ^ v2 ^ v3; }