Blender V4.5
md5.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 1999, 2002 Aladdin Enterprises. All rights reserved.
2 *
3 * SPDX-License-Identifier: Zlib
4 *
5 * By `L. Peter Deutsch <ghost@aladdin.com>`. */
6
7/* Minor modifications done to remove some code and change style. */
8
9#include "util/md5.h"
10#include "util/path.h"
11
12#include <cstdio>
13#include <cstring>
14
16
17// NOLINTBEGIN
18#define T_MASK ((uint32_t)~0)
19#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
20#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
21#define T3 0x242070db
22#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
23#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
24#define T6 0x4787c62a
25#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
26#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
27#define T9 0x698098d8
28#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
29#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
30#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
31#define T13 0x6b901122
32#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
33#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
34#define T16 0x49b40821
35#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
36#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
37#define T19 0x265e5a51
38#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
39#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
40#define T22 0x02441453
41#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
42#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
43#define T25 0x21e1cde6
44#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
45#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
46#define T28 0x455a14ed
47#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
48#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
49#define T31 0x676f02d9
50#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
51#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
52#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
53#define T35 0x6d9d6122
54#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
55#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
56#define T38 0x4bdecfa9
57#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
58#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
59#define T41 0x289b7ec6
60#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
61#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
62#define T44 0x04881d05
63#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
64#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
65#define T47 0x1fa27cf8
66#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
67#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
68#define T50 0x432aff97
69#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
70#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
71#define T53 0x655b59c3
72#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
73#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
74#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
75#define T57 0x6fa87e4f
76#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
77#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
78#define T60 0x4e0811a1
79#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
80#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
81#define T63 0x2ad7d2bb
82#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
83// NOLINTEND
84
85void MD5Hash::process(const uint8_t *data /*[64]*/)
86{
87 uint32_t a = abcd[0];
88 uint32_t b = abcd[1];
89 uint32_t c = abcd[2];
90 uint32_t d = abcd[3];
91 uint32_t t;
92 /* Define storage for little-endian or both types of CPUs. */
93 uint32_t xbuf[16];
94 const uint32_t *X;
95
96 {
97 /*
98 * Determine dynamically whether this is a big-endian or
99 * little-endian machine, since we can use a more efficient
100 * algorithm on the latter.
101 */
102 static const int w = 1;
103
104 if (*((const uint8_t *)&w)) /* dynamic little-endian */ {
105 /*
106 * On little-endian machines, we can process properly aligned
107 * data without copying it.
108 */
109 if (!((data - (const uint8_t *)nullptr) & 3)) {
110 /* data are properly aligned */
111 X = (const uint32_t *)data;
112 }
113 else {
114 /* not aligned */
115 memcpy(xbuf, data, 64);
116 X = xbuf;
117 }
118 }
119 else { /* dynamic big-endian */
120 /*
121 * On big-endian machines, we must arrange the bytes in the
122 * right order.
123 */
124 const uint8_t *xp = data;
125 int i;
126
127 X = xbuf; /* (dynamic only) */
128 for (i = 0; i < 16; ++i, xp += 4) {
129 xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
130 }
131 }
132 }
133
134#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
135
136 /* Round 1. */
137 /* Let [abcd k s i] denote the operation
138 * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
139#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
140#define SET(a, b, c, d, k, s, Ti) \
141 t = a + F(b, c, d) + X[k] + Ti; \
142 a = ROTATE_LEFT(t, s) + b
143 /* Do the following 16 operations. */
144 SET(a, b, c, d, 0, 7, T1);
145 SET(d, a, b, c, 1, 12, T2);
146 SET(c, d, a, b, 2, 17, T3);
147 SET(b, c, d, a, 3, 22, T4);
148 SET(a, b, c, d, 4, 7, T5);
149 SET(d, a, b, c, 5, 12, T6);
150 SET(c, d, a, b, 6, 17, T7);
151 SET(b, c, d, a, 7, 22, T8);
152 SET(a, b, c, d, 8, 7, T9);
153 SET(d, a, b, c, 9, 12, T10);
154 SET(c, d, a, b, 10, 17, T11);
155 SET(b, c, d, a, 11, 22, T12);
156 SET(a, b, c, d, 12, 7, T13);
157 SET(d, a, b, c, 13, 12, T14);
158 SET(c, d, a, b, 14, 17, T15);
159 SET(b, c, d, a, 15, 22, T16);
160#undef SET
161
162 /* Round 2. */
163 /* Let [abcd k s i] denote the operation
164 * a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
165#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
166#define SET(a, b, c, d, k, s, Ti) \
167 t = a + G(b, c, d) + X[k] + Ti; \
168 a = ROTATE_LEFT(t, s) + b
169 /* Do the following 16 operations. */
170 SET(a, b, c, d, 1, 5, T17);
171 SET(d, a, b, c, 6, 9, T18);
172 SET(c, d, a, b, 11, 14, T19);
173 SET(b, c, d, a, 0, 20, T20);
174 SET(a, b, c, d, 5, 5, T21);
175 SET(d, a, b, c, 10, 9, T22);
176 SET(c, d, a, b, 15, 14, T23);
177 SET(b, c, d, a, 4, 20, T24);
178 SET(a, b, c, d, 9, 5, T25);
179 SET(d, a, b, c, 14, 9, T26);
180 SET(c, d, a, b, 3, 14, T27);
181 SET(b, c, d, a, 8, 20, T28);
182 SET(a, b, c, d, 13, 5, T29);
183 SET(d, a, b, c, 2, 9, T30);
184 SET(c, d, a, b, 7, 14, T31);
185 SET(b, c, d, a, 12, 20, T32);
186#undef SET
187
188 /* Round 3. */
189 /* Let [abcd k s t] denote the operation
190 * a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
191#define H(x, y, z) ((x) ^ (y) ^ (z))
192#define SET(a, b, c, d, k, s, Ti) \
193 t = a + H(b, c, d) + X[k] + Ti; \
194 a = ROTATE_LEFT(t, s) + b
195 /* Do the following 16 operations. */
196 SET(a, b, c, d, 5, 4, T33);
197 SET(d, a, b, c, 8, 11, T34);
198 SET(c, d, a, b, 11, 16, T35);
199 SET(b, c, d, a, 14, 23, T36);
200 SET(a, b, c, d, 1, 4, T37);
201 SET(d, a, b, c, 4, 11, T38);
202 SET(c, d, a, b, 7, 16, T39);
203 SET(b, c, d, a, 10, 23, T40);
204 SET(a, b, c, d, 13, 4, T41);
205 SET(d, a, b, c, 0, 11, T42);
206 SET(c, d, a, b, 3, 16, T43);
207 SET(b, c, d, a, 6, 23, T44);
208 SET(a, b, c, d, 9, 4, T45);
209 SET(d, a, b, c, 12, 11, T46);
210 SET(c, d, a, b, 15, 16, T47);
211 SET(b, c, d, a, 2, 23, T48);
212#undef SET
213
214 /* Round 4. */
215 /* Let [abcd k s t] denote the operation
216 * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
217#define I(x, y, z) ((y) ^ ((x) | ~(z)))
218#define SET(a, b, c, d, k, s, Ti) \
219 t = a + I(b, c, d) + X[k] + Ti; \
220 a = ROTATE_LEFT(t, s) + b
221 /* Do the following 16 operations. */
222 SET(a, b, c, d, 0, 6, T49);
223 SET(d, a, b, c, 7, 10, T50);
224 SET(c, d, a, b, 14, 15, T51);
225 SET(b, c, d, a, 5, 21, T52);
226 SET(a, b, c, d, 12, 6, T53);
227 SET(d, a, b, c, 3, 10, T54);
228 SET(c, d, a, b, 10, 15, T55);
229 SET(b, c, d, a, 1, 21, T56);
230 SET(a, b, c, d, 8, 6, T57);
231 SET(d, a, b, c, 15, 10, T58);
232 SET(c, d, a, b, 6, 15, T59);
233 SET(b, c, d, a, 13, 21, T60);
234 SET(a, b, c, d, 4, 6, T61);
235 SET(d, a, b, c, 11, 10, T62);
236 SET(c, d, a, b, 2, 15, T63);
237 SET(b, c, d, a, 9, 21, T64);
238#undef SET
239
240 /* Then perform the following additions. (That is increment each
241 * of the four registers by the value it had before this block
242 * was started.) */
243 abcd[0] += a;
244 abcd[1] += b;
245 abcd[2] += c;
246 abcd[3] += d;
247}
248
250{
251 count[0] = count[1] = 0;
252 abcd[0] = 0x67452301;
253 abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
254 abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
255 abcd[3] = 0x10325476;
256}
257
258MD5Hash::~MD5Hash() = default;
259
260void MD5Hash::append(const uint8_t *data, const int nbytes)
261{
262 const uint8_t *p = data;
263 int left = nbytes;
264 const int offset = (count[0] >> 3) & 63;
265 const uint32_t nbits = (uint32_t)(nbytes << 3);
266
267 if (nbytes <= 0) {
268 return;
269 }
270
271 /* Update the message length. */
272 count[1] += nbytes >> 29;
273 count[0] += nbits;
274 if (count[0] < nbits) {
275 count[1]++;
276 }
277
278 /* Process an initial partial block. */
279 if (offset) {
280 const int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
281
282 memcpy(buf + offset, p, copy);
283 if (offset + copy < 64) {
284 return;
285 }
286 p += copy;
287 left -= copy;
288 process(buf);
289 }
290
291 /* Process full blocks. */
292 for (; left >= 64; p += 64, left -= 64) {
293 process(p);
294 }
295
296 /* Process a final partial block. */
297 if (left) {
298 memcpy(buf, p, left);
299 }
300}
301
302void MD5Hash::append(const string &str)
303{
304 if (!str.empty()) {
305 append((const uint8_t *)str.c_str(), str.size());
306 }
307}
308
309bool MD5Hash::append_file(const string &filepath)
310{
311 FILE *f = path_fopen(filepath, "rb");
312
313 if (!f) {
314 fprintf(stderr, "MD5: failed to open file %s\n", filepath.c_str());
315 return false;
316 }
317
318 const size_t buffer_size = 1024;
319 uint8_t buffer[buffer_size];
320 size_t n;
321
322 do {
323 n = fread(buffer, 1, buffer_size, f);
324 append(buffer, n);
325 } while (n == buffer_size);
326
327 const bool success = (ferror(f) == 0);
328
329 fclose(f);
330
331 return success;
332}
333
334void MD5Hash::finish(uint8_t digest[16])
335{
336 static const uint8_t pad[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
337 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
338 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
339 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
340
341 uint8_t data[8];
342 int i;
343
344 /* Save the length before padding. */
345 for (i = 0; i < 8; ++i) {
346 data[i] = (uint8_t)(count[i >> 2] >> ((i & 3) << 3));
347 }
348
349 /* Pad to 56 bytes mod 64. */
350 append(pad, ((55 - (count[0] >> 3)) & 63) + 1);
351 /* Append the length. */
352 append(data, 8);
353
354 for (i = 0; i < 16; ++i) {
355 digest[i] = (uint8_t)(abcd[i >> 2] >> ((i & 3) << 3));
356 }
357}
358
360{
361 constexpr char kHexDigits[] = {
362 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
363
364 uint8_t digest[16];
365 char buf[16 * 2 + 1];
366
367 finish(digest);
368
369 for (int i = 0; i < 16; i++) {
370 buf[i * 2 + 0] = kHexDigits[digest[i] / 0x10];
371 buf[i * 2 + 1] = kHexDigits[digest[i] % 0x10];
372 }
373 buf[sizeof(buf) - 1] = '\0';
374
375 return string(buf);
376}
377
378string util_md5_string(const string &str)
379{
380 MD5Hash md5;
381 md5.append((uint8_t *)str.c_str(), str.size());
382 return md5.get_hex();
383}
384
#define X
int pad[32 - sizeof(int)]
BMesh const char void * data
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
Definition md5.h:19
bool append_file(const string &filepath)
Definition md5.cpp:309
void append(const uint8_t *data, const int nbytes)
Definition md5.cpp:260
string get_hex()
Definition md5.cpp:359
uint8_t buf[64]
Definition md5.h:35
void finish(uint8_t digest[16])
Definition md5.cpp:334
MD5Hash()
Definition md5.cpp:249
void process(const uint8_t *data)
Definition md5.cpp:85
uint32_t abcd[4]
Definition md5.h:34
uint32_t count[2]
Definition md5.h:33
#define CCL_NAMESPACE_END
#define str(s)
static int left
#define T51
Definition md5.cpp:69
#define T46
Definition md5.cpp:64
#define T50
Definition md5.cpp:68
#define T45
Definition md5.cpp:63
#define T56
Definition md5.cpp:74
#define T17
Definition md5.cpp:35
#define T54
Definition md5.cpp:72
#define T20
Definition md5.cpp:38
#define T43
Definition md5.cpp:61
#define T9
Definition md5.cpp:27
#define T14
Definition md5.cpp:32
#define T57
Definition md5.cpp:75
#define T37
Definition md5.cpp:55
#define T2
Definition md5.cpp:20
#define T_MASK
Definition md5.cpp:18
#define T7
Definition md5.cpp:25
#define T61
Definition md5.cpp:79
#define T10
Definition md5.cpp:28
#define T31
Definition md5.cpp:49
#define T62
Definition md5.cpp:80
#define T26
Definition md5.cpp:44
#define T24
Definition md5.cpp:42
#define T44
Definition md5.cpp:62
#define T25
Definition md5.cpp:43
#define T36
Definition md5.cpp:54
#define T18
Definition md5.cpp:36
#define T21
Definition md5.cpp:39
#define T6
Definition md5.cpp:24
#define T3
Definition md5.cpp:21
#define T58
Definition md5.cpp:76
#define SET(a, b, c, d, k, s, Ti)
#define T29
Definition md5.cpp:47
#define T60
Definition md5.cpp:78
#define T59
Definition md5.cpp:77
#define T5
Definition md5.cpp:23
#define T53
Definition md5.cpp:71
#define T39
Definition md5.cpp:57
#define T38
Definition md5.cpp:56
#define T19
Definition md5.cpp:37
#define T33
Definition md5.cpp:51
#define T49
Definition md5.cpp:67
#define T16
Definition md5.cpp:34
#define T22
Definition md5.cpp:40
#define T55
Definition md5.cpp:73
#define T41
Definition md5.cpp:59
#define T48
Definition md5.cpp:66
#define T4
Definition md5.cpp:22
#define T64
Definition md5.cpp:82
#define T40
Definition md5.cpp:58
#define T47
Definition md5.cpp:65
#define T13
Definition md5.cpp:31
#define T30
Definition md5.cpp:48
#define T11
Definition md5.cpp:29
#define T63
Definition md5.cpp:81
#define T1
Definition md5.cpp:19
#define T35
Definition md5.cpp:53
string util_md5_string(const string &str)
Definition md5.cpp:378
#define T8
Definition md5.cpp:26
#define T23
Definition md5.cpp:41
#define T42
Definition md5.cpp:60
#define T15
Definition md5.cpp:33
#define T34
Definition md5.cpp:52
#define T27
Definition md5.cpp:45
#define T28
Definition md5.cpp:46
#define T52
Definition md5.cpp:70
#define T32
Definition md5.cpp:50
#define T12
Definition md5.cpp:30
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)
FILE * path_fopen(const string &path, const string &mode)
Definition path.cpp:975
i
Definition text_draw.cc:230