30 namespace digest_detail {
32 static inline uint32_t
min(uint32_t x, uint32_t y) {
36 static inline uint32_t
load32l(
const uint8_t* y) {
38 for (
size_t i = 0; i != 4; ++i)
39 res |= uint32_t(y[i]) << (i * 8);
43 static inline void store32l(uint32_t x, uint8_t* y) {
44 for (
size_t i = 0; i != 4; ++i)
45 y[i] = (x >> (i * 8)) & 255;
48 static inline void store64l(uint64_t x, uint8_t* y) {
49 for (
size_t i = 0; i != 8; ++i)
50 y[i] = (x >> (i * 8)) & 255;
54 uint32_t
F(
const uint32_t& x,
const uint32_t& y,
const uint32_t& z) {
55 return (z ^ (x & (y ^ z)));
58 uint32_t
G(
const uint32_t& x,
const uint32_t& y,
const uint32_t& z) {
59 return (y ^ (z & (y ^ x)));
62 uint32_t
H(
const uint32_t& x,
const uint32_t& y,
const uint32_t& z) {
66 uint32_t
I(
const uint32_t& x,
const uint32_t& y,
const uint32_t& z) {
67 return (y ^ (x | (~z)));
70 static inline void FF(uint32_t& a, uint32_t& b, uint32_t& c, uint32_t& d,
71 uint32_t M, uint32_t s, uint32_t t) {
72 a = (a +
F(b, c, d) + M + t);
76 static inline void GG(uint32_t& a, uint32_t& b, uint32_t& c, uint32_t& d,
77 uint32_t M, uint32_t s, uint32_t t) {
78 a = (a +
G(b, c, d) + M + t);
82 static inline void HH(uint32_t& a, uint32_t& b, uint32_t& c, uint32_t& d,
83 uint32_t M, uint32_t s, uint32_t t) {
84 a = (a +
H(b, c, d) + M + t);
88 static inline void II(uint32_t& a, uint32_t& b, uint32_t& c, uint32_t& d,
89 uint32_t M, uint32_t s, uint32_t t) {
90 a = (a +
I(b, c, d) + M + t);
94 static const uint8_t
Worder[64] = {
95 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
96 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,
97 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,
98 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9
101 static const uint8_t
Rorder[64] = {
102 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
103 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
104 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
105 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
108 static const uint32_t
Korder[64] = {
109 0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL,
110 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL, 0x698098d8UL, 0x8b44f7afUL,
111 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL,
112 0x49b40821UL, 0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL,
113 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL, 0x21e1cde6UL,
114 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL,
115 0x676f02d9UL, 0x8d2a4c8aUL, 0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL,
116 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
117 0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL,
118 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL, 0xf4292244UL, 0x432aff97UL,
119 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL,
120 0x85845dd1UL, 0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL,
121 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
124 static void md5_compress(uint32_t state[4],
const uint8_t* buf) {
125 uint32_t i, W[16], a, b, c, d, t;
128 for (i = 0; i < 16; i++) {
138 for (i = 0; i < 16; ++i) {
140 t = d, d = c, c = b, b = a, a = t;
143 for ( ; i < 32; ++i) {
145 t = d, d = c, c = b, b = a, a = t;
148 for ( ; i < 48; ++i) {
150 t = d, d = c, c = b, b = a, a = t;
153 for ( ; i < 64; ++i) {
155 t = d, d = c, c = b, b = a, a = t;
158 state[0] = state[0] + a;
159 state[1] = state[1] + b;
160 state[2] = state[2] + c;
161 state[3] = state[3] + d;
175 MD5::MD5(
const void* data, uint32_t size) : MD5() {
184 const uint32_t block_size =
sizeof(
MD5::buf_);
185 auto in =
static_cast<const uint8_t*
>(data);
189 if (
curlen_ == 0 && size >= block_size)
200 for (
const uint8_t* a = in; a != in + n; ++a, ++b) {
218 return process(str.data(), str.size());
247 for (
size_t i = 0; i < 4; i++) {
255 finalize(
const_cast<char*
>(out.data()));
271 std::string
md5_hex(
const void* data, uint32_t size) {
275 std::string
md5_hex(
const std::string& str) {
279 std::string
md5_hex_uc(
const void* data, uint32_t size) {
283 std::string
md5_hex_uc(
const std::string& str) {