36 void update(
const uint8_t* input,
size_t length);
42 void update(
const std::string& input);
55 static std::string
hash(
const std::string& input);
65 void transform(
const uint8_t block[64]);
79inline uint32_t
F(uint32_t x, uint32_t y, uint32_t z) {
return (x & y) | (~x & z); }
88inline uint32_t
G(uint32_t x, uint32_t y, uint32_t z) {
return (x & z) | (y & ~z); }
97inline uint32_t
H(uint32_t x, uint32_t y, uint32_t z) {
return x ^ y ^ z; }
106inline uint32_t
I(uint32_t x, uint32_t y, uint32_t z) {
return y ^ (x | ~z); }
114inline uint32_t
rotate_left(uint32_t x,
int n) {
return (x << n) | (x >> (32 - n)); }
126inline void FF(uint32_t &a, uint32_t b, uint32_t c, uint32_t d,
127 uint32_t x, uint32_t s, uint32_t ac)
129 a +=
F(b, c, d) + x + ac;
144inline void GG(uint32_t &a, uint32_t b, uint32_t c, uint32_t d,
145 uint32_t x, uint32_t s, uint32_t ac)
147 a +=
G(b, c, d) + x + ac;
162inline void HH(uint32_t &a, uint32_t b, uint32_t c, uint32_t d,
163 uint32_t x, uint32_t s, uint32_t ac)
165 a +=
H(b, c, d) + x + ac;
180inline void II(uint32_t &a, uint32_t b, uint32_t c, uint32_t d,
181 uint32_t x, uint32_t s, uint32_t ac)
183 a +=
I(b, c, d) + x + ac;
194inline void encode(uint8_t* output,
const uint32_t* input,
size_t length) {
195 for (
size_t i = 0, j = 0; j < length; ++i, j += 4) {
196 output[j] = input[i] & 0xff;
197 output[j + 1] = (input[i] >> 8) & 0xff;
198 output[j + 2] = (input[i] >> 16) & 0xff;
199 output[j + 3] = (input[i] >> 24) & 0xff;
209inline void decode(uint32_t* output,
const uint8_t* input,
size_t length) {
210 for (
size_t i = 0, j = 0; j < length; ++i, j += 4) {
211 output[i] = ((uint32_t)input[j]) |
212 (((uint32_t)input[j + 1]) << 8) |
213 (((uint32_t)input[j + 2]) << 16) |
214 (((uint32_t)input[j + 3]) << 24);
218inline void kMD5::init() {
220 state[0] = 0x67452301;
221 state[1] = 0xefcdab89;
222 state[2] = 0x98badcfe;
223 state[3] = 0x10325476;
227 size_t i = 0, index = (size_t)((count >> 3) & 0x3F);
228 count += ((uint64_t)length) << 3;
230 size_t partLen = 64 - index;
232 if (length >= partLen) {
233 std::memcpy(&buffer[index], input, partLen);
235 for (i = partLen; i + 63 < length; i += 64)
236 transform(&input[i]);
241 std::memcpy(&buffer[index], &input[i], length - i);
245 update(
reinterpret_cast<const uint8_t*
>(input.c_str()), input.length());
249 static uint8_t PADDING[64] = { 0x80 };
251 encode(bits,
reinterpret_cast<uint32_t*
>(&count), 8);
253 size_t index = (size_t)((count >> 3) & 0x3f);
254 size_t padLen = (index < 56) ? (56 - index) : (120 - index);
259 encode(digest, state, 16);
261 std::ostringstream oss;
262 for (
int i = 0; i < 16; ++i)
263 oss << std::hex << std::setw(2) << std::setfill(
'0') << (int)digest[i];
273inline void kMD5::transform(
const uint8_t block[64]) {
274 uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
277 FF(a, b, c, d, x[ 0], 7, 0xd76aa478);
278 FF(d, a, b, c, x[ 1], 12, 0xe8c7b756);
279 FF(c, d, a, b, x[ 2], 17, 0x242070db);
280 FF(b, c, d, a, x[ 3], 22, 0xc1bdceee);
281 FF(a, b, c, d, x[ 4], 7, 0xf57c0faf);
282 FF(d, a, b, c, x[ 5], 12, 0x4787c62a);
283 FF(c, d, a, b, x[ 6], 17, 0xa8304613);
284 FF(b, c, d, a, x[ 7], 22, 0xfd469501);
285 FF(a, b, c, d, x[ 8], 7, 0x698098d8);
286 FF(d, a, b, c, x[ 9], 12, 0x8b44f7af);
287 FF(c, d, a, b, x[10], 17, 0xffff5bb1);
288 FF(b, c, d, a, x[11], 22, 0x895cd7be);
289 FF(a, b, c, d, x[12], 7, 0x6b901122);
290 FF(d, a, b, c, x[13], 12, 0xfd987193);
291 FF(c, d, a, b, x[14], 17, 0xa679438e);
292 FF(b, c, d, a, x[15], 22, 0x49b40821);
294 GG(a, b, c, d, x[ 1], 5, 0xf61e2562);
295 GG(d, a, b, c, x[ 6], 9, 0xc040b340);
296 GG(c, d, a, b, x[11], 14, 0x265e5a51);
297 GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa);
298 GG(a, b, c, d, x[ 5], 5, 0xd62f105d);
299 GG(d, a, b, c, x[10], 9, 0x02441453);
300 GG(c, d, a, b, x[15], 14, 0xd8a1e681);
301 GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8);
302 GG(a, b, c, d, x[ 9], 5, 0x21e1cde6);
303 GG(d, a, b, c, x[14], 9, 0xc33707d6);
304 GG(c, d, a, b, x[ 3], 14, 0xf4d50d87);
305 GG(b, c, d, a, x[ 8], 20, 0x455a14ed);
306 GG(a, b, c, d, x[13], 5, 0xa9e3e905);
307 GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8);
308 GG(c, d, a, b, x[ 7], 14, 0x676f02d9);
309 GG(b, c, d, a, x[12], 20, 0x8d2a4c8a);
311 HH(a, b, c, d, x[ 5], 4, 0xfffa3942);
312 HH(d, a, b, c, x[ 8], 11, 0x8771f681);
313 HH(c, d, a, b, x[11], 16, 0x6d9d6122);
314 HH(b, c, d, a, x[14], 23, 0xfde5380c);
315 HH(a, b, c, d, x[ 1], 4, 0xa4beea44);
316 HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9);
317 HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60);
318 HH(b, c, d, a, x[10], 23, 0xbebfbc70);
319 HH(a, b, c, d, x[13], 4, 0x289b7ec6);
320 HH(d, a, b, c, x[ 0], 11, 0xeaa127fa);
321 HH(c, d, a, b, x[ 3], 16, 0xd4ef3085);
322 HH(b, c, d, a, x[ 6], 23, 0x04881d05);
323 HH(a, b, c, d, x[ 9], 4, 0xd9d4d039);
324 HH(d, a, b, c, x[12], 11, 0xe6db99e5);
325 HH(c, d, a, b, x[15], 16, 0x1fa27cf8);
326 HH(b, c, d, a, x[ 2], 23, 0xc4ac5665);
328 II(a, b, c, d, x[ 0], 6, 0xf4292244);
329 II(d, a, b, c, x[ 7], 10, 0x432aff97);
330 II(c, d, a, b, x[14], 15, 0xab9423a7);
331 II(b, c, d, a, x[ 5], 21, 0xfc93a039);
332 II(a, b, c, d, x[12], 6, 0x655b59c3);
333 II(d, a, b, c, x[ 3], 10, 0x8f0ccc92);
334 II(c, d, a, b, x[10], 15, 0xffeff47d);
335 II(b, c, d, a, x[ 1], 21, 0x85845dd1);
336 II(a, b, c, d, x[ 8], 6, 0x6fa87e4f);
337 II(d, a, b, c, x[15], 10, 0xfe2ce6e0);
338 II(c, d, a, b, x[ 6], 15, 0xa3014314);
339 II(b, c, d, a, x[13], 21, 0x4e0811a1);
340 II(a, b, c, d, x[ 4], 6, 0xf7537e82);
341 II(d, a, b, c, x[11], 10, 0xbd3af235);
342 II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb);
343 II(b, c, d, a, x[ 9], 21, 0xeb86d391);
void update(const uint8_t *input, size_t length)
Feeds a block of raw bytes into the running digest.
Definition kmd5.h:226
static std::string hash(const std::string &input)
One-shot helper that hashes an entire string.
Definition kmd5.h:267
std::string final()
Finalises the digest and returns it as a lowercase hex string.
Definition kmd5.h:248
kMD5()
Constructs the context and initialises it to the MD5 starting state.
Definition kmd5.h:29
Top-level Kemena3D engine namespace.
Definition kanimation.h:23
uint32_t I(uint32_t x, uint32_t y, uint32_t z)
MD5 auxiliary function I used in round 4: y ^ (x | ~z).
Definition kmd5.h:106
void decode(uint32_t *output, const uint8_t *input, size_t length)
Reassembles bytes into 32-bit words assuming little-endian order.
Definition kmd5.h:209
uint32_t G(uint32_t x, uint32_t y, uint32_t z)
MD5 auxiliary function G used in round 2: (x & z) | (y & ~z).
Definition kmd5.h:88
void encode(uint8_t *output, const uint32_t *input, size_t length)
Serialises 32-bit words into bytes in little-endian order.
Definition kmd5.h:194
void HH(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac)
Round-3 transformation step using the H mixing function.
Definition kmd5.h:162
void GG(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac)
Round-2 transformation step using the G mixing function.
Definition kmd5.h:144
uint32_t H(uint32_t x, uint32_t y, uint32_t z)
MD5 auxiliary function H used in round 3: x ^ y ^ z.
Definition kmd5.h:97
uint32_t F(uint32_t x, uint32_t y, uint32_t z)
MD5 auxiliary function F used in round 1: (x & y) | (~x & z).
Definition kmd5.h:79
uint32_t rotate_left(uint32_t x, int n)
Performs a circular left rotation of a 32-bit value.
Definition kmd5.h:114
void II(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac)
Round-4 transformation step using the I mixing function.
Definition kmd5.h:180
void FF(uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac)
Round-1 transformation step using the F mixing function.
Definition kmd5.h:126