赞
踩
首先初始化明文和密钥,将明文和密钥按照4*4的矩阵从上往下从左往右摆放,每个矩阵元素占领一个字节
将初始化后的明文矩阵和密钥矩阵按照相同位置的进行异或运算
经过9轮的(字节替换,行移位,列混合,轮密钥加)和一次(字节替换,行移位,轮密钥加)的运算得到密文。(其实就是第10轮不做列混合运算)。
也就是将当前轮次的密文和当前轮次的密钥进行异或操作(相同结果为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
字节替换也就是通过当前密文替换成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} };
移位前:
移位后:
这里的移位就是从第0行到第3行,第几行就往左边移动几格。
第0行移动0格!第1行移动1格!第2行移动2格!第3行移动3格!
这里的列混合是一个特殊的矩阵乘法运算
通常矩阵的乘法的第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)
下图是轮密钥生成表(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 */
如有错误请指正!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。