Cryptography Reference
In-Depth Information
Listing 9-16: “aes.c” gf_multiply
/**
* “Multiply” X by Y (in a GF-128 field) and return the result in Z.
* X, Y, and Z are all AES_BLOCK_SIZE in length.
*/
static void gf_multiply( const unsigned char *X,
const unsigned char *Y,
unsigned char *Z )
{
unsigned char V[ AES_BLOCK_SIZE ];
unsigned char R[ AES_BLOCK_SIZE ];
unsigned char mask;
int i, j;
int lsb;
memset( Z, '\0', AES_BLOCK_SIZE );
memset( R, '\0', AES_BLOCK_SIZE );
R[ 0 ] = 0xE1;
memcpy( V, X, AES_BLOCK_SIZE );
for ( i = 0; i < 16; i++ )
{
for ( mask = 0x80; mask; mask >>= 1 )
{
if ( Y[ i ] & mask )
{
xor( Z, V, AES_BLOCK_SIZE );
}
lsb = ( V[ AES_BLOCK_SIZE - 1 ] & 0x01 );
for ( j = AES_BLOCK_SIZE - 1; j; j-- )
{
V[ j ] = ( V[ j ] >> 1 ) | ( ( V[ j - 1 ] & 0x01 ) << 7 );
}
V[ 0 ] >>= 1;
if ( lsb )
{
xor( V, R, AES_BLOCK_SIZE );
}
}
}
}
This is just another variant of the same double-and-add multiplication rou-
tine that has come up over and over again throughout this topic — the counter
variables i and mask iterate over the bits of the input Y and add X to the Z com-
putation whenever the input bit is 1 (you may want to refer to Listing 3-9 for a
more detailed look at this format). The only big difference is that X — which is
copied into the temporary variable V at the start of the routine — is right-shifted
Search WWH ::




Custom Search