26 static_assert(
Bits % 8 == 0);
27 constexpr static std::size_t nr_rounds = (
sizeof(T) == 4) ? 64 : 80;
28 constexpr static std::size_t pad_length_of_length = (
sizeof(T) == 4) ? 8 : 16;
40 constexpr state_type(T a, T b, T c, T d, T e, T f, T g, T h)
noexcept : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h) {}
68 hi_axiom(i < 8 *
sizeof(T));
72 return static_cast<std::byte
>(
word >> (
sizeof(T) - 1 -
byte_nr) * 8);
75 template<std::
size_t N>
76 [[
nodiscard]] bstring get_bytes()
const noexcept
87 constexpr state_type& operator+=(state_type
const& rhs)
noexcept
106 constexpr void set_byte(
std::size_t i, std::byte value)
noexcept
112 hilet
valueT =
static_cast<T
>(
static_cast<uint8_t
>(value));
116 constexpr block_type(std::byte
const *ptr)
noexcept : v()
119 set_byte(i, *(ptr++));
123 constexpr T
const& operator[](
std::size_t i)
const noexcept
134 using byteptr = std::byte *;
135 using cbyteptr = std::byte
const *;
139 overflow_type overflow;
140 typename overflow_type::iterator overflow_it;
147 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
148 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
149 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
150 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
151 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
152 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
153 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
154 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
157 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538,
158 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe,
159 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
160 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
161 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab,
162 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
163 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed,
164 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
165 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
166 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
167 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373,
168 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
169 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c,
170 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6,
171 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
172 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817};
174 if constexpr (std::is_same_v<T, uint32_t>) {
181 [[
nodiscard]]
constexpr static T Maj(T x, T y, T z)
noexcept
183 return (x & y) ^ (x & z) ^ (y & z);
186 [[
nodiscard]]
constexpr static T Ch(T x, T y, T z)
noexcept
188 return (x & y) ^ (
~x & z);
191 template<
int A,
int B,
int C>
192 [[
nodiscard]]
constexpr static T S(T x)
noexcept
194 return std::rotr(x, A) ^ std::rotr(x, B) ^ std::rotr(x, C);
197 template<
int A,
int B,
int C>
198 [[
nodiscard]]
constexpr static T s(T x)
noexcept
200 return std::rotr(x, A) ^ std::rotr(x, B) ^ x >> C;
203 [[
nodiscard]]
constexpr static T S0(T x)
noexcept
205 if constexpr (std::is_same_v<T, uint32_t>) {
214 if constexpr (std::is_same_v<T, uint32_t>) {
223 if constexpr (std::is_same_v<T, uint32_t>) {
232 if constexpr (std::is_same_v<T, uint32_t>) {
239 constexpr static state_type
round(state_type
const&
tmp, T K, T W)
noexcept
248 constexpr void add(block_type W)
noexcept
256 hilet
W_ = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
265 constexpr void add_to_overflow(cbyteptr& ptr, std::byte
const *last)
noexcept
267 hi_axiom_not_null(ptr);
268 hi_axiom_not_null(last);
270 while (overflow_it != overflow.end() && ptr != last) {
271 *(overflow_it++) = *(ptr++);
275 constexpr void pad()
noexcept
277 hi_axiom(overflow_it != overflow.end());
280 *(overflow_it++) = std::byte{0x80};
286 while (overflow_it != overflow.end()) {
287 *(overflow_it++) = std::byte{0x00};
289 add(block_type{overflow.data()});
290 overflow_it = overflow.begin();
296 *(overflow_it++) = std::byte{0x00};
300 for (
int i = pad_length_of_length - 1; i >= 0; --i) {
301 *(overflow_it++) = i <
sizeof(
nr_of_bits) ?
static_cast<std::byte
>(
nr_of_bits >> i * 8) : std::byte{0x00};
304 auto b = block_type{overflow.data()};
309 constexpr SHA2(T a, T b, T c, T d, T e, T f, T g, T h)
noexcept :
310 state(a, b, c, d, e, f, g, h), overflow(), overflow_it(overflow.begin()), size(0)
314 constexpr SHA2& add(std::byte
const *ptr, std::byte
const *last,
bool finish =
true)
noexcept
318 if (overflow_it != overflow.begin()) {
319 add_to_overflow(ptr, last);
321 if (overflow_it == overflow.end()) {
322 add(block_type{overflow.data()});
323 overflow_it = overflow.begin();
333 while (ptr + block_type::size <= last) {
334 add(block_type{ptr});
335 ptr += block_type::size;
338 add_to_overflow(ptr, last);
346 constexpr SHA2& add(bstring
const& str,
bool finish =
true)
noexcept
348 hilet first = str.data();
349 hilet last = first + str.size();
350 return add(first, last, finish);
353 constexpr SHA2& add(bstring_view str,
bool finish =
true)
noexcept
355 hilet first = str.data();
356 hilet last = first + str.size();
357 return add(first, last, finish);
360 constexpr SHA2& add(
std::string const& str,
bool finish =
true)
noexcept
362 hilet first =
reinterpret_cast<std::byte
const *
>(str.data());
363 hilet last = first + str.size();
364 return add(first, last, finish);
367 constexpr SHA2& add(std::string_view str,
bool finish =
true)
noexcept
369 hilet first =
reinterpret_cast<std::byte
const *
>(str.data());
370 hilet last = first + str.size();
371 return add(first, last, finish);
374 constexpr void add(std::span<std::byte const> str,
bool finish =
true)
noexcept
376 hilet first =
reinterpret_cast<std::byte
const *
>(str.data());
377 hilet last = first + str.size();
378 add(first, last, finish);
381 [[
nodiscard]] bstring get_bytes()
const noexcept
383 return state.template get_bytes<
Bits / 8>();