39 sip_hash(detail::sip_hash_seed.k0, detail::sip_hash_seed.k1)
47 constexpr sip_hash(uint64_t k0, uint64_t k1) noexcept :
48 _v0(k0 ^ 0x736f6d6570736575),
49 _v1(k1 ^ 0x646f72616e646f6d),
50 _v2(k0 ^ 0x6c7967656e657261),
51 _v3(k1 ^ 0x7465646279746573),
55#if HI_BUILT_TYPE == HI_BT_DEBUG
56 _debug_state = debug_state_type::idle;
60 [[nodiscard]] uint64_t finish()
noexcept
62#if HI_BUILT_TYPE == HI_BT_DEBUG
63 hi_axiom(_debug_state < debug_state_type::finalized);
64 _debug_state = debug_state_type::finalized;
75 m |=
static_cast<uint64_t
>(b) << 56;
76 _compress(v0, v1, v2, v3, m);
77 _finalize(v0, v1, v2, v3);
79 return v0 ^ v1 ^ v2 ^ v3;
82 void add(
void const *data,
size_t size)
noexcept
84#if HI_BUILT_TYPE == HI_BT_DEBUG
85 hi_axiom(_debug_state <= debug_state_type::partial);
86 _debug_state = debug_state_type::partial;
89 auto *src =
reinterpret_cast<char const *
>(data);
98 if (
hilet offset = _b & 7) {
100 unaligned_load_le(m, src, num_bytes, offset);
102 if (offset + num_bytes == 8) {
103 _compress(v0, v1, v2, v3, std::exchange(m, 0));
112 m = load_le<uint64_t>(src);
115 _compress(v0, v1, v2, v3, std::exchange(m, 0));
120 unaligned_load_le(m, src, todo);
128 _b =
static_cast<uint8_t
>(_b + size);
142 auto *src =
reinterpret_cast<char const *
>(data);
144#if HI_BUILT_TYPE == HI_BT_DEBUG
145 hi_axiom(_debug_state == debug_state_type::idle);
154 for (
auto block_count = size / 8; block_count > 0; --block_count, src += 8) {
155 m = load_le<uint64_t>(src);
156 _compress(v0, v1, v2, v3, m);
160 m = wide_cast<uint64_t>(size & 0xff) << 56;
161 unaligned_load_le(m, src, size & 7);
162 _compress(v0, v1, v2, v3, m);
163 _finalize(v0, v1, v2, v3);
165 return v0 ^ v1 ^ v2 ^ v3;
172 [[nodiscard]] uint64_t
operator()(
void const *data,
size_t size)
const noexcept
174 return complete_message(data, size);
185#if HI_BUILT_TYPE == HI_BT_DEBUG
186 enum class debug_state_type : uint8_t { idle, full, partial, finalized };
187 state_type _debug_state;
190 hi_force_inline
static constexpr void _round(uint64_t& v0, uint64_t& v1, uint64_t& v2, uint64_t& v3)
noexcept
194 v1 = std::rotl(v1, 13);
195 v3 = std::rotl(v3, 16);
198 v0 = std::rotl(v0, 32);
202 v1 = std::rotl(v1, 17);
203 v3 = std::rotl(v3, 21);
206 v2 = std::rotl(v2, 32);
209 static constexpr void _compress(uint64_t& v0, uint64_t& v1, uint64_t& v2, uint64_t& v3, uint64_t m)
noexcept
214 for (
auto i = 0_uz; i != C; ++i) {
215 _round(v0, v1, v2, v3);
220 static constexpr void _finalize(uint64_t& v0, uint64_t& v1, uint64_t& v2, uint64_t& v3)
noexcept
223 for (
auto i = 0_uz; i != D; ++i) {
224 _round(v0, v1, v2, v3);