Cryptography Reference
In-Depth Information
ROUND( I, c, d, a, b, 10, 15, 55 );
ROUND( I, b, c, d, a, 1, 21, 56 );
ROUND( I, a, b, c, d, 8, 6, 57 );
ROUND( I, d, a, b, c, 15, 10, 58 );
ROUND( I, c, d, a, b, 6, 15, 59 );
ROUND( I, b, c, d, a, 13, 21, 60 );
ROUND( I, a, b, c, d, 4, 6, 61 );
ROUND( I, d, a, b, c, 11, 10, 62 );
ROUND( I, c, d, a, b, 2, 15, 63 );
ROUND( I, b, c, d, a, 9, 21, 64 );
hash[ 0 ] += a;
hash[ 1 ] += b;
hash[ 2 ] += c;
hash[ 3 ] += d;
}
3. Create a work area to hold the a , b , c , and d values from the current hash.
You see in just a minute how this is initialized — this is important. Then,
split the input, which is required to be exactly 512 bits, into 16 integers.
Notice that you convert to integers using little-endian conventions, rather
than the big-endian conventions you've been following thus far:
for ( j = 0; j < 16; j++ )
{
x[ j ] = input[ ( j * 4 ) + 3 ] << 24 |
input[ ( j * 4 ) + 2 ] << 16 |
input[ ( j * 4 ) + 1 ] << 8 |
input[ ( j * 4 ) ];
}
Technically speaking, because you know you're compiling to a 32-bit
little-endian architecture, you could actually memcpy into x — or even forgo
it completely if you are willing to be fast and loose with your typecasting.
The rest of the function consists of 64 expansions of the ROUND macro. You can
probably see how, if you just index hash directly, rather than using the work
area variables a, b, c, and d , you can change this from a macro expansion
to a loop. In fact, if you want to get a bit tricky, you could follow the pattern
in the k 's a nd s 's and code the whole thing in a terse loop. You can replace
md5_block_operate with the shorter, but more divergent — in terms of the
specifi cation — function shown in Listing 4-5.
Listing 4-5: Alternate md5_block_operate implementation
static int s[ 4 ][ 4 ] = {
{ 7, 12, 17, 22 },
{ 5, 9, 14, 20 },
{ 4, 11, 16, 23 },
{ 6, 10, 15, 21 }
};
 
Search WWH ::




Custom Search