123 static_assert(Bits % 8 == 0);
124 static constexpr std::size_t nr_rounds = (
sizeof(T) == 4) ? 64 : 80;
125 static constexpr std::size_t pad_length_of_length = (
sizeof(T) == 4) ? 8 : 16;
129 using byteptr = std::byte *;
130 using cbyteptr = std::byte
const *;
135 typename overflow_type::iterator overflow_it;
139 [[nodiscard]]
static constexpr T K(
std::size_t i)
noexcept
142 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
143 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
144 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
145 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
146 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
147 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
148 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
149 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
152 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538,
153 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe,
154 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
155 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
156 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab,
157 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
158 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed,
159 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
160 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
161 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
162 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373,
163 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
164 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c,
165 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6,
166 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
167 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817};
169 if constexpr (std::is_same_v<T, uint32_t>) {
176 [[nodiscard]]
static constexpr T Maj(T x, T y, T z)
noexcept
178 return (x & y) ^ (x & z) ^ (y & z);
181 [[nodiscard]]
static constexpr T Ch(T x, T y, T z)
noexcept
183 return (x & y) ^ (~x & z);
186 template<
int A,
int B,
int C>
187 [[nodiscard]]
static constexpr T S(T x)
noexcept
189 return std::rotr(x, A) ^ std::rotr(x, B) ^ std::rotr(x, C);
192 template<
int A,
int B,
int C>
193 [[nodiscard]]
static constexpr T s(T x)
noexcept
195 return std::rotr(x, A) ^ std::rotr(x, B) ^ x >> C;
198 [[nodiscard]]
static constexpr T S0(T x)
noexcept
200 if constexpr (std::is_same_v<T, uint32_t>) {
201 return S<2, 13, 22>(x);
203 return S<28, 34, 39>(x);
207 [[nodiscard]]
static constexpr T S1(T x)
209 if constexpr (std::is_same_v<T, uint32_t>) {
210 return S<6, 11, 25>(x);
212 return S<14, 18, 41>(x);
216 [[nodiscard]]
static constexpr T s0(T x)
218 if constexpr (std::is_same_v<T, uint32_t>) {
219 return s<7, 18, 3>(x);
221 return s<1, 8, 7>(x);
225 [[nodiscard]]
static constexpr T s1(T x)
227 if constexpr (std::is_same_v<T, uint32_t>) {
228 return s<17, 19, 10>(x);
230 return s<19, 61, 6>(x);
236 hilet T1 = tmp.h + S1(tmp.e) + Ch(tmp.e, tmp.f, tmp.g) + K + W;
238 hilet T2 = S0(tmp.a) + Maj(tmp.a, tmp.b, tmp.c);
240 return {T1 + T2, tmp.a, tmp.b, tmp.c, tmp.d + T1, tmp.e, tmp.f, tmp.g};
247 tmp = round(tmp, K(i), W[i]);
251 hilet W_ = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
253 tmp = round(tmp, K(i), W_);
260 constexpr void add_to_overflow(cbyteptr &ptr, std::byte
const *last)
noexcept
265 while (overflow_it != overflow.
end() && ptr != last) {
266 *(overflow_it++) = *(ptr++);
270 constexpr void pad()
noexcept
275 *(overflow_it++) = std::byte{0x80};
279 hilet overflow_left = overflow.
end() - overflow_it;
280 if (overflow_left < pad_length_of_length) {
281 while (overflow_it != overflow.
end()) {
282 *(overflow_it++) = std::byte{0x00};
285 overflow_it = overflow.
begin();
289 hilet overflow_length_start = overflow.
end() - pad_length_of_length;
290 while (overflow_it != overflow_length_start) {
291 *(overflow_it++) = std::byte{0x00};
295 for (
int i = pad_length_of_length - 1; i >= 0; --i) {
296 *(overflow_it++) = i <
sizeof(nr_of_bits) ?
static_cast<std::byte
>(nr_of_bits >> i * 8) : std::byte{0x00};
304 constexpr SHA2(T a, T b, T
c, T d, T e, T f, T g, T h) noexcept :
305 state(a, b,
c, d, e, f, g, h), overflow(), overflow_it(overflow.
begin()), size(0)
309 constexpr SHA2 &add(std::byte
const *ptr, std::byte
const *last,
bool finish =
true)
noexcept
313 if (overflow_it != overflow.
begin()) {
314 add_to_overflow(ptr, last);
316 if (overflow_it == overflow.
end()) {
318 overflow_it = overflow.
begin();
328 while (ptr + block_type::size <= last) {
330 ptr += block_type::size;
333 add_to_overflow(ptr, last);
341 constexpr SHA2 &add(
bstring const &str,
bool finish =
true)
noexcept
345 return add(first, last, finish);
348 constexpr SHA2 &add(bstring_view str,
bool finish =
true)
noexcept
352 return add(first, last, finish);
355 constexpr SHA2 &add(
std::string const &str,
bool finish =
true)
noexcept
357 hilet first =
reinterpret_cast<std::byte
const *
>(str.
data());
359 return add(first, last, finish);
362 constexpr SHA2 &add(std::string_view str,
bool finish =
true)
noexcept
364 hilet first =
reinterpret_cast<std::byte
const *
>(str.
data());
366 return add(first, last, finish);
369 constexpr void add(std::span<std::byte const> str,
bool finish =
true)
noexcept
371 hilet first =
reinterpret_cast<std::byte
const *
>(str.
data());
373 add(first, last, finish);
376 [[nodiscard]]
bstring get_bytes()
const noexcept
378 return state.template get_bytes<Bits / 8>();