2 * freerainbowtables is a project for generating, distributing, and using
3 * perfect rainbow tables
6 * Copyright 2009, 2010 Daniƫl Niggebrugge <niggebrugge@fox-it.com>
7 * Copyright 2009, 2010, 2011 James Nobis <frt@quelrod.net>
9 * This file is part of freerainbowtables.
11 * freerainbowtables is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 2 of the License, or
14 * (at your option) any later version.
16 * freerainbowtables is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with freerainbowtables. If not, see <http://www.gnu.org/licenses/>.
26 * This code implements the MD4 message-digest algorithm.
27 * "Just the reference implementation, single stage. Hardly "optimized." Though a good bit faster than libssl's MD4, as it isn't doing nearly the same amount of work." - Bitweasil
29 * little bit optimized (or at least attempted) for NTLM (unicode) by neinbrucke
36 /* MD4 Defines as per RFC reference implementation */
37 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
38 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
39 #define H(x, y, z) ((x) ^ (y) ^ (z))
40 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
41 #define FF(a, b, c, d, x, s) { \
42 (a) += F ((b), (c), (d)) + (x); \
43 (a) = ROTATE_LEFT ((a), (s)); \
45 #define GG(a, b, c, d, x, s) { \
46 (a) += G ((b), (c), (d)) + (x) + (uint32)0x5a827999; \
47 (a) = ROTATE_LEFT ((a), (s)); \
49 #define HH(a, b, c, d, x, s) { \
50 (a) += H ((b), (c), (d)) + (x) + (uint32)0x6ed9eba1; \
51 (a) = ROTATE_LEFT ((a), (s)); \
68 void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
70 // For the hash working space
71 uint32 b0,b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;
73 // For the output result
93 // LOAD DATA INTO b0 ... whatever here.
99 memcpy(in, pData, length);
102 uint32 * pUiIn = (uint32 *) in;
109 memcpy(in, pData, length);
110 uint32 * pUiIn = (uint32 *) in;
118 memcpy(in, pData, length);
121 uint32 * pUiIn = (uint32 *) in;
129 memcpy(in, pData, length);
130 uint32 * pUiIn = (uint32 *) in;
138 unsigned char in[12];
139 memcpy(in, pData, length);
142 uint32 * pUiIn = (uint32 *) in;
150 unsigned char in[32];
151 memcpy(in, pData, length);
153 memset(in + length + 1, 0, 32 - length - 1);
154 uint32 * pUiIn = (uint32 *) in;
162 b7 = pUiIn[7]; // max 14 2byte chars (ntlm)
176 FF (a, b, c, d, b0, S11); /* 1 */
177 FF (d, a, b, c, b1, S12); /* 2 */
178 FF (c, d, a, b, b2, S13); /* 3 */
179 FF (b, c, d, a, b3, S14); /* 4 */
180 FF (a, b, c, d, b4, S11); /* 5 */
181 FF (d, a, b, c, b5, S12); /* 6 */
182 FF (c, d, a, b, b6, S13); /* 7 */
183 FF (b, c, d, a, b7, S14); /* 8 */
184 FF (a, b, c, d, 0, S11); /* 9 */
185 FF (d, a, b, c, 0, S12); /* 10 */
186 FF (c, d, a, b, 0, S13); /* 11 */
187 FF (b, c, d, a, 0, S14); /* 12 */
188 FF (a, b, c, d, 0, S11); /* 13 */
189 FF (d, a, b, c, 0, S12); /* 14 */
190 FF (c, d, a, b, b14, S13); /* 15 */
191 FF (b, c, d, a, 0, S14); /* 16 */
194 GG (a, b, c, d, b0, S21); /* 17 */
195 GG (d, a, b, c, b4, S22); /* 18 */
196 GG (c, d, a, b, 0, S23); /* 19 */
197 GG (b, c, d, a, 0, S24); /* 20 */
198 GG (a, b, c, d, b1, S21); /* 21 */
199 GG (d, a, b, c, b5, S22); /* 22 */
200 GG (c, d, a, b, 0, S23); /* 23 */
201 GG (b, c, d, a, 0, S24); /* 24 */
202 GG (a, b, c, d, b2, S21); /* 25 */
203 GG (d, a, b, c, b6, S22); /* 26 */
204 GG (c, d, a, b, 0, S23); /* 27 */
205 GG (b, c, d, a, b14, S24); /* 28 */
206 GG (a, b, c, d, b3, S21); /* 29 */
207 GG (d, a, b, c, b7, S22); /* 30 */
208 GG (c, d, a, b, 0, S23); /* 31 */
209 GG (b, c, d, a, 0, S24); /* 32 */
212 HH (a, b, c, d, b0, S31); /* 33 */
213 HH (d, a, b, c, 0, S32); /* 34 */
214 HH (c, d, a, b, b4, S33); /* 35 */
215 HH (b, c, d, a, 0, S34); /* 36 */
216 HH (a, b, c, d, b2, S31); /* 37 */
217 HH (d, a, b, c, 0, S32); /* 38 */
218 HH (c, d, a, b, b6, S33); /* 39 */
219 HH (b, c, d, a, b14, S34); /* 40 */
220 HH (a, b, c, d, b1, S31); /* 41 */
221 HH (d, a, b, c, 0, S32); /* 42 */
222 HH (c, d, a, b, b5, S33); /* 43 */
223 HH (b, c, d, a, 0, S34); /* 44 */
224 HH (a, b, c, d, b3, S31); /* 45 */
225 HH (d, a, b, c, 0, S32); /* 46 */
226 HH (c, d, a, b, b7, S33); /* 47 */
227 HH (b, c, d, a, 0, S34); /* 48 */
229 // Finally, add initial values, as this is the only pass we make.
235 uint32 buf[4] = { a, b, c, d};
236 memcpy(pDigest, buf, 16);