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