stdex
Additional custom or not Standard C++ covered algorithms
Loading...
Searching...
No Matches
hash.hpp
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 2016-2023 Amebis
4*/
5
6#pragma once
7
8#include "compat.hpp"
9#include "math.h"
10#include "stream.hpp"
11#include <stdint.h>
12
13namespace stdex
14{
15#ifdef _MSC_VER
16#pragma warning(push)
17#pragma warning(disable: 26495)
18#endif
19
23 template<class T>
25 {
26 public:
30 virtual void clear() = 0;
31
38 virtual void hash(_In_reads_bytes_opt_(length) const void* data, _In_ size_t length) = 0;
39
43 virtual void finalize() = 0;
44
48 static inline size_t size() { return sizeof(T); }
49
53 inline const T& data() { return m_value; };
54
58 inline operator const T&() const { return m_value; };
59
60 protected:
61 T m_value;
62 };
63
67 template<class T>
68 class block_hash : public basic_hash<T>
69 {
70 public:
71 virtual void clear()
72 {
73 m_counter[0] = m_counter[1] = 0;
74 }
75
76 virtual void hash(_In_reads_bytes_opt_(length) const void* data, _In_ size_t length)
77 {
78 assert(data || !length);
79
80 // Compute number of bytes mod 64.
81 size_t j = static_cast<size_t>((m_counter[0] >> 3) & 63);
82
83 // Update number of m_counter[1].
84 if ((m_counter[0] += (static_cast<uint32_t>(length) << 3)) < (static_cast<uint32_t>(length) << 3))
85 m_counter[1]++;
86 m_counter[1] += static_cast<uint32_t>(length) >> 29;
87
88 // Transform as many times as possible.
89 size_t i, remainder = 64 - j;
90 if (length >= remainder) {
91 assert(j < 64 && j + remainder <= 64);
92 assert(remainder <= length);
93 memcpy(m_queue + j, data, remainder);
94 hash_block();
95 for (i = remainder; i + 64 <= length; i += 64) {
96#ifdef _MSC_VER
97#pragma warning(push)
98#pragma warning(disable: 6385)
99#endif
100 memcpy(m_queue, reinterpret_cast<const uint8_t*>(data) + i, 64);
101#ifdef _MSC_VER
102#pragma warning(pop)
103#endif
104 hash_block();
105 }
106
107 j = 0;
108 }
109 else
110 i = 0;
111
112 // Buffer remaining input.
113 assert(j < 64 && j + length - i <= 64);
114 assert(i <= length);
115 memcpy(m_queue + j, reinterpret_cast<const uint8_t*>(data) + i, length - i);
116 }
117
118 protected:
119 virtual void hash_block() = 0;
120
121 protected:
122 uint32_t m_counter[2];
123 union {
124 uint8_t m_queue[64];
125 uint32_t m_temp[16];
126 };
127 };
128
129#ifdef _MSC_VER
130#pragma warning(pop)
131#endif
132
136 template<class T>
138 {
139 public:
140 stream_hasher(_Inout_ basic_hash<T>& hash, _Inout_ stdex::stream::basic& source) :
142 m_hash(hash)
143 {}
144
145 virtual _Success_(return != 0 || length == 0) size_t read(
146 _Out_writes_bytes_to_opt_(length, return) void* data, _In_ size_t length)
147 {
148 size_t num_read = stdex::stream::converter::read(data, length);
149 m_hash.hash(data, num_read);
150 return num_read;
151 }
152
153 virtual _Success_(return != 0) size_t write(
154 _In_reads_bytes_opt_(length) const void* data, _In_ size_t length)
155 {
156 size_t num_written = stdex::stream::converter::write(data, length);
157 m_hash.hash(data, num_written);
158 return num_written;
159 }
160
161 protected:
162 basic_hash<T>& m_hash;
163 };
164
168 using crc32_t = uint32_t;
169
173 class crc32_hash : public basic_hash<crc32_t>
174 {
175 public:
176 crc32_hash(crc32_t crc = 0)
177 {
178 m_value = ~crc;
179 }
180
181 virtual void clear()
182 {
183 m_value = 0xffffffff;
184 }
185
186 virtual void hash(_In_reads_bytes_opt_(length) const void* data, _In_ size_t length)
187 {
188 static const uint32_t crc32_table[256] = {
189 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
190 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
191 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
192 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
193 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
194 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
195 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
196 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
197 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
198 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
199 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
200 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
201 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
202 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
203 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
204 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
205 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
206 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
207 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
208 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
209 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
210 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
211 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
212 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
213 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
214 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
215 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
216 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
217 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
218 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
219 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
220 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
221 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
222 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
223 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
224 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
225 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
226 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
227 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
228 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
229 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
230 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
231 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
232 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
233 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
234 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
235 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
236 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
237 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
238 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
239 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
240 0x2d02ef8d
241 };
242
243 assert(data || !length);
244 for (size_t i = 0; i < length; i++)
245 m_value = crc32_table[(m_value ^ reinterpret_cast<const uint8_t*>(data)[i]) & 0xff] ^ (m_value >> 8);
246 }
247
248 virtual void finalize()
249 {
250 m_value = ~m_value;
251 }
252 };
253
257 union md2_t
258 {
259 uint8_t data8[16];
260 uint32_t data32[4];
261 };
262
266 using md5_t = md2_t;
267
271 class md5_hash : public block_hash<md5_t>
272 {
273 public:
274 md5_hash()
275 {
276 clear();
277 }
278
279 virtual void clear()
280 {
282 m_state[0] = 0x67452301;
283 m_state[1] = 0xefcdab89;
284 m_state[2] = 0x98badcfe;
285 m_state[3] = 0x10325476;
286 }
287
288 virtual void finalize()
289 {
290 static const uint8_t md5_padding[64] = {
291 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
292 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
293 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
294 };
295
296 // Save number of final.
297 uint8_t final[8];
298 memcpy(final, m_counter, sizeof(m_counter));
299
300 // Pad out to 56 mod 64.
301 size_t index = (m_counter[0] >> 3) & 0x3f;
302 size_t remainder = index < 56 ? 56 - index : 120 - index;
303 hash(md5_padding, remainder);
304
305 // Append length (before padding).
306 hash(final, 8);
307
308 // Store m_state in m_value.
309 memcpy(&m_value, m_state, sizeof(md5_t));
310 }
311
312 protected:
313 virtual void hash_block()
314 {
315 constexpr int S11 = 7;
316 constexpr int S12 = 12;
317 constexpr int S13 = 17;
318 constexpr int S14 = 22;
319 constexpr int S21 = 5;
320 constexpr int S22 = 9;
321 constexpr int S23 = 14;
322 constexpr int S24 = 20;
323 constexpr int S31 = 4;
324 constexpr int S32 = 11;
325 constexpr int S33 = 16;
326 constexpr int S34 = 23;
327 constexpr int S41 = 6;
328 constexpr int S42 = 10;
329 constexpr int S43 = 15;
330 constexpr int S44 = 21;
331
332 // Copy m_state[] to working vars.
333 uint32_t a = m_state[0], b = m_state[1], c = m_state[2], d = m_state[3];
334
335 // MD5 rounds
336 #define MD5_R1(a, b, c, d, i, s, ac) { (a) += (((b) & (c)) | ((~b) & (d))) + m_temp[(i)] + static_cast<uint32_t>(ac); (a) = rol((a), (s)); (a) += (b); }
337 #define MD5_R2(a, b, c, d, i, s, ac) { (a) += (((b) & (d)) | ((c) & (~d))) + m_temp[(i)] + static_cast<uint32_t>(ac); (a) = rol((a), (s)); (a) += (b); }
338 #define MD5_R3(a, b, c, d, i, s, ac) { (a) += ((b) ^ (c) ^ (d)) + m_temp[(i)] + static_cast<uint32_t>(ac); (a) = rol((a), (s)); (a) += (b); }
339 #define MD5_R4(a, b, c, d, i, s, ac) { (a) += ((c) ^ ((b) | (~d))) + m_temp[(i)] + static_cast<uint32_t>(ac); (a) = rol((a), (s)); (a) += (b); }
340
341 // 4 rounds of 16 operations each. Loop unrolled.
342 MD5_R1(a, b, c, d, 0, S11, 0xd76aa478);
343 MD5_R1(d, a, b, c, 1, S12, 0xe8c7b756);
344 MD5_R1(c, d, a, b, 2, S13, 0x242070db);
345 MD5_R1(b, c, d, a, 3, S14, 0xc1bdceee);
346 MD5_R1(a, b, c, d, 4, S11, 0xf57c0faf);
347 MD5_R1(d, a, b, c, 5, S12, 0x4787c62a);
348 MD5_R1(c, d, a, b, 6, S13, 0xa8304613);
349 MD5_R1(b, c, d, a, 7, S14, 0xfd469501);
350 MD5_R1(a, b, c, d, 8, S11, 0x698098d8);
351 MD5_R1(d, a, b, c, 9, S12, 0x8b44f7af);
352 MD5_R1(c, d, a, b, 10, S13, 0xffff5bb1);
353 MD5_R1(b, c, d, a, 11, S14, 0x895cd7be);
354 MD5_R1(a, b, c, d, 12, S11, 0x6b901122);
355 MD5_R1(d, a, b, c, 13, S12, 0xfd987193);
356 MD5_R1(c, d, a, b, 14, S13, 0xa679438e);
357 MD5_R1(b, c, d, a, 15, S14, 0x49b40821);
358 MD5_R2(a, b, c, d, 1, S21, 0xf61e2562);
359 MD5_R2(d, a, b, c, 6, S22, 0xc040b340);
360 MD5_R2(c, d, a, b, 11, S23, 0x265e5a51);
361 MD5_R2(b, c, d, a, 0, S24, 0xe9b6c7aa);
362 MD5_R2(a, b, c, d, 5, S21, 0xd62f105d);
363 MD5_R2(d, a, b, c, 10, S22, 0x2441453);
364 MD5_R2(c, d, a, b, 15, S23, 0xd8a1e681);
365 MD5_R2(b, c, d, a, 4, S24, 0xe7d3fbc8);
366 MD5_R2(a, b, c, d, 9, S21, 0x21e1cde6);
367 MD5_R2(d, a, b, c, 14, S22, 0xc33707d6);
368 MD5_R2(c, d, a, b, 3, S23, 0xf4d50d87);
369 MD5_R2(b, c, d, a, 8, S24, 0x455a14ed);
370 MD5_R2(a, b, c, d, 13, S21, 0xa9e3e905);
371 MD5_R2(d, a, b, c, 2, S22, 0xfcefa3f8);
372 MD5_R2(c, d, a, b, 7, S23, 0x676f02d9);
373 MD5_R2(b, c, d, a, 12, S24, 0x8d2a4c8a);
374 MD5_R3(a, b, c, d, 5, S31, 0xfffa3942);
375 MD5_R3(d, a, b, c, 8, S32, 0x8771f681);
376 MD5_R3(c, d, a, b, 11, S33, 0x6d9d6122);
377 MD5_R3(b, c, d, a, 14, S34, 0xfde5380c);
378 MD5_R3(a, b, c, d, 1, S31, 0xa4beea44);
379 MD5_R3(d, a, b, c, 4, S32, 0x4bdecfa9);
380 MD5_R3(c, d, a, b, 7, S33, 0xf6bb4b60);
381 MD5_R3(b, c, d, a, 10, S34, 0xbebfbc70);
382 MD5_R3(a, b, c, d, 13, S31, 0x289b7ec6);
383 MD5_R3(d, a, b, c, 0, S32, 0xeaa127fa);
384 MD5_R3(c, d, a, b, 3, S33, 0xd4ef3085);
385 MD5_R3(b, c, d, a, 6, S34, 0x4881d05);
386 MD5_R3(a, b, c, d, 9, S31, 0xd9d4d039);
387 MD5_R3(d, a, b, c, 12, S32, 0xe6db99e5);
388 MD5_R3(c, d, a, b, 15, S33, 0x1fa27cf8);
389 MD5_R3(b, c, d, a, 2, S34, 0xc4ac5665);
390 MD5_R4(a, b, c, d, 0, S41, 0xf4292244);
391 MD5_R4(d, a, b, c, 7, S42, 0x432aff97);
392 MD5_R4(c, d, a, b, 14, S43, 0xab9423a7);
393 MD5_R4(b, c, d, a, 5, S44, 0xfc93a039);
394 MD5_R4(a, b, c, d, 12, S41, 0x655b59c3);
395 MD5_R4(d, a, b, c, 3, S42, 0x8f0ccc92);
396 MD5_R4(c, d, a, b, 10, S43, 0xffeff47d);
397 MD5_R4(b, c, d, a, 1, S44, 0x85845dd1);
398 MD5_R4(a, b, c, d, 8, S41, 0x6fa87e4f);
399 MD5_R4(d, a, b, c, 15, S42, 0xfe2ce6e0);
400 MD5_R4(c, d, a, b, 6, S43, 0xa3014314);
401 MD5_R4(b, c, d, a, 13, S44, 0x4e0811a1);
402 MD5_R4(a, b, c, d, 4, S41, 0xf7537e82);
403 MD5_R4(d, a, b, c, 11, S42, 0xbd3af235);
404 MD5_R4(c, d, a, b, 2, S43, 0x2ad7d2bb);
405 MD5_R4(b, c, d, a, 9, S44, 0xeb86d391);
406
407 #undef MD5_R1
408 #undef MD5_R2
409 #undef MD5_R3
410 #undef MD5_R4
411
412 // Add the working vars back into internal state.
413 m_state[0] += a;
414 m_state[1] += b;
415 m_state[2] += c;
416 m_state[3] += d;
417 }
418
419 protected:
420 uint32_t m_state[4];
421 };
422
426 union sha_t
427 {
428 uint8_t data8[20];
429 uint32_t data32[5];
430 };
431
435 using sha1_t = sha_t;
436
440 class sha1_hash : public block_hash<sha1_t>
441 {
442 public:
443 sha1_hash()
444 {
445 clear();
446 }
447
448 virtual void clear()
449 {
451
452 // SHA1 initialization constants
453 m_state[0] = 0x67452301;
454 m_state[1] = 0xEFCDAB89;
455 m_state[2] = 0x98BADCFE;
456 m_state[3] = 0x10325476;
457 m_state[4] = 0xC3D2E1F0;
458 }
459
460 virtual void finalize()
461 {
462 // Save number of final.
463 uint8_t final[8];
464 for (size_t i = 0; i < 8; i++)
465 final[i] = static_cast<uint8_t>((m_counter[((i >= 4) ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); // Endian independent
466
467 hash("\200", 1);
468 while ((m_counter[0] & 504) != 448)
469 hash("\0", 1);
470 hash(final, 8); // Cause a SHA1Transform()
471
472 // Store m_state in m_value.
473 for (size_t i = 0; i < 20; i++)
474 m_value.data8[i] = static_cast<uint8_t>((m_state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
475 }
476
477 protected:
478 virtual void hash_block()
479 {
480 // Copy m_state[] to working vars.
481 uint32_t a = m_state[0], b = m_state[1], c = m_state[2], d = m_state[3], e = m_state[4];
482
483#if BYTE_ORDER == BIG_ENDIAN
484 #define SHA1BLK0(i) (m_temp[i])
485#else
486 #define SHA1BLK0(i) (m_temp[i] = (rol(m_temp[i],24) & 0xFF00FF00) | (rol(m_temp[i],8) & 0x00FF00FF))
487#endif
488 #define SHA1BLK(i) (m_temp[i&15] = rol(m_temp[(i+13)&15] ^ m_temp[(i+8)&15] ^ m_temp[(i+2)&15] ^ m_temp[i&15],1))
489
490 // SHA1 rounds
491 #define SHA1_R0(v, w, x, y, z, i) { (z) += (((w)&((x)^(y)))^(y))+SHA1BLK0((i))+0x5A827999+rol((v),5); (w)=rol((w),30); }
492 #define SHA1_R1(v, w, x, y, z, i) { (z) += (((w)&((x)^(y)))^(y))+SHA1BLK((i))+0x5A827999+rol((v),5); (w)=rol((w),30); }
493 #define SHA1_R2(v, w, x, y, z, i) { (z) += ((w)^(x)^(y))+SHA1BLK((i))+0x6ED9EBA1+rol((v),5); (w)=rol((w),30); }
494 #define SHA1_R3(v, w, x, y, z, i) { (z) += ((((w)|(x))&(y))|((w)&(x)))+SHA1BLK((i))+0x8F1BBCDC+rol((v),5); (w)=rol((w),30); }
495 #define SHA1_R4(v, w, x, y, z, i) { (z) += ((w)^(x)^(y))+SHA1BLK((i))+0xCA62C1D6+rol((v),5); (w)=rol((w),30); }
496
497 // 5 rounds of 16 operations each. Loop unrolled.
498 SHA1_R0(a, b, c, d, e, 0); SHA1_R0(e, a, b, c, d, 1); SHA1_R0(d, e, a, b, c, 2); SHA1_R0(c, d, e, a, b, 3);
499 SHA1_R0(b, c, d, e, a, 4); SHA1_R0(a, b, c, d, e, 5); SHA1_R0(e, a, b, c, d, 6); SHA1_R0(d, e, a, b, c, 7);
500 SHA1_R0(c, d, e, a, b, 8); SHA1_R0(b, c, d, e, a, 9); SHA1_R0(a, b, c, d, e, 10); SHA1_R0(e, a, b, c, d, 11);
501 SHA1_R0(d, e, a, b, c, 12); SHA1_R0(c, d, e, a, b, 13); SHA1_R0(b, c, d, e, a, 14); SHA1_R0(a, b, c, d, e, 15);
502 SHA1_R1(e, a, b, c, d, 16); SHA1_R1(d, e, a, b, c, 17); SHA1_R1(c, d, e, a, b, 18); SHA1_R1(b, c, d, e, a, 19);
503 SHA1_R2(a, b, c, d, e, 20); SHA1_R2(e, a, b, c, d, 21); SHA1_R2(d, e, a, b, c, 22); SHA1_R2(c, d, e, a, b, 23);
504 SHA1_R2(b, c, d, e, a, 24); SHA1_R2(a, b, c, d, e, 25); SHA1_R2(e, a, b, c, d, 26); SHA1_R2(d, e, a, b, c, 27);
505 SHA1_R2(c, d, e, a, b, 28); SHA1_R2(b, c, d, e, a, 29); SHA1_R2(a, b, c, d, e, 30); SHA1_R2(e, a, b, c, d, 31);
506 SHA1_R2(d, e, a, b, c, 32); SHA1_R2(c, d, e, a, b, 33); SHA1_R2(b, c, d, e, a, 34); SHA1_R2(a, b, c, d, e, 35);
507 SHA1_R2(e, a, b, c, d, 36); SHA1_R2(d, e, a, b, c, 37); SHA1_R2(c, d, e, a, b, 38); SHA1_R2(b, c, d, e, a, 39);
508 SHA1_R3(a, b, c, d, e, 40); SHA1_R3(e, a, b, c, d, 41); SHA1_R3(d, e, a, b, c, 42); SHA1_R3(c, d, e, a, b, 43);
509 SHA1_R3(b, c, d, e, a, 44); SHA1_R3(a, b, c, d, e, 45); SHA1_R3(e, a, b, c, d, 46); SHA1_R3(d, e, a, b, c, 47);
510 SHA1_R3(c, d, e, a, b, 48); SHA1_R3(b, c, d, e, a, 49); SHA1_R3(a, b, c, d, e, 50); SHA1_R3(e, a, b, c, d, 51);
511 SHA1_R3(d, e, a, b, c, 52); SHA1_R3(c, d, e, a, b, 53); SHA1_R3(b, c, d, e, a, 54); SHA1_R3(a, b, c, d, e, 55);
512 SHA1_R3(e, a, b, c, d, 56); SHA1_R3(d, e, a, b, c, 57); SHA1_R3(c, d, e, a, b, 58); SHA1_R3(b, c, d, e, a, 59);
513 SHA1_R4(a, b, c, d, e, 60); SHA1_R4(e, a, b, c, d, 61); SHA1_R4(d, e, a, b, c, 62); SHA1_R4(c, d, e, a, b, 63);
514 SHA1_R4(b, c, d, e, a, 64); SHA1_R4(a, b, c, d, e, 65); SHA1_R4(e, a, b, c, d, 66); SHA1_R4(d, e, a, b, c, 67);
515 SHA1_R4(c, d, e, a, b, 68); SHA1_R4(b, c, d, e, a, 69); SHA1_R4(a, b, c, d, e, 70); SHA1_R4(e, a, b, c, d, 71);
516 SHA1_R4(d, e, a, b, c, 72); SHA1_R4(c, d, e, a, b, 73); SHA1_R4(b, c, d, e, a, 74); SHA1_R4(a, b, c, d, e, 75);
517 SHA1_R4(e, a, b, c, d, 76); SHA1_R4(d, e, a, b, c, 77); SHA1_R4(c, d, e, a, b, 78); SHA1_R4(b, c, d, e, a, 79);
518
519 // Add the working vars back into m_state.
520 m_state[0] += a;
521 m_state[1] += b;
522 m_state[2] += c;
523 m_state[3] += d;
524 m_state[4] += e;
525
526 #undef SHA1_R0
527 #undef SHA1_R1
528 #undef SHA1_R2
529 #undef SHA1_R3
530 #undef SHA1_R4
531 #undef SHA1BLK0
532 #undef SHA1BLK0
533 #undef SHA1BLK
534 }
535
536 protected:
537 uint32_t m_state[5];
538 };
539
544 {
545 uint8_t data8[32];
546 uint32_t data32[8];
547 };
548}
549
550inline bool operator !=(const stdex::md2_t& odtis1, const stdex::md2_t& odtis2)
551{
552 return
553 (odtis1.data32[0] ^ odtis2.data32[0]) |
554 (odtis1.data32[1] ^ odtis2.data32[1]) |
555 (odtis1.data32[2] ^ odtis2.data32[2]) |
556 (odtis1.data32[3] ^ odtis2.data32[3]);
557}
558
559inline bool operator ==(const stdex::md2_t& odtis1, const stdex::md2_t& odtis2)
560{
561 return !operator !=(odtis1, odtis2);
562}
563
564inline bool operator !=(_In_ const stdex::sha_t& odtis1, _In_ const stdex::sha_t& odtis2)
565{
566 return
567 (odtis1.data32[0] ^ odtis2.data32[0]) |
568 (odtis1.data32[1] ^ odtis2.data32[1]) |
569 (odtis1.data32[2] ^ odtis2.data32[2]) |
570 (odtis1.data32[3] ^ odtis2.data32[3]) |
571 (odtis1.data32[4] ^ odtis2.data32[4]);
572}
573
574inline bool operator ==(_In_ const stdex::sha_t& odtis1, _In_ const stdex::sha_t& odtis2)
575{
576 return !operator !=(odtis1, odtis2);
577}
578
579inline bool operator !=(const stdex::sha256_t& odtis1, const stdex::sha256_t& odtis2)
580{
581 return
582 (odtis1.data32[0] ^ odtis2.data32[0]) |
583 (odtis1.data32[1] ^ odtis2.data32[1]) |
584 (odtis1.data32[2] ^ odtis2.data32[2]) |
585 (odtis1.data32[3] ^ odtis2.data32[3]) |
586 (odtis1.data32[4] ^ odtis2.data32[4]) |
587 (odtis1.data32[5] ^ odtis2.data32[5]) |
588 (odtis1.data32[6] ^ odtis2.data32[6]) |
589 (odtis1.data32[7] ^ odtis2.data32[7]);
590}
591
592inline bool operator ==(const stdex::sha256_t& odtis1, const stdex::sha256_t& odtis2)
593{
594 return !(odtis1 != odtis2);
595}
596
597inline stdex::stream::basic& operator >>(_Inout_ stdex::stream::basic& stream, _Out_ stdex::md2_t& data)
598{
599 if (!stream.ok()) _Unlikely_{
600 memset(&data, 0, sizeof(data));
601 return stream;
602 }
603 stream.read_array(&data, sizeof(data), 1);
604 return stream;
605}
606
607inline stdex::stream::basic& operator <<(_Inout_ stdex::stream::basic& stream, _In_ const stdex::md2_t& data)
608{
609 if (!stream.ok()) _Unlikely_
610 return stream;
611 stream.write_array(&data, sizeof(data), 1);
612 return stream;
613}
614
615inline stdex::stream::basic& operator >>(_Inout_ stdex::stream::basic& stream, _Out_ stdex::sha_t& data)
616{
617 if (!stream.ok()) _Unlikely_{
618 memset(&data, 0, sizeof(data));
619 return stream;
620 }
621 stream.read_array(&data, sizeof(data), 1);
622 return stream;
623}
624
625inline stdex::stream::basic& operator <<(_Inout_ stdex::stream::basic& stream, _In_ const stdex::sha_t& data)
626{
627 if (!stream.ok()) _Unlikely_
628 return stream;
629 stream.write_array(&data, sizeof(data), 1);
630 return stream;
631}
632
633inline stdex::stream::basic& operator >>(_Inout_ stdex::stream::basic& stream, _Out_ stdex::sha256_t& data)
634{
635 if (!stream.ok()) _Unlikely_{
636 memset(&data, 0, sizeof(data));
637 return stream;
638 }
639 stream.read_array(&data, sizeof(data), 1);
640 return stream;
641}
642
643inline stdex::stream::basic& operator <<(_Inout_ stdex::stream::basic& stream, _In_ const stdex::sha256_t& data)
644{
645 if (!stream.ok()) _Unlikely_
646 return stream;
647 stream.write_array(&data, sizeof(data), 1);
648 return stream;
649}
Basic hashing operations.
Definition hash.hpp:25
const T & data()
Returns hash value.
Definition hash.hpp:53
virtual void hash(_In_reads_bytes_opt_(length) const void *data, size_t length)=0
Hashes block of data.
static size_t size()
Returns size of the hash value in bytes.
Definition hash.hpp:48
virtual void finalize()=0
Finalizes hash value.
virtual void clear()=0
Initializes hash value and internal state.
Hashing in blocks.
Definition hash.hpp:69
virtual void hash(_In_reads_bytes_opt_(length) const void *data, size_t length)
Hashes block of data.
Definition hash.hpp:76
virtual void clear()
Initializes hash value and internal state.
Definition hash.hpp:71
Hashes as CRC32.
Definition hash.hpp:174
virtual void finalize()
Finalizes hash value.
Definition hash.hpp:248
virtual void hash(_In_reads_bytes_opt_(length) const void *data, size_t length)
Hashes block of data.
Definition hash.hpp:186
virtual void clear()
Initializes hash value and internal state.
Definition hash.hpp:181
Hashes as MD5.
Definition hash.hpp:272
virtual void clear()
Initializes hash value and internal state.
Definition hash.hpp:279
virtual void finalize()
Finalizes hash value.
Definition hash.hpp:288
Hashes as SHA1.
Definition hash.hpp:441
virtual void clear()
Initializes hash value and internal state.
Definition hash.hpp:448
virtual void finalize()
Finalizes hash value.
Definition hash.hpp:460
‍UTF-8 byte-order-mark
Definition stream.hpp:77
Modifies data on the fly when reading from/writing to a source stream.
Definition stream.hpp:895
virtual size_t read(_Out_writes_bytes_to_opt_(length, return) void *data, size_t length)
Reads block of data from the stream.
Definition stream.hpp:919
virtual size_t write(_In_reads_bytes_opt_(length) const void *data, size_t length)
Writes block of data to the stream.
Definition stream.hpp:927
Hashes read to or write from data of the stream.
Definition hash.hpp:138
virtual size_t read(_Out_writes_bytes_to_opt_(length, return) void *data, size_t length)
Reads block of data from the stream.
Definition hash.hpp:145
virtual size_t write(_In_reads_bytes_opt_(length) const void *data, size_t length)
Writes block of data to the stream.
Definition hash.hpp:153
MD2 hash value.
Definition hash.hpp:258
SHA256 hash value.
Definition hash.hpp:544
SHA hash value.
Definition hash.hpp:427