dice-hash
Hash function for stl types and container
Loading...
Searching...
No Matches
Blake3.hpp
1#ifndef DICE_HASH_BLAKE3_HPP
2#define DICE_HASH_BLAKE3_HPP
3
4#include <algorithm>
5#include <cstddef>
6#include <span>
7#include <limits>
8#include <random>
9
10#include <blake3.h>
11
12namespace dice::hash::blake3 {
13
14 inline constexpr size_t dynamic_output_extent = std::dynamic_extent;
15 inline constexpr size_t min_key_extent = BLAKE3_KEY_LEN;
16 inline constexpr size_t max_key_extent = BLAKE3_KEY_LEN;
17 inline constexpr size_t default_key_extent = BLAKE3_KEY_LEN;
18
22 inline void generate_key(std::span<std::byte, default_key_extent> key_out) {
23 using byte_utype = std::underlying_type_t<std::byte>;
24
25 std::random_device rng;
26 std::uniform_int_distribution<byte_utype> dist{std::numeric_limits<byte_utype>::min(), std::numeric_limits<byte_utype>::max()};
27
28 std::generate(key_out.begin(), key_out.end(), [&]() {
29 return static_cast<std::byte>(dist(rng));
30 });
31 }
32
33 template<size_t OutputExtent = dynamic_output_extent>
34 struct Blake3 {
38 static constexpr size_t output_extent = OutputExtent;
39
40 static constexpr size_t min_key_extent = ::dice::hash::blake3::min_key_extent;
41 static constexpr size_t max_key_extent = ::dice::hash::blake3::max_key_extent;
42 static constexpr size_t default_key_extent = ::dice::hash::blake3::default_key_extent;
43
44 private:
45 blake3_hasher state_;
46
47 public:
48 Blake3() noexcept {
49 blake3_hasher_init(&state_);
50 }
51
56 explicit Blake3(std::span<std::byte const, default_key_extent> key) noexcept {
57 blake3_hasher_init_keyed(&state_, reinterpret_cast<uint8_t const *>(key.data()));
58 }
59
63 void digest(std::span<std::byte const> data) noexcept {
64 blake3_hasher_update(&state_, data.data(), data.size());
65 }
66
72 void finish(std::span<std::byte, output_extent> out) && noexcept {
73 blake3_hasher_finalize(&state_, reinterpret_cast<uint8_t *>(out.data()), out.size());
74 }
75
79 static void hash_single(std::span<std::byte const> data,
80 std::span<std::byte, output_extent> out) noexcept {
81 Blake3 blake;
82 blake.digest(data);
83 std::move(blake).finish(out);
84 }
85
89 static void hash_single(std::span<std::byte const> data,
90 std::span<std::byte, output_extent> out,
91 std::span<std::byte const, default_key_extent> key) noexcept {
92 Blake3 blake{key};
93 blake.digest(data);
94 std::move(blake).finish(out);
95 }
96 };
97
98} // namespace dice::hash::blake3
99
100#endif//DICE_HASH_BLAKE3_HPP
Definition Blake3.hpp:34
void digest(std::span< std::byte const > data) noexcept
digests data into the underlying BLAKE2Xb state
Definition Blake3.hpp:63
Blake3(std::span< std::byte const, default_key_extent > key) noexcept
Construct a BLAKE3 instance.
Definition Blake3.hpp:56
static constexpr size_t output_extent
if known at compile time, the size of the resulting hash, otherwise dynamic_output_extent
Definition Blake3.hpp:38
void finish(std::span< std::byte, output_extent > out) &&noexcept
produces the hash corresponding to the previously digested bytes
Definition Blake3.hpp:72
static void hash_single(std::span< std::byte const > data, std::span< std::byte, output_extent > out, std::span< std::byte const, default_key_extent > key) noexcept
convenience function to hash a single byte-span
Definition Blake3.hpp:89
static void hash_single(std::span< std::byte const > data, std::span< std::byte, output_extent > out) noexcept
convenience function to hash a single byte-span
Definition Blake3.hpp:79