/* PIP - Platform Independent Primitives Digest algorithms Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #include "pidigest_md5_p.h" template inline T rotate_u(T v, int bits) { return (v << bits) | (v >> ((sizeof(T) * 8) - bits)); } PIByteArray MD5::md5(const PIByteArray & in) { constexpr int part_size = 64; static constexpr uint32_t K[64] = { 0xD76AA478u, 0xE8C7B756u, 0x242070DBu, 0xC1BDCEEEu, 0xF57C0FAFu, 0x4787C62Au, 0xA8304613u, 0xFD469501u, 0x698098D8u, 0x8B44F7AFu, 0xFFFF5BB1u, 0x895CD7BEu, 0x6B901122u, 0xFD987193u, 0xA679438Eu, 0x49B40821u, 0xF61E2562u, 0xC040B340u, 0x265E5A51u, 0xE9B6C7AAu, 0xD62F105Du, 0x02441453u, 0xD8A1E681u, 0xE7D3FBC8u, 0x21E1CDE6u, 0xC33707D6u, 0xF4D50D87u, 0x455A14EDu, 0xA9E3E905u, 0xFCEFA3F8u, 0x676F02D9u, 0x8D2A4C8Au, 0xFFFA3942u, 0x8771F681u, 0x6D9D6122u, 0xFDE5380Cu, 0xA4BEEA44u, 0x4BDECFA9u, 0xF6BB4B60u, 0xBEBFBC70u, 0x289B7EC6u, 0xEAA127FAu, 0xD4EF3085u, 0x04881D05u, 0xD9D4D039u, 0xE6DB99E5u, 0x1FA27CF8u, 0xC4AC5665u, 0xF4292244u, 0x432AFF97u, 0xAB9423A7u, 0xFC93A039u, 0x655B59C3u, 0x8F0CCC92u, 0xFFEFF47Du, 0x85845DD1u, 0x6FA87E4Fu, 0xFE2CE6E0u, 0xA3014314u, 0x4E0811A1u, 0xF7537E82u, 0xBD3AF235u, 0x2AD7D2BBu, 0xEB86D391u}; static constexpr uint32_t s[64] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}; uint32_t a0 = 0x67452301u; uint32_t b0 = 0xefcdab89u; uint32_t c0 = 0x98badcfeu; uint32_t d0 = 0x10325476u; uint64_t l = in.size() * 8; PIByteArray msg = in; int add_l = (part_size - 8) - (msg.size() % (part_size)); if (add_l <= 0) add_l += part_size; msg.append(0x80); for (int i = 1; i < add_l; ++i) msg.append(0x0); msg << l; int parts = msg.size_s() / part_size; // piCout << l << "add" << add_l << "=" << (in.size() + add_l + sizeof(l)) << msg.size() << parts; for (int p = 0; p < parts; ++p) { uint32_t * mw = (uint32_t *)msg.data(p * part_size); uint32_t A = a0; uint32_t B = b0; uint32_t C = c0; uint32_t D = d0; for (int i = 0; i < 64; ++i) { uint32_t F = 0, g = 0; if (i >= 0 && i <= 15) { F = (B & C) | ((~B) & D); g = i; } else if (i >= 16 && i <= 31) { F = (D & B) | ((~D) & C); g = (5 * i + 1) % 16; } else if (i >= 32 && i <= 47) { F = B ^ C ^ D; g = (3 * i + 5) % 16; } else if (i >= 48 && i <= 63) { F = C ^ (B | (~D)); g = (7 * i) % 16; } F = F + A + K[i] + mw[g]; A = D; D = C; C = B; B = B + rotate_u(F, s[i]); } a0 = a0 + A; b0 = b0 + B; c0 = c0 + C; d0 = d0 + D; } PIByteArray ret; ret << a0 << b0 << c0 << d0; return ret; }