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