109 static_assert(Bits % 8 == 0);
110 static constexpr size_t nr_rounds = (
sizeof(T) == 4) ? 64 : 80;
111 static constexpr size_t pad_length_of_length = (
sizeof(T) == 4) ? 8 : 16;
115 using byteptr = std::byte *;
116 using cbyteptr = std::byte
const *;
121 typename overflow_type::iterator overflow_it;
125 [[nodiscard]]
static constexpr T K(
size_t i)
noexcept {
127 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
128 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
129 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
130 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
131 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
132 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
133 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
134 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
138 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538,
139 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe,
140 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
141 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
142 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab,
143 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
144 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed,
145 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
146 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
147 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
148 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373,
149 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
150 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c,
151 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6,
152 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
153 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
156 if constexpr (std::is_same_v<T,uint32_t>) {
163 [[nodiscard]]
static constexpr T Maj(T x, T y, T z)
noexcept {
164 return (x & y) ^ (x & z) ^ (y & z);
167 [[nodiscard]]
static constexpr T Ch(T x, T y, T z)
noexcept {
168 return (x & y) ^ (~x & z);
171 template<
int A,
int B,
int C>
172 [[nodiscard]]
static constexpr T S(T x)
noexcept {
173 return std::rotr(x, A) ^ std::rotr(x, B) ^ std::rotr(x, C);
176 template<
int A,
int B,
int C>
177 [[nodiscard]]
static constexpr T s(T x)
noexcept {
178 return std::rotr(x, A) ^ std::rotr(x, B) ^ x >> C;
181 [[nodiscard]]
static constexpr T S0(T x)
noexcept {
182 if constexpr (std::is_same_v<T,uint32_t>) {
183 return S<2,13,22>(x);
185 return S<28,34,39>(x);
189 [[nodiscard]]
static constexpr T S1(T x) {
190 if constexpr (std::is_same_v<T,uint32_t>) {
191 return S<6,11,25>(x);
193 return S<14,18,41>(x);
197 [[nodiscard]]
static constexpr T s0(T x) {
198 if constexpr (std::is_same_v<T,uint32_t>) {
205 [[nodiscard]]
static constexpr T s1(T x) {
206 if constexpr (std::is_same_v<T,uint32_t>) {
207 return s<17,19,10>(x);
209 return s<19,61,6>(x);
218 Ch(tmp.e, tmp.f, tmp.g) +
224 Maj(tmp.a, tmp.b, tmp.c);
241 for (
size_t i = 0; i != 16; ++i) {
242 tmp = round(tmp, K(i), W[i]);
245 for (
size_t i = 16; i != nr_rounds; ++i) {
246 ttlet W_ = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
248 tmp = round(tmp, K(i), W_);
255 constexpr void add_to_overflow(cbyteptr &ptr, std::byte
const *last)
noexcept {
256 while (overflow_it != overflow.
end() && ptr != last) {
257 *(overflow_it++) = *(ptr++);
261 constexpr void pad()
noexcept {
262 tt_axiom(overflow_it != overflow.
end());
265 *(overflow_it++) = std::byte{0x80};
269 ttlet overflow_left = overflow.
end() - overflow_it;
270 if (overflow_left < pad_length_of_length) {
271 while (overflow_it != overflow.
end()) {
272 *(overflow_it++) = std::byte{0x00};
275 overflow_it = overflow.
begin();
279 ttlet overflow_length_start = overflow.
end() - pad_length_of_length;
280 while (overflow_it != overflow_length_start) {
281 *(overflow_it++) = std::byte{0x00};
284 size_t nr_of_bits = size * 8;
285 for (
int i = pad_length_of_length - 1; i >= 0; --i) {
286 *(overflow_it++) = i <
sizeof(nr_of_bits) ?
static_cast<std::byte
>(nr_of_bits >> i * 8) : std::byte{0x00};
294 constexpr SHA2(T a, T b, T c, T d, T e, T f, T g, T h) noexcept :
295 state(a, b, c, d, e, f, g, h),
297 overflow_it(overflow.
begin()),
300 constexpr SHA2 &add(std::byte
const *ptr, std::byte
const *last,
bool finish=
true)
noexcept {
303 if (overflow_it != overflow.
begin()) {
304 add_to_overflow(ptr, last);
306 if (overflow_it == overflow.
end()) {
308 overflow_it = overflow.
begin();
318 while (ptr + block_type::size <= last) {
320 ptr += block_type::size;
323 add_to_overflow(ptr, last);
331 constexpr SHA2 &add(
bstring const &str,
bool finish=
true)
noexcept {
332 ttlet first = str.
data();
333 ttlet last = first + str.
size();
334 return add(first, last, finish);
337 constexpr SHA2 &add(bstring_view str,
bool finish=
true)
noexcept {
338 ttlet first = str.
data();
339 ttlet last = first + str.
size();
340 return add(first, last, finish);
343 constexpr SHA2 &add(
std::string const &str,
bool finish=
true)
noexcept {
344 ttlet first =
reinterpret_cast<std::byte
const *
>(str.
data());
345 ttlet last = first + str.
size();
346 return add(first, last, finish);
349 constexpr SHA2 &add(std::string_view str,
bool finish=
true)
noexcept {
350 ttlet first =
reinterpret_cast<std::byte
const *
>(str.
data());
351 ttlet last = first + str.
size();
352 return add(first, last, finish);
355 constexpr void add(std::span<std::byte const> str,
bool finish=
true)
noexcept {
356 ttlet first =
reinterpret_cast<std::byte
const *
>(str.
data());
357 ttlet last = first + str.
size();
358 add(first, last, finish);
361 [[nodiscard]]
bstring get_bytes()
const noexcept {
362 return state.template get_bytes<Bits / 8>();