2015
05-23

Matrix operation

M_0 is interested in cryptography. Recently he learned the Advanced Encryption Standard (AES). AES operates on a 4×4 column-major order matrix of bytes and he found it that there is a step called the MixColumns step in the AES.
In the MixColumns step, there is a state matrix, the four bytes of each column of the state are combined using an invertible linear transformation. The MixColumns function takes four bytes as input and outputs four bytes, where each input byte affects all four output bytes. Together with ShiftRows, MixColumns provides diffusion in the cipher.
During this operation, each column is multiplied by the known matrix that for the 128 bit key is:

The addition operation is defined as: xor.
The multiplication operation is defined as:
multiplication by 1 means no change
multiplication by 2 means shifting to the left
multiplication by 3 means shifting to the left and then performing xor with the initial unshifted value.
Notice:After each shifting, a conditional xor with 0x1B should be performed if the shifted value is larger than 0xFF.

There are several cases.
The first line is an integer T (T <= 20000), indicating the test cases.
Then is the state matrix, each case followed by four lines, each line contains four bytes, separated by spaces.

There are several cases.
The first line is an integer T (T <= 20000), indicating the test cases.
Then is the state matrix, each case followed by four lines, each line contains four bytes, separated by spaces.

1
00 01 02 03
04 05 06 07
08 09 0A 0B
0C 0D 0E 0F

08 09 0A 0B
1C 1D 1E 1F
00 01 02 03
14 15 16 17

#include <iostream>
#include <cstdio>
using namespace std;
int mat[4][4]={2,3,1,1,1,2,3,1,1,1,2,3,3,1,1,2};
int state[4][4],ans[4][4];

void work()
{
int i,j,k,temp1,temp2[4];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
for(k=0;k<4;k++)
{
if(mat[i][k]==2)
{
temp1=state[k][j]<<1;
if(temp1>0xFF)
temp1^=0x1B;
if(temp1>0xFF)
temp1%=(0xFF+1);
}
else if(mat[i][k]==3)
{
temp1=state[k][j]<<1;
if(temp1>0xFF)
temp1^=0x1B;
temp1^=state[k][j];
if(temp1>0xFF)
temp1%=(0xFF+1);
}
else
temp1=state[k][j];
temp2[k]=temp1;
}
for(k=1;k<4;k++)
temp2[0]^=temp2[k];
ans[i][j]=temp2[0];
}
}

int main()
{
int i,j,t;
scanf("%d",&t);
while(t--)
{
for(i=0;i<4;i++)
for(j=0;j<4;j++)
scanf("%X",&state[i][j]);
work();
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(j!=3)
printf("%02X ",ans[i][j]);
else
printf("%02X\n",ans[i][j]);
if(t!=0)
printf("\n");
}
return 0;
}