c++实现ASE加密


注意!
注意!
注意!
-----这里默认明文,密钥都是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=3001*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

*/

如有错误请指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mystic Musings

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值