6#include "Stroika/Foundation/StroikaPreComp.h"
16using namespace Stroika::Foundation::Cryptography;
17using namespace Stroika::Foundation::Cryptography::Digest;
103 constexpr static unsigned char kPADDING_[64] = {
104 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
109#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
110#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
111#define H(x, y, z) ((x) ^ (y) ^ (z))
112#define I(x, y, z) ((y) ^ ((x) | (~z)))
115#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
119#define FF(a, b, c, d, x, s, ac) \
121 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
122 (a) = ROTATE_LEFT ((a), (s)); \
125#define GG(a, b, c, d, x, s, ac) \
127 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
128 (a) = ROTATE_LEFT ((a), (s)); \
131#define HH(a, b, c, d, x, s, ac) \
133 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
134 (a) = ROTATE_LEFT ((a), (s)); \
137#define II(a, b, c, d, x, s, ac) \
139 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
140 (a) = ROTATE_LEFT ((a), (s)); \
147 mdContext->i[0] = mdContext->i[1] = (UINT4)0;
150 mdContext->buf[0] = (UINT4)0x67452301;
151 mdContext->buf[1] = (UINT4)0xefcdab89;
152 mdContext->buf[2] = (UINT4)0x98badcfe;
153 mdContext->buf[3] = (UINT4)0x10325476;
163 mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
166 if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
168 mdContext->i[0] += ((UINT4)inLen << 3);
169 mdContext->i[1] += ((UINT4)inLen >> 29);
173 mdContext->in[mdi++] = *inBuf++;
177 for (i = 0, ii = 0; i < 16; i++, ii += 4)
178 in[i] = (((UINT4)mdContext->in[ii + 3]) << 24) | (((UINT4)mdContext->in[ii + 2]) << 16) |
179 (((UINT4)mdContext->in[ii + 1]) << 8) | ((UINT4)mdContext->in[ii]);
194 in[14] = mdContext->i[0];
195 in[15] = mdContext->i[1];
198 mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
201 padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
205 Assert (padLen < Memory::NEltsOf (kPADDING_));
206 MD5Update_ (mdContext, kPADDING_, padLen);
209 for (i = 0, ii = 0; i < 14; i++, ii += 4)
210 in[i] = (((UINT4)mdContext->in[ii + 3]) << 24) | (((UINT4)mdContext->in[ii + 2]) << 16) | (((UINT4)mdContext->in[ii + 1]) << 8) |
211 ((UINT4)mdContext->in[ii]);
215 for (i = 0, ii = 0; i < 4; i++, ii += 4) {
216 mdContext->digest[ii] = (
unsigned char)(mdContext->buf[i] & 0xFF);
217 mdContext->digest[ii + 1] = (
unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
218 mdContext->digest[ii + 2] = (
unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
219 mdContext->digest[ii + 3] = (
unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
226 UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
233 FF (a, b, c, d, in[0], S11, 3614090360u);
234 FF (d, a, b, c, in[1], S12, 3905402710u);
235 FF (c, d, a, b, in[2], S13, 606105819u);
236 FF (b, c, d, a, in[3], S14, 3250441966u);
237 FF (a, b, c, d, in[4], S11, 4118548399u);
238 FF (d, a, b, c, in[5], S12, 1200080426u);
239 FF (c, d, a, b, in[6], S13, 2821735955u);
240 FF (b, c, d, a, in[7], S14, 4249261313u);
241 FF (a, b, c, d, in[8], S11, 1770035416u);
242 FF (d, a, b, c, in[9], S12, 2336552879u);
243 FF (c, d, a, b, in[10], S13, 4294925233u);
244 FF (b, c, d, a, in[11], S14, 2304563134u);
245 FF (a, b, c, d, in[12], S11, 1804603682u);
246 FF (d, a, b, c, in[13], S12, 4254626195u);
247 FF (c, d, a, b, in[14], S13, 2792965006u);
248 FF (b, c, d, a, in[15], S14, 1236535329u);
255 GG (a, b, c, d, in[1], S21, 4129170786u);
256 GG (d, a, b, c, in[6], S22, 3225465664u);
257 GG (c, d, a, b, in[11], S23, 643717713u);
258 GG (b, c, d, a, in[0], S24, 3921069994u);
259 GG (a, b, c, d, in[5], S21, 3593408605u);
260 GG (d, a, b, c, in[10], S22, 38016083u);
261 GG (c, d, a, b, in[15], S23, 3634488961u);
262 GG (b, c, d, a, in[4], S24, 3889429448u);
263 GG (a, b, c, d, in[9], S21, 568446438u);
264 GG (d, a, b, c, in[14], S22, 3275163606u);
265 GG (c, d, a, b, in[3], S23, 4107603335u);
266 GG (b, c, d, a, in[8], S24, 1163531501u);
267 GG (a, b, c, d, in[13], S21, 2850285829u);
268 GG (d, a, b, c, in[2], S22, 4243563512u);
269 GG (c, d, a, b, in[7], S23, 1735328473u);
270 GG (b, c, d, a, in[12], S24, 2368359562u);
277 HH (a, b, c, d, in[5], S31, 4294588738u);
278 HH (d, a, b, c, in[8], S32, 2272392833u);
279 HH (c, d, a, b, in[11], S33, 1839030562u);
280 HH (b, c, d, a, in[14], S34, 4259657740u);
281 HH (a, b, c, d, in[1], S31, 2763975236u);
282 HH (d, a, b, c, in[4], S32, 1272893353u);
283 HH (c, d, a, b, in[7], S33, 4139469664u);
284 HH (b, c, d, a, in[10], S34, 3200236656u);
285 HH (a, b, c, d, in[13], S31, 681279174u);
286 HH (d, a, b, c, in[0], S32, 3936430074u);
287 HH (c, d, a, b, in[3], S33, 3572445317u);
288 HH (b, c, d, a, in[6], S34, 76029189u);
289 HH (a, b, c, d, in[9], S31, 3654602809u);
290 HH (d, a, b, c, in[12], S32, 3873151461u);
291 HH (c, d, a, b, in[15], S33, 530742520u);
292 HH (b, c, d, a, in[2], S34, 3299628645u);
299 II (a, b, c, d, in[0], S41, 4096336452u);
300 II (d, a, b, c, in[7], S42, 1126891415u);
301 II (c, d, a, b, in[14], S43, 2878612391u);
302 II (b, c, d, a, in[5], S44, 4237533241u);
303 II (a, b, c, d, in[12], S41, 1700485571u);
304 II (d, a, b, c, in[3], S42, 2399980690u);
305 II (c, d, a, b, in[10], S43, 4293915773u);
306 II (b, c, d, a, in[1], S44, 2240044497u);
307 II (a, b, c, d, in[8], S41, 1873313359u);
308 II (d, a, b, c, in[15], S42, 4264355552u);
309 II (c, d, a, b, in[6], S43, 2734768916u);
310 II (b, c, d, a, in[13], S44, 1309151649u);
311 II (a, b, c, d, in[4], S41, 4149444226u);
312 II (d, a, b, c, in[11], S42, 3174756917u);
313 II (c, d, a, b, in[2], S43, 718787259u);
314 II (b, c, d, a, in[9], S44, 3951481745u);
340#if qStroika_Foundation_Debug_AssertionsChecked
341 Require (not fCompleted_);
343 Require (start == end or start !=
nullptr);
344 Require (start == end or end !=
nullptr);
345 MD5Update_ (&fCtx_,
reinterpret_cast<const unsigned char*
> (start),
static_cast<unsigned int> (end - start));
350#if qStroika_Foundation_Debug_AssertionsChecked
351 Require (not fCompleted_);
356 (void)::memcpy (Traversal::Iterator2Pointer (result.begin ()), fCtx_.digest, 16);
constexpr auto Transform(const optional< T > &o, F &&f)
DigesterAlgorithm is specialized for each algorithm; generally don't use this directly,...