#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdio.h>
using namespace std;
typedef unsigned char byte;
struct word
{
byte wordKey[4];
};
const byte SBox[16][16] = {
{0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76},
{0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0},
{0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15},
{0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75},
{0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84},
{0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf},
{0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8},
{0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2},
{0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73},
{0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb},
{0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79},
{0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08},
{0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a},
{0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e},
{0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf},
{0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}
};
/*轮密钥加*/
void AddRoundKey(unsigned char *plaintext, unsigned char * CipherKey)
{
for (int i = 0; i < 16; i++)
{
plaintext[i] = plaintext[i] ^ CipherKey[i];
}
}
const int Rcon[10] = {
0x01000000, 0x02000000,
0x04000000, 0x08000000,
0x10000000, 0x20000000,
0x40000000, 0x80000000,
0x1b000000, 0x36000000
};
const byte mixColumnMatrix[4][4] = {
{0x02, 0x03, 0x01, 0x01},
{0x01, 0x02, 0x03, 0x01},
{0x01, 0x01, 0x02, 0x03},
{0x03, 0x01, 0x01, 0x02}
};
const byte invmixColumnMatrix[4][4] = {
{0x0e, 0x0b, 0x0d, 0x09},
{0x09, 0x0e, 0x0b, 0x0d},
{0x0d, 0x09, 0x0e, 0x0b},
{0x0b, 0x0d, 0x09, 0x0e}
};
/*字节代换*/
void SubBytes(unsigned char *plaintext, unsigned char *plaintextencrypt,int count)
{
unsigned int row, column;
unsigned char Sbox[16][16] = {
/* 0 1 2 3 4 5 6 7 8 9 a b c d ef */
/*0*/{ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01,0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 },
/*1*/{ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4,0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 },
/*2*/{ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5,0xf1, 0x71, 0xd8, 0x31, 0x15 },
/*3*/{ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12,0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 },
/*4*/{ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b,0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 },
/*5*/{ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb,0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf },
/*6*/{ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9,0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 },
/*7*/{ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6,0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 },
/*8*/{ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7,0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 },
/*9*/{ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee,0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb },
/*a*/{ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3,0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 },
/*b*/{ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56,0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 },
/*c*/{ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd,0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a },
/*d*/{ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35,0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e },
/*e*/{ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e,0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf },
/*f*/{ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99,0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }
};
// 填充Sbox矩阵
for (int i = 0; i < count; i++)
{
row = (plaintext[i] & 0xF0) >> 4;
column = plaintext[i] & 0x0F;
plaintextencrypt[i] = Sbox[row][column];
}
}
/*逆向字节代换*/
void SubBytesRe(unsigned char *plaintext, unsigned char *plaintextencrypt,int count)
{
unsigned int row, column;
unsigned char Sbox[16][16] =
{/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
{0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3,0x9e, 0x81, 0xf3, 0xd7, 0xfb},
{0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43,0x44, 0xc4, 0xde, 0xe9, 0xcb},
{0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95,0x0b, 0x42, 0xfa, 0xc3, 0x4e},
{0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2,0x49, 0x6d, 0x8b, 0xd1, 0x25},
{0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c,0xcc, 0x5d, 0x65, 0xb6, 0x92},
{0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46,0x57, 0xa7, 0x8d, 0x9d, 0x84},
{0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58,0x05, 0xb8, 0xb3, 0x45, 0x06},
{0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd,0x03, 0x01, 0x13, 0x8a, 0x6b},
{0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf,0xce, 0xf0, 0xb4, 0xe6, 0x73},
{0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37,0xe8, 0x1c, 0x75, 0xdf, 0x6e},
{0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62,0x0e, 0xaa, 0x18, 0xbe, 0x1b},
{0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0,0xfe, 0x78, 0xcd, 0x5a, 0xf4},
{0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10,0x59, 0x27, 0x80, 0xec, 0x5f},
{0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a,0x9f, 0x93, 0xc9, 0x9c, 0xef},
{0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb,0x3c, 0x83, 0x53, 0x99, 0x61},
{0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14,0x63, 0x55, 0x21, 0x0c, 0x7d} };
// 填充Sbox矩阵
for (int i = 0; i < count; i++)
{
row = (plaintext[i] & 0xF0) >> 4;
column = plaintext[i] & 0x0F;
plaintextencrypt[i] = Sbox[row][column];
}
}
/*逆向行移位*/
void ShiftRowsRe(unsigned char *plaintextencrypt)
{
unsigned char copy[16];
for (int i = 0; i < 16; i++)
{
copy[i] = plaintextencrypt[i];
}
for (int i = 4; i < 16; i++)
{
plaintextencrypt[i] = copy[int(i / 4) * 4 + (4 - (i / 4)) % 4];
}
}
/*行移位*/
void ShiftRows(unsigned char *plaintextencrypt)
{
int i, j;
unsigned char temp[16];
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
temp[i*4+j] = plaintextencrypt[((i + j) % 4)*4+j];
}
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
plaintextencrypt[i*4+j] = temp[i*4+j];
}
}
}
byte GFMultiplyByte(byte L, byte R) {
byte temp[8];
byte result = 0x00;
temp[0] = L;
int i;
// temp[0] = L, temp[1] = L*x(modm(x)), temp[2] = L*x^2(mod(m(x))), temp[3] = L*x^3(mod(m(x)))...
//先计算,再存起来,后面根据R的实际情况选用需要的
for (i = 1; i < 8; i++) {
if (temp[i - 1] >= 0x80) {
temp[i] = (temp[i - 1] << 1) ^ 0x1b;
}
else {
temp[i] = temp[i - 1] << 1;
}
}
for (i = 0; i < 8; i++) {
if (int((R >> i) & 0x01) == 1) {
result ^= temp[i];
}
}
return result;
}
//void AES::mixColumn(word in[]) {
// word result[4];
// int i, j, k;
// for (i = 0; i < 4; i++) {
// for (j = 0; j < 4; j++) {
// result[i].wordKey[j] = GFMultiplyByte(mixColumnMatrix[j][0], in[i].wordKey[0]);
// for (k = 1; k < 4; k++) {
// result[i].wordKey[j] ^= GFMultiplyByte(mixColumnMatrix[j][k], in[i].wordKey[k]);
// }
// }
// }
// for (i = 0; i < 4; i++) {
// for (j = 0; j < 4; j++) {
// in[i].wordKey[j] = result[i].wordKey[j];
// }
// }
//}
/*列混淆*/
void MixColumns(unsigned char *plaintextencrypt, unsigned char*plaintextcrypt)
{
int i, j, k;
unsigned char res[16] = {};
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
plaintextcrypt[i * 4 + j] = GFMultiplyByte(mixColumnMatrix[j][0], plaintextencrypt[4 * i]);
for (k = 1; k < 4; k++) {
plaintextcrypt[i * 4 + j] ^= GFMultiplyByte(mixColumnMatrix[j][k], plaintextencrypt[4 * i + k]);
}
}
}
//for (int i = 0; i < 16; i++)
//{
// plaintextcrypt[i] = res[i];
//}
}
void invMixColumn(word in[]) {
word result[4];
int i, j, k;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
result[i].wordKey[j] = GFMultiplyByte(invmixColumnMatrix[j][0], in[i].wordKey[0]);
for (k = 1; k < 4; k++) {
result[i].wordKey[j] ^= GFMultiplyByte(invmixColumnMatrix[j][k], in[i].wordKey[k]);
}
}
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
in[i].wordKey[j] = result[i].wordKey[j];
}
}
}
/*逆向列混淆*/
#define xtime(x) ((x << 1) ^ (((x >> 7) & 1) * 0x1b))
#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))))))
void MixColumnsRe(unsigned char *state)
{
unsigned char result[16] = {};
int i, j, k;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
result[i*4+j] = GFMultiplyByte(invmixColumnMatrix[j][0], state[i*4]);
for (k = 1; k < 4; k++) {
result[i*4+k] ^= GFMultiplyByte(invmixColumnMatrix[j][k], state[i*4+k]);
}
}
}
for (int i = 0; i < 16; i++)
{
state[i] = result[i];
}
}
/*字节转字*/
int CharToWord(unsigned char *character, int first)
{
unsigned int val = 0x0;
for (int i = first; i < first + 4; i++)
{
val += (unsigned int(character[i])) < ((3 - i % 4) * 8);
}
return int(val);
}
/*字转字节*/
void WordToChar(unsigned int word, unsigned char *character)
{
for (int i = 0; i < 4; i++)
{
character[3 - i] = char(word & 0xff);
word = word > 8;
}
}
/*密钥扩展*/
void ExtendCipherKey(unsigned int *CipherKey_word, int round)
{
for (int i = 4; i < 44; i++)
{
if (i % 4 != 0)
{
CipherKey_word[i] = CipherKey_word[i - 1] ^ CipherKey_word[i - 4];
}
else
{
// 循环移位
unsigned int key_is1 = CipherKey_word[i - 1];
unsigned int ii = 0xff000000;
ii = ii & key_is1;
ii = ii >> 24;
key_is1 = key_is1 << 8 + ii;
// 先将int转换成char
unsigned char to_change[4] = {};
WordToChar(key_is1, to_change);
unsigned char res[4] = {};
SubBytes(to_change, res, 4);
unsigned int new_key = Rcon[i/4] ^ CharToWord(res, 0);
CipherKey_word[i] = new_key;
}
}
}
int main() {
printf("**************AES加解密***************\n");
int i = 0, k;
unsigned char PlainText[16] = { 0x32,0x43,0xf6,0xa8,0x88,0x5a,0x30,0x8d,0x31,0x31,0x98,0xa2,0xe0,0x37,0x07,0x34 },
CipherKey[16] = { 0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c },
CipherKey1[16] = { 0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c },
PlainText1[16] = { 0 },
PlainText2[16] = { 0 };
unsigned int CipherKey_word[44] = { 0 };
for (i = 0; i < 4; CipherKey_word[i++] = CharToWord(CipherKey, 4 * i));
printf("密钥:");
for (k = 0; k < 16; k++) printf("%2X ", CipherKey[k]);
printf("\n明文:");
for (k = 0; k < 16; k++) printf("%02X ", PlainText[k]);
/*加密过程*/
printf("\n**************开始加密****************");
for (int i = 0; i < 4; i++)
{
CipherKey_word[i] = CharToWord(CipherKey, 4 * i);
}
ExtendCipherKey(CipherKey_word, 0);
AddRoundKey(PlainText, CipherKey);
for (int i = 0; i < 16; i++)
{
printf("%2X ", PlainText[i]);
}
cout << endl;
cout << endl;
int ii = 0;
cout << endl;
for (int i = 1; i < 10; i++)
{
cout << "第" << i << "轮循环" << endl;
unsigned char tmp[16] = {};
SubBytes(PlainText, tmp, 16);
for (int i = 0; i < 16; i++)
{
PlainText[i] = tmp[i];
}
cout << "字节代换:" << endl;
for (int i = 0; i < 16; i++)
{
printf("%2X ", PlainText[i]);
}
cout << endl;
ShiftRows(PlainText);
cout << "行移位:" << endl;
for (int i = 0; i < 16; i++)
{
printf("%2X ", PlainText[i]);
}
cout << endl;
MixColumns(PlainText, tmp);
for (int i = 0; i < 16; i++)
{
PlainText[i] = tmp[i];
}
cout << "列混淆:" << endl;
for (int i = 0; i < 16; i++)
{
printf("%2X ", PlainText[i]);
}
cout << endl;
//以下修改 轮密钥加:
unsigned char temp_key[16] = {};
for (ii = 0; ii < 4; ii++)
{
WordToChar(CipherKey_word[4 * i + ii], temp_key + 4 * ii);
}
for (int i = 0; i < 16; i++)
{
printf("%2X ", temp_key[i]);
}
cout << endl;
AddRoundKey(PlainText, temp_key);
cout << "轮密钥加:" << endl;
for (int i = 0; i < 16; i++)
{
printf("%2X ", PlainText[i]);
}
cout << endl;
cout << endl;
}
unsigned char tmp[16] = {};
SubBytes(PlainText, tmp, 16);
for (int i = 0; i < 16; i++)
{
PlainText[i] = tmp[i];
}
ShiftRows(PlainText);
unsigned char temp_key[16] = {};
for (int ii = 0; ii < 4; ii++)
{
WordToChar(CipherKey_word[40 + ii], temp_key + 4 * ii);
}
AddRoundKey(PlainText, temp_key);
for (int i = 0; i < 16; i++)
{
printf("%2X ", PlainText[i]);
}
cout << endl;
/*解密过程*/
printf("\n\n**************开始解密***************");
}