72 #ifdef _WIN32 // to disable warning C4996 about sprintf being deprecated
73 # include "../config.h.win"
74 #elif defined( _WIN32_WCE )
75 # include "../config.h.win"
99 const unsigned char MD4::pad[64] =
101 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
107 const std::string
MD4::md4(
const std::string& data )
115 : m_finished( false )
124 void MD4::process(
const unsigned char* data )
126 unsigned int a = m_state.abcd[0];
127 unsigned int b = m_state.abcd[1];
128 unsigned int c = m_state.abcd[2];
129 unsigned int d = m_state.abcd[3];
136 unsigned int xbuf[16];
137 const unsigned int *X;
147 static const int w = 1;
149 if( *((
const unsigned char *)&w) )
157 if( !((data - (
const unsigned char*)0) & 3) )
160 X = (
const unsigned int*)data;
165 memcpy( xbuf, data, 64 );
173 #if BYTE_ORDER >= 0 // big-endian
179 const unsigned char* xp = data;
187 for( i = 0; i < 16; ++i, xp += 4 )
188 xbuf[i] = xp[0] + ( xp[1] << 8 ) + ( xp[2] << 16 ) + ( xp[3] << 24 );
193 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
198 #define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
199 #define SET(a, b, c, d, k, s)\
200 t = a + F(b,c,d) + X[k];\
201 a = ROTATE_LEFT(t, s)
203 SET(a, b, c, d, 0, 3);
204 SET(d, a, b, c, 1, 7);
205 SET(c, d, a, b, 2, 11);
206 SET(b, c, d, a, 3, 19);
207 SET(a, b, c, d, 4, 3);
208 SET(d, a, b, c, 5, 7);
209 SET(c, d, a, b, 6, 11);
210 SET(b, c, d, a, 7, 19);
211 SET(a, b, c, d, 8, 3);
212 SET(d, a, b, c, 9, 7);
213 SET(c, d, a, b, 10, 11);
214 SET(b, c, d, a, 11, 19);
215 SET(a, b, c, d, 12, 3);
216 SET(d, a, b, c, 13, 7);
217 SET(c, d, a, b, 14, 11);
218 SET(b, c, d, a, 15, 19);
224 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
225 #define SET(a, b, c, d, k, s)\
226 t = a + G(b,c,d) + X[k] + 0x5A827999;\
227 a = ROTATE_LEFT(t, s)
229 SET(a, b, c, d, 0, 3);
230 SET(d, a, b, c, 4, 5);
231 SET(c, d, a, b, 8, 9);
232 SET(b, c, d, a, 12, 13);
233 SET(a, b, c, d, 1, 3);
234 SET(d, a, b, c, 5, 5);
235 SET(c, d, a, b, 9, 9);
236 SET(b, c, d, a, 13, 13);
237 SET(a, b, c, d, 2, 3);
238 SET(d, a, b, c, 6, 5);
239 SET(c, d, a, b, 10, 9);
240 SET(b, c, d, a, 14, 13);
241 SET(a, b, c, d, 3, 3);
242 SET(d, a, b, c, 7, 5);
243 SET(c, d, a, b, 11, 9);
244 SET(b, c, d, a, 15, 13);
250 #define H(x, y, z) ((x) ^ (y) ^ (z))
251 #define SET(a, b, c, d, k, s)\
252 t = a + H(b,c,d) + X[k] + 0x6ED9EBA1;\
253 a = ROTATE_LEFT(t, s)
255 SET(a, b, c, d, 0, 3);
256 SET(d, a, b, c, 8, 9);
257 SET(c, d, a, b, 4, 11);
258 SET(b, c, d, a, 12, 15);
259 SET(a, b, c, d, 2, 3);
260 SET(d, a, b, c, 10, 9);
261 SET(c, d, a, b, 6, 11);
262 SET(b, c, d, a, 14, 15);
263 SET(a, b, c, d, 1, 3);
264 SET(d, a, b, c, 9, 9);
265 SET(c, d, a, b, 5, 11);
266 SET(b, c, d, a, 13, 15);
267 SET(a, b, c, d, 3, 3);
268 SET(d, a, b, c, 11, 9);
269 SET(c, d, a, b, 7, 11);
270 SET(b, c, d, a, 15, 15);
277 m_state.abcd[0] += a;
278 m_state.abcd[1] += b;
279 m_state.abcd[2] += c;
280 m_state.abcd[3] += d;
286 m_state.count[0] = 0;
287 m_state.count[1] = 0;
288 m_state.abcd[0] = 0x67452301;
289 m_state.abcd[1] = 0xefcdab89;
290 m_state.abcd[2] = 0x98badcfe;
291 m_state.abcd[3] = 0x10325476;
296 feed( (
const unsigned char*)data.c_str(), (int)data.length() );
301 const unsigned char* p = data;
303 int offset = ( m_state.count[0] >> 3 ) & 63;
304 unsigned int nbits = (
unsigned int)( bytes << 3 );
310 m_state.count[1] += bytes >> 29;
311 m_state.count[0] += nbits;
312 if( m_state.count[0] < nbits )
318 int copy = ( offset + bytes > 64 ? 64 - offset : bytes );
320 memcpy( m_state.buf + offset, p, copy );
321 if( offset + copy < 64 )
325 process( m_state.buf );
329 for( ; left >= 64; p += 64, left -= 64 )
334 memcpy( m_state.buf, p, left );
342 unsigned char data[8];
345 for(
int i = 0; i < 8; ++i )
346 data[i] = (
unsigned char)( m_state.count[i >> 2] >> ( ( i & 3 ) << 3 ) );
349 feed( pad, ( ( 55 - ( m_state.count[0] >> 3 ) ) & 63 ) + 1 );
364 for(
int i = 0; i < 16; ++i )
365 sprintf( buf + i * 2,
"%02x", (
unsigned char)( m_state.abcd[i >> 2] >> ( ( i & 3 ) << 3 ) ) );
367 return std::string( buf, 32 );
375 unsigned char digest[16];
376 for(
int i = 0; i < 16; ++i )
377 digest[i] = (
unsigned char)( m_state.abcd[i >> 2] >> ( ( i & 3 ) << 3 ) );
379 return std::string( (
char*)digest, 16 );