|
1 | 1 | /////////////////////////////////////////////////////////////////////////////// |
2 | | -// Copyright Christopher Kormanyos 2013 - 2025. |
| 2 | +// Copyright Christopher Kormanyos 2013 - 2026. |
3 | 3 | // Distributed under the Boost Software License, |
4 | 4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt |
5 | 5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) |
|
8 | 8 | #ifndef HASH_BASE_2013_09_05_H |
9 | 9 | #define HASH_BASE_2013_09_05_H |
10 | 10 |
|
11 | | - #include <limits> |
12 | | - |
13 | 11 | #include <math/checksums/hash/hash_detail.h> |
| 12 | + #include <math/checksums/hash/hash_stream_base.h> |
| 13 | + |
| 14 | + #include <array> |
| 15 | + #include <cstddef> |
| 16 | + #include <cstdint> |
| 17 | + #include <limits> |
14 | 18 |
|
15 | 19 | namespace math { namespace checksums { namespace hash { |
16 | 20 |
|
17 | | - template<typename CountType, |
18 | | - const std::uint16_t ResultBitCount, |
19 | | - const std::uint16_t MessageBufferSize, |
20 | | - const std::uint16_t MessageLengthTotalBitCount> |
21 | | - class hash_base |
| 21 | + template<const std::uint16_t ResultBitCount, |
| 22 | + const std::uint16_t MessageBlockBufferSize, |
| 23 | + const std::uint16_t MessageBlockBitCount> |
| 24 | + class hash_base : public hash_stream_base |
22 | 25 | { |
23 | | - public: |
24 | | - using count_type = CountType; |
| 26 | + private: |
| 27 | + using base_class_type = hash_stream_base; |
25 | 28 |
|
| 29 | + public: |
26 | 30 | using result_type = std::array<std::uint8_t, static_cast<std::size_t>(ResultBitCount / static_cast<std::uint16_t>(UINT8_C(8)))>; |
27 | 31 |
|
28 | 32 | static_assert |
29 | 33 | ( |
30 | | - std::numeric_limits<count_type>::is_specialized |
31 | | - && std::numeric_limits<count_type>::is_integer |
32 | | - && (!std::numeric_limits<count_type>::is_signed) |
33 | | - && (std::numeric_limits<count_type>::radix == static_cast<int>(INT8_C(2))) |
34 | | - && (std::numeric_limits<count_type>::digits >= static_cast<int>(INT8_C(16))) |
35 | | - && (static_cast<int>(std::numeric_limits<count_type>::digits % static_cast<int>(INT8_C(8))) == static_cast<int>(INT8_C(0))), |
36 | | - "Error: The count type must be an unsigned integer with radix 2, that is 16 bits or wider, and having a multiple of 8 bits" |
| 34 | + std::numeric_limits<base_class_type::count_type>::is_specialized |
| 35 | + && std::numeric_limits<base_class_type::count_type>::is_integer |
| 36 | + && (!std::numeric_limits<base_class_type::count_type>::is_signed) |
| 37 | + && (std::numeric_limits<base_class_type::count_type>::radix == static_cast<int>(INT8_C(2))) |
| 38 | + && (std::numeric_limits<base_class_type::count_type>::digits >= static_cast<int>(INT8_C(32))) |
| 39 | + && (static_cast<int>(std::numeric_limits<base_class_type::count_type>::digits % static_cast<int>(INT8_C(8))) == static_cast<int>(INT8_C(0))), |
| 40 | + "Error: The count type must be an unsigned integer with radix 2, that is 32 bits or wider, and having a multiple of 8 bits" |
37 | 41 | ); |
38 | 42 |
|
39 | | - virtual ~hash_base() = default; |
| 43 | + ~hash_base() override = default; |
40 | 44 |
|
41 | | - virtual auto initialize() -> void |
| 45 | + auto initialize() -> void override |
42 | 46 | { |
43 | | - message_index = static_cast<std::uint_least16_t>(UINT8_C(0)); |
| 47 | + message_index = static_cast<std::uint_least32_t>(UINT8_C(0)); |
44 | 48 | message_length_total = static_cast<count_type>(UINT8_C(0)); |
45 | 49 |
|
46 | 50 | message_buffer.fill(static_cast<std::uint8_t>(UINT8_C(0))); |
47 | 51 | } |
48 | 52 |
|
49 | | - auto process(const std::uint8_t* message, const count_type count) -> void |
| 53 | + auto process(const std::uint8_t* message, const count_type count) -> void override |
50 | 54 | { |
51 | 55 | auto process_index = count_type { }; |
52 | 56 | auto process_chunk_size = count_type { }; |
53 | 57 |
|
54 | 58 | while(process_index < count) |
55 | 59 | { |
56 | | - message_index = static_cast<std::uint_least16_t>(message_index + process_chunk_size); |
| 60 | + message_index = static_cast<std::uint_least32_t>(message_index + process_chunk_size); |
57 | 61 | message_length_total = static_cast<count_type> (message_length_total + process_chunk_size); |
58 | 62 | process_index = static_cast<count_type> (process_index + process_chunk_size); |
59 | 63 |
|
60 | 64 | if(message_index == message_buffer_static_size()) |
61 | 65 | { |
62 | | - my_perform_algorithm(); |
| 66 | + perform_algorithm(); |
63 | 67 | } |
64 | 68 |
|
65 | 69 | process_chunk_size = (std::min)(static_cast<count_type>(count - process_index), |
|
72 | 76 | } |
73 | 77 | } |
74 | 78 |
|
75 | | - auto finalize() -> void |
| 79 | + auto finalize() -> void override |
76 | 80 | { |
77 | 81 | // Create the padding. Begin by setting the leading padding byte to 0x80. |
78 | | - message_buffer[message_index] = static_cast<std::uint8_t>(UINT8_C(0x80)); |
| 82 | + message_buffer[static_cast<std::size_t>(message_index)] = static_cast<std::uint8_t>(UINT8_C(0x80)); |
79 | 83 |
|
80 | 84 | ++message_index; |
81 | 85 |
|
|
86 | 90 | const auto message_top = |
87 | 91 | static_cast<std::uint16_t> |
88 | 92 | ( |
89 | | - message_index + static_cast<std::uint_least16_t>(message_length_total_width()) |
| 93 | + message_index + static_cast<std::uint_least32_t>(message_length_total_width()) |
90 | 94 | ); |
91 | 95 |
|
92 | 96 | if(message_top > message_buffer_static_size()) |
93 | 97 | { |
94 | | - my_perform_algorithm(); |
| 98 | + perform_algorithm(); |
95 | 99 | } |
96 | 100 |
|
97 | 101 | // Encode the total number of bits in the final transform buffer. |
|
105 | 109 | ri != message_buffer.rbegin() + static_cast<std::size_t>(message_length_total_width()); |
106 | 110 | ++ri) |
107 | 111 | { |
108 | | - const std::uint_least16_t the_word = |
109 | | - static_cast<std::uint_least16_t> |
| 112 | + const std::uint_least32_t the_word = |
| 113 | + static_cast<std::uint_least32_t> |
110 | 114 | ( |
111 | | - static_cast<std::uint_least16_t>(message_length_total) << static_cast<unsigned>(UINT8_C(3)) |
| 115 | + static_cast<std::uint_least32_t>(message_length_total) << static_cast<unsigned>(UINT8_C(3)) |
112 | 116 | ); |
113 | 117 |
|
114 | 118 | *ri = static_cast<std::uint8_t>(the_word | carry); |
|
127 | 131 | ); |
128 | 132 | } |
129 | 133 |
|
130 | | - my_perform_algorithm(); |
| 134 | + perform_algorithm(); |
131 | 135 | } |
132 | 136 |
|
133 | 137 | auto get_result(typename result_type::pointer result) -> void |
|
149 | 153 | } |
150 | 154 |
|
151 | 155 | protected: |
152 | | - using message_block_type = std::array<std::uint8_t, static_cast<std::size_t>(MessageBufferSize)>; |
| 156 | + using message_block_type = std::array<std::uint8_t, static_cast<std::size_t>(MessageBlockBufferSize)>; |
153 | 157 |
|
154 | 158 | using context_type = std::array<std::uint32_t, static_cast<std::size_t>(std::tuple_size<result_type>::value / sizeof(std::uint32_t))>; |
155 | 159 |
|
|
158 | 162 | return static_cast<std::uint16_t>(std::tuple_size<message_block_type>::value); |
159 | 163 | } |
160 | 164 |
|
161 | | - std::uint_least16_t message_index { }; |
| 165 | + std::uint_least32_t message_index { }; |
162 | 166 | count_type message_length_total { }; |
163 | 167 | message_block_type message_buffer { }; |
164 | 168 | context_type transform_context { }; |
165 | 169 |
|
166 | 170 | hash_base() = default; |
167 | 171 |
|
168 | 172 | hash_base(const hash_base&) = default; |
169 | | - hash_base(hash_base&&) noexcept = default; |
| 173 | + hash_base(hash_base&&) = default; |
170 | 174 |
|
171 | 175 | auto operator=(const hash_base& other) -> hash_base& = default; |
172 | | - auto operator=(hash_base&& other) noexcept -> hash_base& = default; |
| 176 | + auto operator=(hash_base&& other) -> hash_base& = default; |
173 | 177 |
|
174 | 178 | private: |
175 | | - static constexpr auto message_length_total_width() noexcept -> std::uint16_t |
| 179 | + static constexpr auto message_length_total_width() -> std::uint16_t |
176 | 180 | { |
177 | 181 | return |
178 | 182 | static_cast<std::uint16_t> |
179 | 183 | ( |
180 | | - MessageLengthTotalBitCount / static_cast<std::uint16_t>(UINT8_C(8)) |
| 184 | + MessageBlockBitCount / static_cast<std::uint16_t>(UINT8_C(8)) |
181 | 185 | ); |
182 | 186 | } |
183 | 187 |
|
184 | | - virtual auto perform_algorithm() -> void = 0; |
| 188 | + virtual auto my_perform_algorithm() -> void = 0; |
185 | 189 |
|
186 | | - auto my_perform_algorithm() -> void |
| 190 | + auto perform_algorithm() -> void |
187 | 191 | { |
188 | | - this->perform_algorithm(); |
| 192 | + this->my_perform_algorithm(); |
189 | 193 |
|
190 | | - message_index = static_cast<std::uint_least16_t>(UINT8_C(0)); |
| 194 | + message_index = std::uint_least32_t { UINT8_C(0) }; |
191 | 195 |
|
192 | | - message_buffer.fill(static_cast<std::uint8_t>(UINT8_C(0))); |
| 196 | + message_buffer.fill(std::uint8_t { UINT8_C(0) }); |
193 | 197 | } |
194 | 198 | }; |
195 | 199 |
|
|
0 commit comments