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