⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 08d2.c

📁 Program for implementing AES on 8051 based microcontrollers. SDCC is used as the C compiler. Microco
💻 C
📖 第 1 页 / 共 2 页
字号:
	}
}

// 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 InvShiftRows()
{
	unsigned char temp;

	// Rotate first row 1 columns to right	
	temp=state[1][3];
	state[1][3]=state[1][2];
	state[1][2]=state[1][1];
	state[1][1]=state[1][0];
	state[1][0]=temp;

	// Rotate second row 2 columns to right	
	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 right
	temp=state[3][0];
	state[3][0]=state[3][1];
	state[3][1]=state[3][2];
	state[3][2]=state[3][3];
	state[3][3]=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))

// Multiplty is a macro used to multiply numbers in the field GF(2^8)
#define Multiply(x,y) (((y & 1) * x) ^ ((y>>1 & 1) * xtime(x)) ^ ((y>>2 & 1) * xtime(xtime(x))) ^ ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ ((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))))

// MixColumns function mixes the columns of the state matrix.
// The method used to multiply may be difficult to understand for the inexperienced.
// Please use the references to gain more information.
void InvMixColumns()
{
	int i;
	unsigned char a,b,c,d;
	for(i=0;i<4;i++)
	{	
	
		a = state[0][i];
		b = state[1][i];
		c = state[2][i];
		d = state[3][i];

		
		state[0][i] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
		state[1][i] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
		state[2][i] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
		state[3][i] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
	}
}

// InvCipher is the main function that decrypts the CipherText.
void InvCipher()
{
	int i,j,round=0;

	//Copy the input CipherText 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(Nr); 

	// There will be Nr rounds.
	// The first Nr-1 rounds are identical.
	// These Nr-1 rounds are executed in the loop below.
	for(round=Nr-1;round>0;round--)
	{
		InvShiftRows();
		InvSubBytes();
		AddRoundKey(round);
		InvMixColumns();
	}
	
	// The last round is given below.
	// The MixColumns function is not here in the last round.
	InvShiftRows();
	InvSubBytes();
	AddRoundKey(0);

	// The decryption 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 Cipher 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.

	
	InvCipher();		//The next function call encrypts the PlainText with the Key using AES algorithm.
	
	
	
	
	//Report all Strings (PLAINTEXT,KEY,CIPHER) to UART --->
	//Send Cipher to UART
	uart_puts("\r\n\r\nCipher entered (Hex Digits) :\n");
	for(i=0;i<Nk*4;i++)
	{
		uart_putc(toASCIICode(in[i]>>4));		//Send Most Significant Nibble to UART
		uart_putc(toASCIICode(in[i]&0x0F));		//Send Least Significant Nibble to UART
	}
	uart_puts("\r\nCipher entered (String) :\n");
	for(i=0;i<Nk*4;i++)
	{
		uart_putc(in[i]);
	}
		
	//Send Key to UART
	uart_puts("\r\n\r\nKey (Hex Digits) :\n");
	for(i=0;i<Nk*4;i++)
	{
		uart_putc(toASCIICode(Key[i]>>4));		//Send Most Significant Nibble to UART
		uart_putc(toASCIICode(Key[i]&0x0F));		//Send Least Significant Nibble to UART
	}
	uart_puts("\r\nKey (String) :\n");
	for(i=0;i<Nk*4;i++)
	{
		uart_putc(Key[i]);
	}
	
	//Send plaintext to UART
	uart_puts("\r\n\r\nPlaintext after decryption (Hex Digits) :\n");
	for(i=0;i<Nk*4;i++)
	{
		uart_putc(toASCIICode(out[i]>>4));		//Send Most Significant Nibble to UART
		uart_putc(toASCIICode(out[i]&0x0F));	//Send Least Significant Nibble to UART
	}
	uart_puts("\r\nPlaintext after decryption (String) :\n");
	for(i=0;i<Nk*4;i++)
	{
		uart_putc(out[i]);
	}
	//<--- Report all Strings (PLAINTEXT,KEY,CIPHER) to UART
	
	
	
	
	//Show the plaintext on LCD
	LCD_row1();
	for(i=0;i<Nk*4;i++)
	{
		LCD_putc(out[i]);		//Send Most Significant Nibble to LCD
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -