119 static_assert(Bits % 8 == 0);
120 static constexpr std::size_t nr_rounds = (
sizeof(T) == 4) ? 64 : 80;
121 static constexpr std::size_t pad_length_of_length = (
sizeof(T) == 4) ? 8 : 16;
125 using byteptr = std::byte *;
126 using cbyteptr = std::byte
const *;
131 typename overflow_type::iterator overflow_it;
135 [[nodiscard]]
static constexpr T K(
std::size_t i)
noexcept
138 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
139 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
140 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
141 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
142 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
143 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
144 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
145 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
148 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538,
149 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe,
150 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
151 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
152 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab,
153 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
154 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed,
155 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
156 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
157 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
158 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373,
159 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
160 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c,
161 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6,
162 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
163 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817};
165 if constexpr (std::is_same_v<T, uint32_t>) {
172 [[nodiscard]]
static constexpr T Maj(T x, T y, T z)
noexcept
174 return (x & y) ^ (x & z) ^ (y & z);
177 [[nodiscard]]
static constexpr T Ch(T x, T y, T z)
noexcept
179 return (x & y) ^ (~x & z);
182 template<
int A,
int B,
int C>
183 [[nodiscard]]
static constexpr T S(T x)
noexcept
185 return std::rotr(x, A) ^ std::rotr(x, B) ^ std::rotr(x, C);
188 template<
int A,
int B,
int C>
189 [[nodiscard]]
static constexpr T s(T x)
noexcept
191 return std::rotr(x, A) ^ std::rotr(x, B) ^ x >> C;
194 [[nodiscard]]
static constexpr T S0(T x)
noexcept
196 if constexpr (std::is_same_v<T, uint32_t>) {
197 return S<2, 13, 22>(x);
199 return S<28, 34, 39>(x);
203 [[nodiscard]]
static constexpr T S1(T x)
205 if constexpr (std::is_same_v<T, uint32_t>) {
206 return S<6, 11, 25>(x);
208 return S<14, 18, 41>(x);
212 [[nodiscard]]
static constexpr T s0(T x)
214 if constexpr (std::is_same_v<T, uint32_t>) {
215 return s<7, 18, 3>(x);
217 return s<1, 8, 7>(x);
221 [[nodiscard]]
static constexpr T s1(T x)
223 if constexpr (std::is_same_v<T, uint32_t>) {
224 return s<17, 19, 10>(x);
226 return s<19, 61, 6>(x);
232 hilet T1 = tmp.h + S1(tmp.e) + Ch(tmp.e, tmp.f, tmp.g) + K + W;
234 hilet T2 = S0(tmp.a) + Maj(tmp.a, tmp.b, tmp.c);
236 return {T1 + T2, tmp.a, tmp.b, tmp.c, tmp.d + T1, tmp.e, tmp.f, tmp.g};
243 tmp = round(tmp, K(i), W[i]);
247 hilet W_ = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
249 tmp = round(tmp, K(i), W_);
256 constexpr void add_to_overflow(cbyteptr &ptr, std::byte
const *last)
noexcept
258 while (overflow_it != overflow.
end() && ptr != last) {
259 *(overflow_it++) = *(ptr++);
263 constexpr void pad()
noexcept
268 *(overflow_it++) = std::byte{0x80};
272 hilet overflow_left = overflow.
end() - overflow_it;
273 if (overflow_left < pad_length_of_length) {
274 while (overflow_it != overflow.
end()) {
275 *(overflow_it++) = std::byte{0x00};
278 overflow_it = overflow.
begin();
282 hilet overflow_length_start = overflow.
end() - pad_length_of_length;
283 while (overflow_it != overflow_length_start) {
284 *(overflow_it++) = std::byte{0x00};
288 for (
int i = pad_length_of_length - 1; i >= 0; --i) {
289 *(overflow_it++) = i <
sizeof(nr_of_bits) ?
static_cast<std::byte
>(nr_of_bits >> i * 8) : std::byte{0x00};
297 constexpr SHA2(T a, T b, T
c, T d, T e, T f, T g, T h) noexcept :
298 state(a, b,
c, d, e, f, g, h), overflow(), overflow_it(overflow.
begin()), size(0)
302 constexpr SHA2 &add(std::byte
const *ptr, std::byte
const *last,
bool finish =
true)
noexcept
306 if (overflow_it != overflow.
begin()) {
307 add_to_overflow(ptr, last);
309 if (overflow_it == overflow.
end()) {
311 overflow_it = overflow.
begin();
321 while (ptr + block_type::size <= last) {
323 ptr += block_type::size;
326 add_to_overflow(ptr, last);
334 constexpr SHA2 &add(
bstring const &str,
bool finish =
true)
noexcept
338 return add(first, last, finish);
341 constexpr SHA2 &add(bstring_view str,
bool finish =
true)
noexcept
345 return add(first, last, finish);
348 constexpr SHA2 &add(
std::string const &str,
bool finish =
true)
noexcept
350 hilet first =
reinterpret_cast<std::byte
const *
>(str.
data());
352 return add(first, last, finish);
355 constexpr SHA2 &add(std::string_view str,
bool finish =
true)
noexcept
357 hilet first =
reinterpret_cast<std::byte
const *
>(str.
data());
359 return add(first, last, finish);
362 constexpr void add(std::span<std::byte const> str,
bool finish =
true)
noexcept
364 hilet first =
reinterpret_cast<std::byte
const *
>(str.
data());
366 add(first, last, finish);
369 [[nodiscard]]
bstring get_bytes()
const noexcept
371 return state.template get_bytes<Bits / 8>();