本文借鉴了下文。
https://blog.csdn.net/weixin_46395886/article/details/113060749?spm=1001.2014.3001.5506
并修改和增加了如下功能:
修改列移位,上文的操作为列移位,本代码更正为行移位。
增加原文分快和补位功能:上文的明文只能是16位数,本文的代码可以输入任意位数明文。
下面详细介绍AES原理和对应代码
完整代码在最后
本实验采用的编程语言为C++。将AES加解密的操作封装为名为”AES”的类。
下面首先简单介绍类”AES”,再逐个介绍其他实验内容。
#include
#include
#include
using namespace std;
typedef unsigned char byte;//重命名 unsigned char
struct word
{byte wordKey[4];//word x,x可存储4个byte数据,索引:x.wordkey[i]
};class AES
{
public:AES(int sizeplain){SizePlain = sizeplain;initRcon();//Rcon函数};// ~AES();void setCipherKey(byte key[]);//初始化密钥including密钥扩展void setPlainText(byte plain[]);//转换明文数据类型//密钥扩展void keyExpansion(byte key[], word w[]);word rotWord(word w);// RotByte(a,b,c,d) = (b,c,d,a)word subWord(word w);// S盒变换word wordXOR(word w1, word w2);//异或//加解密void encryption();//10轮加密算法void addRoundKey(word in[], int round);//加密机:密钥与输入异或void subByte(word in[]);//字节替代void shiftRows(word in[]);//行移位void mixColumn(word in[]);//列混淆byte GFMultiplyByte(byte L, byte R);void decryption();//10轮解密void invShiftRows(word in[]);//逆行移位void invSubByte(word in[]);//逆字节替代void invMixColumn(word in[]);//逆列混淆void initRcon();//构造函数,初始化Rcon[]void showWord16(word w[], int len);//输出格式:16进制数void showWordChar(word w[],int len);//输出格式:字符void showMesage(byte p[],word w[],word c[],int l3, word d[],int l4);//格式化输出void CoveringPlain(byte plain[]);void InverCover(word in[]);//去补位//成员变量int NumGroup;//明文分块后的块的数量int DifferValue;//补位的数值int SizePlain;//明文长度byte CoverPlain[200];//补位后的明文word InCoverdeCipherText[16];//解密后再去补位byte cipherKey[16];word plainText[4];//明文word cipherText[4];//密文word deCipherText[4];//解密后输出static const int Nb=4, Nk=4, Nr=10;word Rcon[11];word wordKey[44];//密钥static const byte SBox[16][16];//S盒static const byte invSBox[16][16];//逆S盒static const byte mixColumnMatrix[4][4];//列混淆常数矩阵static const byte invmixColumnMatrix[4][4];//逆列混淆常数矩阵
};
字节替代变换
字符串的补位
原理:AES属于分组加密算法,即把明文分为多段的独立明文块再依次进行加密,每个明文块的长度是128bit,对于长度不是128bit的整数倍的明文,其最后一个明文块不足128bit,这时需要对明文进行填充,使最后一个明文块凑够128bit,经过调查[1],填充数据的内容有至少三种选择,我们这里选择PKCS5Padding(默认)填充模式,其内容是如果明文块少于128bit,在明文块末尾补足相应数量的字符,且每个字节的值等于缺少的字符数。
综上,x补位的结果应该是”abcdefghijklmn22”
代码实现:
“AES”类内完成补位操作的成员函数代码
// 补位
void AES::CoveringPlain(byte plain[]){NumGroup = SizePlain/16 + 1;DifferValue = NumGroup*16 - SizePlain;//补位for (int i = 0; i < SizePlain; i++) {CoverPlain[i] = plain[i];}for (int i = SizePlain; i < NumGroup*16; i++) {CoverPlain[i] = DifferValue + '0';}}
测试结果:
字符串的转码
原理:即编码:将输入字符转为数字,我们采用ASCII码进行转码。即用字符串对应的ASCII码进行编码
测试代码实现:
说明:将已经补位后的明文作为输入,输出其ASCII码对应的16进制数。事实上是把字符ASCII的16进制数作为我们的转码结果参与后面的操作。
测试结果:正确,a的ASCII码对应的16进制数是61。
字节替代
原理:字符转码后为8位16进制数,把高4位作为行值,低4位作为列值,取出S盒中对应的行列的元素作为输出,即为字节替代。
代码:
“AES”类内完成字节替代操作的成员函数代码
//字节替代
void AES::subByte(word in[]){int i,j;byte L, R;for(i=0; i<4; i++){for(j=0; j<4; j++){L = in[i].wordKey[j] >> 4;R = in[i].wordKey[j] & 0x0f;in[i].wordKey[j] = SBox[L][R];}}
}
测试代码
测试结果:查表验证正确
逆字节替代变换
逆字节替代
原理:是字节替代的逆过程,过程为:把输入数据的高4位作为行值,低4位作为列值,取出逆S盒中对应的行列的元素作为输出。
代码:
“AES”类内完成逆字节替代操作的成员函数代码
//逆字节替代
void AES::invSubByte(word in[]){int i,j;byte L, R;for(i=0; i<4; i++){for(j=0; j<4; j++){L = in[i].wordKey[j] >> 4;R = in[i].wordKey[j] & 0x0f;in[i].wordKey[j] = invSBox[L][R];}}
}
测试代码
逆转码
原理:ASCII码转为字符,在C++里字符就是以ASCII码的形式存储的,二者转换对于C++很容易实现。
测试代码:
这里有必要介绍两个成员函数:
void showWord16(word w[], int len);//输出w(w的数据类型为unsigned char)的ASCII码的十六进制形式。
void showWordChar(word w[],int len);//以字符的形式输出w(w的数据类型为unsigned char)。
测试结果:正确,回到了转码前补位后的结果。
去补位
原理:根据数组的最后一位和之前位的关系决定补位的数量和数值,从而去补位。
第16位和第15位不同,认为之前没有补位。
第16位和第16-j位相同,且值都为j,那么去掉数组的后j位。
代码:
“AES”类内完成去补位操作的成员函数代码
//去补位
void AES::InverCover(word in[]){//初始化for (int i = 0; i < 4*NumGroup; i++)for (int j = 0; j < 4; j++)InCoverdeCipherText[i].wordKey[j] = in[i].wordKey[j];for (int i = 0; i < 4*NumGroup; i++) {for (int j = 0; j < 4; j++) {if(i*4+j>=SizePlain){InCoverdeCipherText[i].wordKey[j] = '\0';//抹去补位}}}
}
测试代码:正确,与明文相同。
行移位变换和逆行移位变换
行移位变换
原理:(1)将矩阵的第i行左移i个字节(i∈[0,3])
代码
“AES”类内完成行移位变换操作的成员函数代码
//行移位
void AES::shiftRows(word in[]){int i,j;word temp[4];for(i=0; i<4; i++){for(j=0; j<4; j++){
// temp[i].wordKey[j] = in[(i+j)%4].wordKey[j];temp[i].wordKey[j] = in[i].wordKey[(i+j)%4];}}for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] = temp[i].wordKey[j];}}
}
测试代码
结果测试:正确
逆行移位变换
原理:将第i行(i∈[0,3])的元素循环右移i个字节
代码:
“AES”类内完成逆行移位变换操作的成员函数代码
//逆行移位
void AES::invShiftRows(word in[]){int i,j;word temp[4];for(i=0; i<4; i++){for(j=0; j<4; j++){
// temp[i].wordKey[j] = in[(i-j+4)%4].wordKey[j];temp[i].wordKey[j] = in[i].wordKey[(j-i+4)%4];}}for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] = temp[i].wordKey[j];}}
}
测试代码
测试结果:正确
列混合和逆列混合
列混合
原理:给输入矩阵乘以一个字节矩阵,计算过程如下,其中s’是混合后矩阵,s是输入矩阵:
代码:
“AES”类内完成列混淆操作的成员函数代码:列混淆由两部分组成,除了矩阵乘法外,还要定义GF(2^8)上的运算。
列混淆代码1矩阵乘法
// GF(2^8)运算
byte AES::GFMultiplyByte(byte L, byte R){byte temp[8];byte result = 0x00;temp[0] = L;int i;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;
}
测试代码
测试结果:正确,与手算结果一致
逆列混合
原理:是列混合的逆操作,计算过程如下,重要的是等式左边第一个常数矩阵的取值。
代码:
“AES”类内完成逆列混淆操作的成员函数代码
//逆列混淆
void AES::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];}}
}
测试代码
测试结果:结果与列混淆之后,逆行移位后一样,正确。
原始密钥:
取值:“abcdefghijklmnop”
存储和扩展:细节如下。
代码:分以下四部分组成。
主体代码
// 密钥扩展
void AES::keyExpansion(byte key[], word w[]){int i=0;int j,k;word temp;while(i < Nk){for(j=0; j<4; j++){w[j].wordKey[i] = key[j+4*i];}i++;}i = Nk;while(i < Nb*(Nr+1)){temp = w[i-1];if((i%Nk) == 0){temp = rotWord(temp);temp = subWord(temp);temp = wordXOR(temp, Rcon[i / Nk]);}else if(Nk > 6 && (i%Nk) == 4){temp = subWord(temp);}w[i] = wordXOR(w[i - Nk], temp);i++;}
}
RotByte函数
S盒变换
异或
结果(16进制数)
测试代码
测试结果:
代码:
加密机:密钥与输入异或
//加密
void AES::addRoundKey(word in[], int round){int i, j;for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] ^= wordKey[i+4*round].wordKey[j];}}
}
十轮加密:加密的整体代码
//10轮加密
void AES::encryption(){int i, j ,k;for(i=0; i<4; i++){for(j=0; j<4; j++){cipherText[i].wordKey[j] = plainText[i].wordKey[j];}}// round functionaddRoundKey(cipherText, 0);for(i=1; i<10; i++){subByte(cipherText);shiftRows(cipherText);mixColumn(cipherText);addRoundKey(cipherText, i);}subByte(cipherText);shiftRows(cipherText);addRoundKey(cipherText, 10);
}
测试:
测试代码:其中不只有加密的完整操作也包括了完整解密的操作。
测试结果:能有密文解出密文,可见加解密操作正确。
解密机
原理:AES解密算法的初始轮和最后一轮(第10轮)的轮密钥分别是加密算法的最后一轮(第10轮)和初始轮的轮密钥,解密算法的第1轮到第9轮的轮密钥分别是加密算法的第9轮到第1轮的轮密钥经逆列混合变换后得到的。具体如下:
代码:十轮解密主体代码如下,具体的逆行移位、逆列混淆等操作前文已经介绍了,这里不再赘述。
完整代码:
#include
#include
#include
using namespace std;
typedef unsigned char byte;//重命名 unsigned char
struct word
{byte wordKey[4];//word x,x可存储4个byte数据,索引:x.wordkey[i]
};class AES
{
public:AES(int sizeplain){SizePlain = sizeplain;initRcon();//Rcon函数};// ~AES();void setCipherKey(byte key[]);//初始化密钥including密钥扩展void setPlainText(byte plain[]);//转换明文数据类型//密钥扩展void keyExpansion(byte key[], word w[]);word rotWord(word w);// RotByte(a,b,c,d) = (b,c,d,a)word subWord(word w);// S盒变换word wordXOR(word w1, word w2);//异或//加解密void encryption();//10轮加密算法void addRoundKey(word in[], int round);//加密机:密钥与输入异或void subByte(word in[]);//字节替代void shiftRows(word in[]);//行移位void mixColumn(word in[]);//列混淆byte GFMultiplyByte(byte L, byte R);void decryption();//10轮解密void invShiftRows(word in[]);//逆行移位void invSubByte(word in[]);//逆字节替代void invMixColumn(word in[]);//逆列混淆void initRcon();//构造函数,初始化Rcon[]void showWord16(word w[], int len);//输出格式:16进制数void showWordChar(word w[],int len);//输出格式:字符void showMesage(byte p[],word w[],word c[],int l3, word d[],int l4);//格式化输出void CoveringPlain(byte plain[]);void InverCover(word in[]);//去补位//成员变量int NumGroup;//明文分块后的块的数量int DifferValue;//补位的数值int SizePlain;//明文长度byte CoverPlain[200];//补位后的明文word InCoverdeCipherText[16];//解密后再去补位byte cipherKey[16];word plainText[4];//明文word cipherText[4];//密文word deCipherText[4];//解密后输出static const int Nb=4, Nk=4, Nr=10;word Rcon[11];word wordKey[44];//密钥static const byte SBox[16][16];//S盒static const byte invSBox[16][16];//逆S盒static const byte mixColumnMatrix[4][4];//列混淆常数矩阵static const byte invmixColumnMatrix[4][4];//逆列混淆常数矩阵
};
//去补位
void AES::InverCover(word in[]){//初始化for (int i = 0; i < 4*NumGroup; i++)for (int j = 0; j < 4; j++)InCoverdeCipherText[i].wordKey[j] = in[i].wordKey[j];for (int i = 0; i < 4*NumGroup; i++) {for (int j = 0; j < 4; j++) {if(i*4+j>=SizePlain){InCoverdeCipherText[i].wordKey[j] = '\0';//抹去补位}}}
}
//展示结果的16进制
void AES::showWord16(word w[], int len){int i,j;for(i=0; iword(矩阵)
void AES::setPlainText(byte plain[]){int i;for(i=0; i<16; i++){plainText[i/4].wordKey[i%4] = plain[i];}
}// 读取密钥
void AES::setCipherKey(byte key[]){int i;for(i=0; i<16; i++){cipherKey[i] = key[i];}keyExpansion(cipherKey, wordKey);
}// 初始化Rcon
void AES::initRcon(){int i,j;for(i=0; i<4; i++)for(j=0; j<4; j++){Rcon[i].wordKey[j] = 0x0;}Rcon[1].wordKey[0] = 0x01;Rcon[2].wordKey[0] = 0x02;Rcon[3].wordKey[0] = 0x04;Rcon[4].wordKey[0] = 0x08;Rcon[5].wordKey[0] = 0x10;Rcon[6].wordKey[0] = 0x20;Rcon[7].wordKey[0] = 0x40;Rcon[8].wordKey[0] = 0x80;Rcon[9].wordKey[0] = 0x1b;Rcon[10].wordKey[0] = 0x36;
}// 初始化列混淆常数矩阵
const byte AES::mixColumnMatrix[4][4] = {{0x02, 0x03, 0x01, 0x01},{0x01, 0x02, 0x03, 0x01},{0x01, 0x01, 0x02, 0x03},{0x03, 0x01, 0x01, 0x02}
};
// 初始化逆列混淆常数矩阵
const byte AES::invmixColumnMatrix[4][4] = {{0x0e, 0x0b, 0x0d, 0x09},{0x09, 0x0e, 0x0b, 0x0d},{0x0d, 0x09, 0x0e, 0x0b},{0x0b, 0x0d, 0x09, 0x0e}
};// 初始化S盒
const byte AES::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}
};
// 初始化逆S盒
const byte AES::invSBox[16][16] = {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
};// 密钥扩展
void AES::keyExpansion(byte key[], word w[]){int i=0;int j,k;word temp;while(i < Nk){for(j=0; j<4; j++){w[j].wordKey[i] = key[j+4*i];}i++;}i = Nk;while(i < Nb*(Nr+1)){temp = w[i-1];if((i%Nk) == 0){temp = rotWord(temp);temp = subWord(temp);temp = wordXOR(temp, Rcon[i / Nk]);}else if(Nk > 6 && (i%Nk) == 4){temp = subWord(temp);}w[i] = wordXOR(w[i - Nk], temp);i++;}
}// 扩展密钥——RotByte(a,b,c,d) = (b,c,d,a)
word AES::rotWord(word w){int i;word temp;for(i=0; i<4; i++){temp.wordKey[(i+3) % 4] = w.wordKey[i];}return temp;
}
// 扩展密钥——S盒变换
word AES::subWord(word w){int i;byte L, R;for(i=0; i<4; i++){L = w.wordKey[i] >> 4;R = w.wordKey[i] & 0x0f;w.wordKey[i] = SBox[L][R];}return w;
}
// 扩展密钥——异或
word AES::wordXOR(word w1, word w2){int i;word temp;for(i=0; i<4; i++){temp.wordKey[i] = w1.wordKey[i] ^ w2.wordKey[i];}return temp;
}//10轮加密
void AES::encryption(){int i, j ,k;for(i=0; i<4; i++){for(j=0; j<4; j++){cipherText[i].wordKey[j] = plainText[i].wordKey[j];}}// round functionaddRoundKey(cipherText, 0);for(i=1; i<10; i++){subByte(cipherText);shiftRows(cipherText);mixColumn(cipherText);addRoundKey(cipherText, i);}subByte(cipherText);shiftRows(cipherText);addRoundKey(cipherText, 10);
}//字节替代
void AES::subByte(word in[]){int i,j;byte L, R;for(i=0; i<4; i++){for(j=0; j<4; j++){L = in[i].wordKey[j] >> 4;R = in[i].wordKey[j] & 0x0f;in[i].wordKey[j] = SBox[L][R];}}
}//行移位
void AES::shiftRows(word in[]){int i,j;word temp[4];for(i=0; i<4; i++){for(j=0; j<4; j++){
// temp[i].wordKey[j] = in[(i+j)%4].wordKey[j];temp[i].wordKey[j] = in[i].wordKey[(i+j)%4];}}for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] = temp[i].wordKey[j];}}
}//列混淆
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];}}
}// GF(2^8)运算
byte AES::GFMultiplyByte(byte L, byte R){byte temp[8];byte result = 0x00;temp[0] = L;int i;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::addRoundKey(word in[], int round){int i, j;for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] ^= wordKey[i+4*round].wordKey[j];}}
}//解密
void AES::decryption(){int i, j, k;for(i=0; i<4; i++){for(j=0; j<4; j++){deCipherText[i].wordKey[j] = cipherText[i].wordKey[j];}}addRoundKey(deCipherText, 10);for(i=9; i>0; i--){invShiftRows(deCipherText);invSubByte(deCipherText);addRoundKey(deCipherText, i);invMixColumn(deCipherText);}invShiftRows(deCipherText);invSubByte(deCipherText);addRoundKey(deCipherText, 0);
}
//逆行移位
void AES::invShiftRows(word in[]){int i,j;word temp[4];for(i=0; i<4; i++){for(j=0; j<4; j++){
// temp[i].wordKey[j] = in[(i-j+4)%4].wordKey[j];temp[i].wordKey[j] = in[i].wordKey[(j-i+4)%4];}}for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] = temp[i].wordKey[j];}}
}
//逆字节替代
void AES::invSubByte(word in[]){int i,j;byte L, R;for(i=0; i<4; i++){for(j=0; j<4; j++){L = in[i].wordKey[j] >> 4;R = in[i].wordKey[j] & 0x0f;in[i].wordKey[j] = invSBox[L][R];}}
}
//逆列混淆
void AES::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];}}
}int main(int argc, char const *argv[])
{// 测试1:字节替代变换和逆字节替代变换cout<<"------------------test1:字节替代变换和逆字节替代变换-----------------------"<word(矩阵)aesTest1.subByte(aesTest1.plainText);//字节替代for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {printf("%x ",aesTest1.plainText[i].wordKey[j]);}cout<