1 // Copyright (c) Microsoft Corporation. All rights reserved. 2 // Licensed under the MIT license. 3 4 #pragma once 5 6 #include "kuku/common.h" 7 #ifdef _MSC_VER 8 # pragma warning(push) 9 # pragma warning(disable: 4804) 10 #endif 11 #include "kuku/internal/blake2.h" 12 #ifdef _MSC_VER 13 # pragma warning(pop) 14 #endif 15 #include <array> 16 #include <cstdint> 17 #include <cstddef> 18 #include <stdexcept> 19 20 namespace kuku 21 { 22 class HashFunc 23 { 24 public: HashFunc(item_type seed)25 HashFunc(item_type seed) 26 { 27 if (blake2xb( 28 random_array_.data(), 29 random_array_size_ * sizeof(location_type), 30 seed.data(), 31 sizeof(seed), 32 nullptr, 0) != 0) 33 { 34 throw std::runtime_error("blake2xb failed"); 35 } 36 } 37 operator()38 inline location_type operator ()(item_type item) const noexcept 39 { 40 return 41 random_array_[0 * block_value_count_ + static_cast<std::size_t>(item[0])] ^ 42 random_array_[1 * block_value_count_ + static_cast<std::size_t>(item[1])] ^ 43 random_array_[2 * block_value_count_ + static_cast<std::size_t>(item[2])] ^ 44 random_array_[3 * block_value_count_ + static_cast<std::size_t>(item[3])] ^ 45 random_array_[4 * block_value_count_ + static_cast<std::size_t>(item[4])] ^ 46 random_array_[5 * block_value_count_ + static_cast<std::size_t>(item[5])] ^ 47 random_array_[6 * block_value_count_ + static_cast<std::size_t>(item[6])] ^ 48 random_array_[7 * block_value_count_ + static_cast<std::size_t>(item[7])] ^ 49 random_array_[8 * block_value_count_ + static_cast<std::size_t>(item[8])] ^ 50 random_array_[9 * block_value_count_ + static_cast<std::size_t>(item[9])] ^ 51 random_array_[10 * block_value_count_ + static_cast<std::size_t>(item[10])] ^ 52 random_array_[11 * block_value_count_ + static_cast<std::size_t>(item[11])] ^ 53 random_array_[12 * block_value_count_ + static_cast<std::size_t>(item[12])] ^ 54 random_array_[13 * block_value_count_ + static_cast<std::size_t>(item[13])] ^ 55 random_array_[14 * block_value_count_ + static_cast<std::size_t>(item[14])] ^ 56 random_array_[15 * block_value_count_ + static_cast<std::size_t>(item[15])]; 57 } 58 59 private: 60 static constexpr std::size_t block_size_ = 1; 61 62 static constexpr std::size_t block_count_ = sizeof(item_type); 63 64 static constexpr std::size_t block_value_count_ = (std::size_t(1) << (8 * block_size_)); 65 66 static constexpr std::size_t random_array_size_ = block_value_count_ * block_count_; 67 68 static constexpr std::uint32_t block_mask_ = 69 static_cast<std::uint32_t>(block_value_count_ - 1); 70 71 std::array<location_type, random_array_size_> random_array_; 72 }; 73 } 74