5#ifndef LINE_UTIL_SHA256_H
6#define LINE_UTIL_SHA256_H
40static const std::uint32_t SHA256_K[64] = {
41 0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu, 0x59f111f1u, 0x923f82a4u,
42 0xab1c5ed5u, 0xd807aa98u, 0x12835b01u, 0x243185beu, 0x550c7dc3u, 0x72be5d74u, 0x80deb1feu,
43 0x9bdc06a7u, 0xc19bf174u, 0xe49b69c1u, 0xefbe4786u, 0x0fc19dc6u, 0x240ca1ccu, 0x2de92c6fu,
44 0x4a7484aau, 0x5cb0a9dcu, 0x76f988dau, 0x983e5152u, 0xa831c66du, 0xb00327c8u, 0xbf597fc7u,
45 0xc6e00bf3u, 0xd5a79147u, 0x06ca6351u, 0x14292967u, 0x27b70a85u, 0x2e1b2138u, 0x4d2c6dfcu,
46 0x53380d13u, 0x650a7354u, 0x766a0abbu, 0x81c2c92eu, 0x92722c85u, 0xa2bfe8a1u, 0xa81a664bu,
47 0xc24b8b70u, 0xc76c51a3u, 0xd192e819u, 0xd6990624u, 0xf40e3585u, 0x106aa070u, 0x19a4c116u,
48 0x1e376c08u, 0x2748774cu, 0x34b0bcb5u, 0x391c0cb3u, 0x4ed8aa4au, 0x5b9cca4fu, 0x682e6ff3u,
49 0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u, 0x90befffau, 0xa4506cebu, 0xbef9a3f7u,
52inline std::uint32_t sha256_ror(std::uint32_t x,
int n) {
return (x >> n) | (x << (32 - n)); }
82 void update(
const void* data, std::size_t n) {
83 const unsigned char* p =
static_cast<const unsigned char*
>(data);
84 total_ +=
static_cast<std::uint64_t
>(n);
86 const std::size_t room = 64 - len_;
87 const std::size_t take = n < room ? n : room;
88 for (std::size_t i = 0; i < take; ++i) buf_[len_ + i] = p[i];
103 const std::uint64_t bitlen = total_ * 8ull;
104 unsigned char pad = 0x80;
107 while (len_ != 56)
update(&pad, 1);
108 unsigned char tail[8];
109 for (
int i = 0; i < 8; ++i)
110 tail[i] =
static_cast<unsigned char>((bitlen >> ((7 - i) * 8)) & 0xFFu);
113 static const char*
const digits =
"0123456789abcdef";
116 for (
int i = 0; i < 8; ++i)
117 for (
int b = 3; b >= 0; --b) {
118 const unsigned char byte =
static_cast<unsigned char>((h_[i] >> (b * 8)) & 0xFFu);
119 out.push_back(digits[
byte >> 4]);
120 out.push_back(digits[
byte & 0x0F]);
126 void compress(
const unsigned char block[64]) {
128 for (
int i = 0; i < 16; ++i)
129 w[i] = (std::uint32_t(block[i * 4]) << 24) | (std::uint32_t(block[i * 4 + 1]) << 16) |
130 (std::uint32_t(block[i * 4 + 2]) << 8) | std::uint32_t(block[i * 4 + 3]);
131 for (
int i = 16; i < 64; ++i) {
132 const std::uint32_t s0 = detail::sha256_ror(w[i - 15], 7) ^
133 detail::sha256_ror(w[i - 15], 18) ^ (w[i - 15] >> 3);
134 const std::uint32_t s1 = detail::sha256_ror(w[i - 2], 17) ^
135 detail::sha256_ror(w[i - 2], 19) ^ (w[i - 2] >> 10);
136 w[i] = w[i - 16] + s0 + w[i - 7] + s1;
138 std::uint32_t a = h_[0], b = h_[1], c = h_[2], d = h_[3];
139 std::uint32_t e = h_[4], f = h_[5], g = h_[6], hh = h_[7];
140 for (
int i = 0; i < 64; ++i) {
141 const std::uint32_t S1 =
142 detail::sha256_ror(e, 6) ^ detail::sha256_ror(e, 11) ^ detail::sha256_ror(e, 25);
143 const std::uint32_t ch = (e & f) ^ ((~e) & g);
144 const std::uint32_t t1 = hh + S1 + ch + detail::SHA256_K[i] + w[i];
145 const std::uint32_t S0 =
146 detail::sha256_ror(a, 2) ^ detail::sha256_ror(a, 13) ^ detail::sha256_ror(a, 22);
147 const std::uint32_t maj = (a & b) ^ (a & c) ^ (b & c);
148 const std::uint32_t t2 = S0 + maj;
169 unsigned char buf_[64];
171 std::uint64_t total_;
189 std::FILE* f = std::fopen(path.c_str(),
"rb");
190 if (f ==
nullptr)
return std::string();
192 unsigned char buf[65536];
194 const std::size_t n = std::fread(buf, 1,
sizeof(buf), f);
195 if (n > 0) s.
update(buf, n);
196 if (n <
sizeof(buf))
break;
198 const bool bad = std::ferror(f) != 0;
200 return bad ? std::string() : s.
hex();
std::string hex()
Finalizes and returns the digest as 64 lowercase hex characters.
void update(const std::string &s)
void update(const void *data, std::size_t n)
std::string sha256_hex(const std::string &data)
The digest of a byte string, as 64 lowercase hex characters.
std::string sha256_file_hex(const std::string &path)
The digest of a file's contents, streamed.
Conservation laws of a layered queueing network, enumerated from its structure.