📄 08e.c
字号:
// state matrix with values in an S-box.
void SubBytes()
{
int i,j;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
state[i][j] = getSBoxValue(state[i][j]);
}
}
}
// The ShiftRows() function shifts the rows in the state to the left.
// Each row is shifted with different offset.
// Offset = Row number. So the first row is not shifted.
void ShiftRows()
{
unsigned char temp;
// Rotate first row 1 columns to left
temp=state[1][0];
state[1][0]=state[1][1];
state[1][1]=state[1][2];
state[1][2]=state[1][3];
state[1][3]=temp;
// Rotate second row 2 columns to left
temp=state[2][0];
state[2][0]=state[2][2];
state[2][2]=temp;
temp=state[2][1];
state[2][1]=state[2][3];
state[2][3]=temp;
// Rotate third row 3 columns to left
temp=state[3][0];
state[3][0]=state[3][3];
state[3][3]=state[3][2];
state[3][2]=state[3][1];
state[3][1]=temp;
}
// xtime is a macro that finds the product of {02} and the argument to xtime modulo {1b}
#define xtime(x) ((x<<1) ^ (((x>>7) & 1) * 0x1b))
// MixColumns function mixes the columns of the state matrix
// The method used may look complicated, but it is easy if you know the underlying theory.
// Refer the documents specified above.
void MixColumns()
{
int i;
unsigned char Tmp,Tm,t;
for(i=0;i<4;i++)
{
t=state[0][i];
Tmp = state[0][i] ^ state[1][i] ^ state[2][i] ^ state[3][i] ;
Tm = state[0][i] ^ state[1][i] ; Tm = xtime(Tm); state[0][i] ^= Tm ^ Tmp ;
Tm = state[1][i] ^ state[2][i] ; Tm = xtime(Tm); state[1][i] ^= Tm ^ Tmp ;
Tm = state[2][i] ^ state[3][i] ; Tm = xtime(Tm); state[2][i] ^= Tm ^ Tmp ;
Tm = state[3][i] ^ t ; Tm = xtime(Tm); state[3][i] ^= Tm ^ Tmp ;
}
}
// Cipher is the main function that encrypts the PlainText.
void Cipher()
{
int i,j,round=0;
//Copy the input PlainText to state array.
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
state[j][i] = in[i*4 + j];
}
}
// Add the First round key to the state before starting the rounds.
AddRoundKey(0);
// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr-1 rounds are executed in the loop below.
for(round=1;round<Nr;round++)
{
SubBytes();
ShiftRows();
MixColumns();
AddRoundKey(round);
}
// The last round is given below.
// The MixColumns function is not here in the last round.
SubBytes();
ShiftRows();
AddRoundKey(Nr);
// The encryption process is over.
// Copy the state array to output array.
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
out[i*4+j]=state[j][i];
}
}
}
char toASCIICode(char x) //This function returns the ASCII Code of the Symbol used to represent the Hexadecimal Digit passed to it.
{
switch(x)
{
case 0x00 : return '0';
break;
case 0x01 : return '1';
break;
case 0x02 : return '2';
break;
case 0x03 : return '3';
break;
case 0x04 : return '4';
break;
case 0x05 : return '5';
break;
case 0x06 : return '6';
break;
case 0x07 : return '7';
break;
case 0x08 : return '8';
break;
case 0x09 : return '9';
break;
case 0x0A : return 'A';
break;
case 0x0B : return 'B';
break;
case 0x0C : return 'C';
break;
case 0x0D : return 'D';
break;
case 0x0E : return 'E';
break;
case 0x0F : return 'F';
break;
}
return 0x00;
}
char fromASCIICode(char x) //This function takes the ASCII Code of the Symbol used to represent a Hexadecimal Digit and returns the Hexadecimal Digit itself.
{
switch(x)
{
case '0' : return 0x00;
break;
case '1' : return 0x01;
break;
case '2' : return 0x02;
break;
case '3' : return 0x03;
break;
case '4' : return 0x04;
break;
case '5' : return 0x05;
break;
case '6' : return 0x06;
break;
case '7' : return 0x07;
break;
case '8' : return 0x08;
break;
case '9' : return 0x09;
break;
case 'A' : return 0x0A;
break;
case 'B' : return 0x0B;
break;
case 'C' : return 0x0C;
break;
case 'D' : return 0x0D;
break;
case 'E' : return 0x0E;
break;
case 'F' : return 0x0F;
break;
}
return 0x00;
}
void main()
{
int i; //General purpose loop counter variable.
Nr=128; //The length of key: 128-bits. (The possible values allowed by AES are 128, 192 or 256 only)
Nk = Nr / 32; //Calculate Nk and Nr from the
Nr = Nk + 6; // "length of the key" value.
uart_init(); //Initialize the UART
LCD_init(); //Initialize the LCD
//Get the plaintext from UART
uart_puts("\r\n\r\nEnter the plaintext using ASCII Symbols for Hex digits:\n");
for(i=0;i<Nk*4;i++)
{
in[i]=fromASCIICode(uart_getc())<<4;
in[i]+=fromASCIICode(uart_getc());
}
KeyExpansion(); //The KeyExpansion routine must be called before encryption.
Cipher(); //The next function call encrypts the PlainText with the Key using AES algorithm.
//Show the cipher on LCD
LCD_row1();
for(i=0;i<Nk*2;i++)
{
LCD_putc(toASCIICode(out[i]>>4)); //Send Most Significant Nibble to LCD
LCD_putc(toASCIICode(out[i]&0x0F)); //Send Least Significant Nibble to LCD
}
LCD_row2();
for(i=Nk*2;i<Nk*4;i++)
{
LCD_putc(toASCIICode(out[i]>>4)); //Send Most Significant Nibble to LCD
LCD_putc(toASCIICode(out[i]&0x0F)); //Send Least Significant Nibble to LCD
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -