10namespace morph::net::detail {
13inline std::uint32_t rotl(std::uint32_t value,
int bits) {
return (value << bits) | (value >> (32 - bits)); }
23inline std::array<std::uint8_t, 20> sha1Digest(std::string_view message) {
24 std::uint32_t h0 = 0x67452301;
25 std::uint32_t h1 = 0xEFCDAB89;
26 std::uint32_t h2 = 0x98BADCFE;
27 std::uint32_t h3 = 0x10325476;
28 std::uint32_t h4 = 0xC3D2E1F0;
33 std::uint64_t
const bitLen = std::uint64_t{message.size()} * 8U;
34 std::vector<std::uint8_t> data(message.begin(), message.end());
35 data.push_back(std::uint8_t{0x80});
36 while (data.size() % 64 != 56) {
37 data.push_back(std::uint8_t{0x00});
39 for (
int shift = 56; shift >= 0; shift -= 8) {
40 data.push_back(
static_cast<std::uint8_t
>((bitLen >> shift) & 0xFFu));
43 for (std::size_t chunkStart = 0; chunkStart < data.size(); chunkStart += 64) {
44 std::array<std::uint32_t, 80> w{};
45 for (
int i = 0; i < 16; ++i) {
46 std::size_t
const base = chunkStart +
static_cast<std::size_t
>(i) * 4;
47 w[
static_cast<std::size_t
>(i)] =
48 (
static_cast<std::uint32_t
>(data[base]) << 24) | (
static_cast<std::uint32_t
>(data[base + 1]) << 16) |
49 (
static_cast<std::uint32_t
>(data[base + 2]) << 8) |
static_cast<std::uint32_t
>(data[base + 3]);
51 for (
int i = 16; i < 80; ++i) {
52 w[
static_cast<std::size_t
>(i)] =
53 sha1_impl::rotl(w[
static_cast<std::size_t
>(i - 3)] ^ w[
static_cast<std::size_t
>(i - 8)] ^
54 w[
static_cast<std::size_t
>(i - 14)] ^ w[
static_cast<std::size_t
>(i - 16)],
63 for (
int i = 0; i < 80; ++i) {
67 f = (b & c) | ((~b) & d);
73 f = (b & c) | (b & d) | (c & d);
79 std::uint32_t
const temp = sha1_impl::rotl(a, 5) + f + e + k + w[
static_cast<std::size_t
>(i)];
82 c = sha1_impl::rotl(b, 30);
93 std::array<std::uint8_t, 20> digest{};
94 std::array<std::uint32_t, 5>
const hs{h0, h1, h2, h3, h4};
95 for (std::size_t i = 0; i < 5; ++i) {
96 digest[(i * 4) + 0] =
static_cast<std::uint8_t
>((hs[i] >> 24) & 0xFFu);
97 digest[(i * 4) + 1] =
static_cast<std::uint8_t
>((hs[i] >> 16) & 0xFFu);
98 digest[(i * 4) + 2] =
static_cast<std::uint8_t
>((hs[i] >> 8) & 0xFFu);
99 digest[(i * 4) + 3] =
static_cast<std::uint8_t
>(hs[i] & 0xFFu);