注意!
注意!
注意!
-----这里默认明文,密钥都是128位(其中密文,密钥,明文都以字节码的16进制展示)-----
--------------------------这里字节码都是用变量类型 unsigned char-----------------------------------
加密过程讲解:
1.过程一
首先初始化明文和密钥,将明文和密钥按照4*4的矩阵从上往下从左往右摆放,每个矩阵元素占领一个字节
2.过程二
将初始化后的明文矩阵和密钥矩阵按照相同位置的进行异或运算
3.过程三
经过9轮的(字节替换,行移位,列混合,轮密钥加)和一次(字节替换,行移位,轮密钥加)的运算得到密文。(其实就是第10轮不做列混合运算)。
细节描述
1.轮密钥加
也就是将当前轮次的密文和当前轮次的密钥进行异或操作(相同结果为0,不同为1。例如1异或1=0,1异或0=1,0异或0=0,0异或1=1 )
假设这是密文
这是密钥
异或以后结果
运算过程举例讲解:
(例一)
32^2b=19
32是16进制,对应的2进制是0011 0010
2b是16进制,对应的2进制是0010 1011
按位逐个异或结果是0001 1001,对应16进制也就是19
例二
88^28=a0
88二进制对应16进制为1000 1000
28二进制对应16进制为0010 1000
异或后就是1010 0000,对应16进制也就是a0
2.字节替换
字节替换也就是通过当前密文替换成S盒的内容
字节的左边4位代表s盒的行号,右边4位代表s盒的列号
替换前密文
替换后密文
替换举例:
(例一)
19-->d4
1就是第一行
9就是第九列
查表得知结果为d4
(例一)
a0-->e0
a就是第a行
0就是第0列
查表得知结果为e0
这个是s盒内容(可以根据公式生成,这里就不演示公式生成过程,一般都直接查下列的表)
下面给出可复制的内容
sBox = {
{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}
};
3.行移位
移位前:
移位后:
这里的移位就是从第0行到第3行,第几行就往左边移动几格。
第0行移动0格!第1行移动1格!第2行移动2格!第3行移动3格!
4.列混合
这里的列混合是一个特殊的矩阵乘法运算
通常矩阵的乘法的第i行第j列的结果是Ai0*B0j+Ai1*B1J+... ...+Ain*Bnj
这里的乘法是一个特殊的乘法,加法用的异或运算
在这个列混合中引入一个列混合的矩阵(这个是固定的),下面就是一个列混合矩阵表
下面给出可复制的内容
ColumnMixtureMatrix = {
{0x02,0x03,0x01,0x01},
{0x01,0x02,0x03,0x01},
{0x01,0x01,0x02,0x03},
{0x03,0x01,0x01,0x02}
};
过程讲解:
这是乘法的举例
这里我用一种简单的写法说明:
注意!注意!注意! 加法做异或运算
当前面是01的时候乘法直接等于右边部分。举例:01*30=30和01*5d=5d
当前面是02的时候,分两种情况:
当右边字节码的最高位为1时候:直接把右边的字节码左移一位然后和1b(固定不变的)做异或运算。
举例:计算02*d4,d4的二进制表示为1101 0100
因为最高位(最左边位)为1,左移移位得到1010 1000
1b的二进制为0001 1011,异或后结果就是1011 0011
当右边字节码的最高位为0时候,直接左移一位即可
举例:计算02*7f,7f的二进制为0111 1111
最高位(最左边位)为0,直接左移一位得到1111 1110
当前面是03的时候:
即03*(xx)的模型,可以写成(02+01)*(xx)也就是02*(xx)+(xx) {满足分配律}
举例:03*bf = 02*bf+bf
02*bf按照上一条规则运算得出65转换二进制位0110 0101,然后加bf(1011 1111)得到da(1101 1010)
这里以02*d4+03*bf+01*5d+01*30 = 04为例子进行计算
02*d4=b3:
d4二进制:1101 0100
第一位为1:左移得到1010 1000
27的二进制 0001 1011
异或结果为: 1011 0011(b3)
03*bf=da
转换成02*bf+bf
bf二进制:1011 1111
第一位为1:左移得到0111 1110
27的二进制 0001 1011
bf的二进制 1011 1111
异或结果为: 1101 1010(da)
01*5d=5d和01*30=30
这里前面是01,不需要变
最后b3+da+5d+30
b3: 1011 0011
da: 1101 1010
5d: 0101 1101
30: 0011 0000
异或结果:0000 0100(04)
5.轮密钥生成
下图是轮密钥生成表(cipher key为初始密钥,后面为轮密钥)
生成规则如下
当密钥的列号n是4的倍数:
以第n=4列(第一轮)为例子:
1.字循环
首先将前一列(n-1=3列)向上循环移动一格:
09 cf
cf -->4f
4f 3c
3c 09
2.字节替换
将循环后的内容查s盒替换
cf 8a
4f -->84
3c eb
09 01
3.轮常量异或
将替换后的内容和轮常量,n-4(4-4)=0列密钥内容进行异或
8a^01^2b=a0
84^00^7e=fa
eb^00^15=fe
01^00^16=17
当密钥的列号n不是4的倍数:
直接将n-1列和n-4列的结果进行异或即可(这里以第5列为例):
a0^28=88
fa^ae=54
fe^d2=2c
17^a6=b1
轮常量矩阵表
下面为可复制内容:
roundConstant = {
{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
};
代码实现
全局参数:
vector<vector<unsigned char>>key;//密钥
vector<vector<unsigned char>>Plaintext;//明文
vector<vector<unsigned char>>ciphertext;//密文
vector<vector<unsigned char>>sBox;//s盒
vector<vector<unsigned char>>ColumnMixtureMatrix;//列混合矩阵
vector<vector<unsigned char>>roundConstant;//轮常量矩阵
公共函数
//字节码转换(将16进制的字符转换成unsigned char类型)
unsigned char convert(string str){
unsigned char ret = 0;
if (str[0]<='9'){
ret = (str[0]-'0')*16;
}else{
ret = (str[0]-'a'+10)*16;
}
if (str[1]<='9'){
ret += (str[1]-'0');
}else{
ret += (str[1]-'a'+10);
}
return ret;
}
//字节替换
unsigned char subByte(unsigned char chr){
int row = (chr>>4)&0xf;
int col = chr&0xf;
return sBox[row][col];
}
密钥相关函数:
//输入密钥(将字节码以16进制的字符串输入,然后通过convert函数转换字节码)
void enterKey(){
for(int i=0;i<4;++i){
for (int j = 0; j < 4; ++j) {
string str;cin>>str;
key[j][i] = convert(str);
}
}
}
//密钥扩展
void expandKey(int n){
//第一列扩展
for (int i = 0; i < 4; ++i) {
//左移
unsigned char temp = key[(i+1)%4][4*n-1];
//字节代换
temp = subByte(temp);
//轮常量异或
int a = key[i][4*(n-1)];
int b = temp;//字节替换
int c = roundConstant[i][n-1];//轮常量
key[i][4*n] = a^b^c;
}
for (int i = 1; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
key[j][4*n+i] = key[j][4*n+i-4]^key[j][4*n+i-1];
}
}
}
初始化函数
void init(){
//初始化轮密钥矩阵大小
key.resize(4,vector<unsigned char>(44));
//初始化明文矩阵
Plaintext.resize(4,vector<unsigned char >(4));
//初始化密文矩阵
ciphertext.resize(4,vector<unsigned char>(44));
//初始化s盒
sBox.resize(16,vector<unsigned char >(16));
//写入列混合矩阵
ColumnMixtureMatrix = {
{0x02,0x03,0x01,0x01},
{0x01,0x02,0x03,0x01},
{0x01,0x01,0x02,0x03},
{0x03,0x01,0x01,0x02}
};
//轮常量初始化
roundConstant = {
{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
};
sBox = {
{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 enterPlaintext(){//输入明文(输入字节码的16进制字符串自动转化为字节码)
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
string str;
cin>>str;
Plaintext[j][i] = convert(str);
}
}
cout<<endl;
}
加密过程
//初始变换(轮函数前的异或运算)
void initRound(){
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
ciphertext[i][j] = Plaintext[i][j]^key[i][j];
}
}
printf("after initRound\n");
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%02x ",ciphertext[i][j]);
}
cout<<endl;
}
}
void subBytes(int n){//第n次的轮字节替换
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
ciphertext[i][n*4+j] = subByte(ciphertext[i][n*4+j-4]);
}
}
printf("No %d subBytes\n",n);
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%02x ",ciphertext[i][n*4+j]);
}
cout<<endl;
}
}
void shiftRows(int n){//第n轮行移位
vector<vector<unsigned char>>temp(4);//拷贝一份字节替换后的密文方便移位操作
for (int i = 0; i < 4; ++i) {
temp[i] = vector<unsigned char>(4);
for (int j = 0; j < 4; ++j) {
temp[i][j] = ciphertext[i][4*n+j];
}
}
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
ciphertext[i][4*n+j] = temp[i][(j+i)%4];
}
}
printf("No %d shiftRows\n",n);
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%02x ",ciphertext[i][n*4+j]);
}
cout<<endl;
}
}
unsigned char mix2(unsigned char chr){//列混合乘2模型
if ((chr>>7&0xf)==0){
return chr<<1;
}else{
return chr<<1^27;
}
}
unsigned char mix3(unsigned char chr){//列混合乘3模型
return mix2(chr)^chr;
}
unsigned char mix(unsigned char t,unsigned char chr){
if (t==2){
return mix2(chr);
}else if (t==3){
return mix3(chr);
}else{
return chr;
}
}
unsigned char minx0(int n,int row, int col) {
unsigned char ret = 0;
for (int k = 0; k < 4; ++k) {
auto a = ColumnMixtureMatrix[row][k],b = ciphertext[k][n*4+col];//这里用于调试的
auto temp = mix(ColumnMixtureMatrix[row][k],ciphertext[k][n*4+col]);
ret^= temp;
}
return ret;
}
void mixColumns(int n){//列混合
vector<vector<unsigned char >>temp(4,vector<unsigned char>(4));
for (int col = 0; col < 4; ++col) {
for (int row = 0; row < 4; ++row) {//按照列的顺序
temp[row][col] = minx0(n,row,col);
//ciphertext[row][n*4+col] = minx0(n,row,col);
}
}
for (int row = 0; row < 4; ++row) {
for (int col = 0; col < 4; ++col) {
ciphertext[row][n*4+col] = temp[row][col];
}
}
printf("No %d mixColumns\n",n);
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%02x ",ciphertext[i][n*4+j]);
}
cout<<endl;
}
}
void addRoundKey(int n){
expandKey(n);//扩展第n次密钥
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
ciphertext[i][n*4+j]^=key[i][n*4+j];
}
}
printf("No %d addRoundKey\n",n);
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%02x ",ciphertext[i][n*4+j]);
}
cout<<endl;
}
}
void run(){//开始加密
initRound();//初始化
for (int i = 1; i <= 9; ++i) {//9轮迭代
subBytes(i);
shiftRows(i);
mixColumns(i);
addRoundKey(i);
}
subBytes(10);
shiftRows(10);
addRoundKey(10);
}
主函数
int main(){
printf("%02x", convert("17")^ convert("a6"));
init();//初始化内存
cout<<"enter key:";
enterKey();//输入密钥
cout<<"enter plaintext:";
enterPlaintext();//输入明文
run();//开始加密
cout<<endl;
for(int i=0;i<4;++i){//输出加密后结果
for (int j = 40; j < 44; ++j) {
printf("%02x ",ciphertext[i][j]);
}
cout<<endl;
}
}
全部函数
#include <bits/stdc++.h>
using namespace std;
//===============================全局参数==============================
vector<vector<unsigned char>>key;//密钥
vector<vector<unsigned char>>Plaintext;//明文
vector<vector<unsigned char>>ciphertext;//密文
vector<vector<unsigned char>>sBox;//s盒
vector<vector<unsigned char>>ColumnMixtureMatrix;//列混合矩阵
vector<vector<unsigned char>>roundConstant;//轮常量矩阵
//==================================公共函数=================================
//字节码转换
unsigned char convert(string str){
unsigned char ret = 0;
if (str[0]<='9'){
ret = (str[0]-'0')*16;
}else{
ret = (str[0]-'a'+10)*16;
}
if (str[1]<='9'){
ret += (str[1]-'0');
}else{
ret += (str[1]-'a'+10);
}
return ret;
}
//字节替换
unsigned char subByte(unsigned char chr){
int row = (chr>>4)&0xf;
int col = chr&0xf;
return sBox[row][col];
}
//==================================密钥相关=================================
//输入密钥
void enterKey(){
for(int i=0;i<4;++i){
for (int j = 0; j < 4; ++j) {
string str;cin>>str;
key[j][i] = convert(str);
}
}
}
//密钥扩展
void expandKey(int n){
//第一列扩展
for (int i = 0; i < 4; ++i) {
//左移
unsigned char temp = key[(i+1)%4][4*n-1];
//字节代换
temp = subByte(temp);
//轮常量异或
//key[i][4*n] = key[i][4*n-4]^temp^roundConstant[i][n];
//---
int a = key[i][4*(n-1)];
int b = temp;//字节替换
int c = roundConstant[i][n-1];//轮常量
key[i][4*n] = a^b^c;
}
for (int i = 1; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
key[j][4*n+i] = key[j][4*n+i-4]^key[j][4*n+i-1];
}
}
}
//=================================初始化内容===============================
void init(){
//初始化轮密钥矩阵大小
key.resize(4,vector<unsigned char>(44));
//初始化明文矩阵
Plaintext.resize(4,vector<unsigned char >(4));
//初始化密文矩阵
ciphertext.resize(4,vector<unsigned char>(44));
//初始化s盒
sBox.resize(16,vector<unsigned char >(16));
//写入列混合矩阵
ColumnMixtureMatrix = {
{0x02,0x03,0x01,0x01},
{0x01,0x02,0x03,0x01},
{0x01,0x01,0x02,0x03},
{0x03,0x01,0x01,0x02}
};
//轮常量初始化
roundConstant = {
{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
};
sBox = {
{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 enterPlaintext(){
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
string str;
cin>>str;
Plaintext[j][i] = convert(str);
}
}
cout<<endl;
}
//=================================开始加密===============================
//初始变换
void initRound(){
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
ciphertext[i][j] = Plaintext[i][j]^key[i][j];
}
}
printf("after initRound\n");
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%02x ",ciphertext[i][j]);
}
cout<<endl;
}
}
void subBytes(int n){//第n次的轮字节替换
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
ciphertext[i][n*4+j] = subByte(ciphertext[i][n*4+j-4]);
}
}
printf("No %d subBytes\n",n);
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%02x ",ciphertext[i][n*4+j]);
}
cout<<endl;
}
}
void shiftRows(int n){//第n轮行移位
vector<vector<unsigned char>>temp(4);//拷贝一份字节替换后的密文方便移位操作
for (int i = 0; i < 4; ++i) {
temp[i] = vector<unsigned char>(4);
for (int j = 0; j < 4; ++j) {
temp[i][j] = ciphertext[i][4*n+j];
}
}
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
ciphertext[i][4*n+j] = temp[i][(j+i)%4];
}
}
printf("No %d shiftRows\n",n);
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%02x ",ciphertext[i][n*4+j]);
}
cout<<endl;
}
}
unsigned char mix2(unsigned char chr){
if ((chr>>7&0xf)==0){
return chr<<1;
}else{
return chr<<1^27;
}
}
unsigned char mix3(unsigned char chr){
return mix2(chr)^chr;
}
unsigned char mix(unsigned char t,unsigned char chr){
if (t==2){
return mix2(chr);
}else if (t==3){
return mix3(chr);
}else{
return chr;
}
}
unsigned char minx0(int n,int row, int col) {
unsigned char ret = 0;
for (int k = 0; k < 4; ++k) {
auto a = ColumnMixtureMatrix[row][k],b = ciphertext[k][n*4+col];
auto temp = mix(ColumnMixtureMatrix[row][k],ciphertext[k][n*4+col]);
ret^= temp;
}
return ret;
}
void mixColumns(int n){
vector<vector<unsigned char >>temp(4,vector<unsigned char>(4));
for (int col = 0; col < 4; ++col) {
for (int row = 0; row < 4; ++row) {
temp[row][col] = minx0(n,row,col);
//ciphertext[row][n*4+col] = minx0(n,row,col);
}
}
for (int row = 0; row < 4; ++row) {
for (int col = 0; col < 4; ++col) {
ciphertext[row][n*4+col] = temp[row][col];
}
}
printf("No %d mixColumns\n",n);
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%02x ",ciphertext[i][n*4+j]);
}
cout<<endl;
}
}
void addRoundKey(int n){
expandKey(n);//扩展第n次密钥
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
ciphertext[i][n*4+j]^=key[i][n*4+j];
}
}
printf("No %d addRoundKey\n",n);
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%02x ",ciphertext[i][n*4+j]);
}
cout<<endl;
}
}
void run(){
initRound();
for (int i = 1; i <= 9; ++i) {
subBytes(i);
shiftRows(i);
mixColumns(i);
addRoundKey(i);
}
subBytes(10);
shiftRows(10);
addRoundKey(10);
}
//=================================主函数运行===============================
int main(){
init();
cout<<"enter key:";
enterKey();
cout<<"enter plaintext:";
enterPlaintext();
run();
cout<<endl;
for(int i=0;i<4;++i){
for (int j = 40; j < 44; ++j) {
printf("%02x ",ciphertext[i][j]);
}
cout<<endl;
}
}
//密钥 2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c
//明文 32 43 f6 a8 88 5a 30 8d 31 31 98 a2 e0 37 07 34
/**
2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c
32 43 f6 a8 88 5a 30 8d 31 31 98 a2 e0 37 07 34
*/
如有错误请指正!