DES AES SM4 TEA源码

DES:


#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
 
 
typedef bool    (*PSubKey)[16][48];
enum    {ENCRYPT,DECRYPT};             //选择:加密;解密
static bool SubKey[2][16][48];         // 16圈子密钥
static bool Is3DES;                    // 3次DES标志
static char Tmp[256], deskey[16];      //暂存字符串,密钥串
 
 
static void DES(char Out[8], char In[8], const PSubKey pSubKey, bool Type);//标准DES加/解密
static void SetKey(const char* Key, int len);// 设置密钥
static void SetSubKey(PSubKey pSubKey, const char Key[8]);// 设置子密钥
static void F_func(bool In[32], const bool Ki[48]);// f 函数
static void S_func(bool Out[32], const bool In[48]);// S 盒代替
static void Transform(bool *Out, bool *In, const char *Table, int len);// 变换
static void Xor(bool *InA, const bool *InB, int len);// 异或
static void RotateL(bool *In, int len, int loop);// 循环左移
static void ByteToBit(bool *Out, const char *In, int bits);// 字节组转换成位组
static void BitToByte(char *Out, const bool *In, int bits);// 位组转换成字节组
 
 
// Type(选择)—ENCRYPT:加密,DECRYPT:解密
// 输出缓冲区(Out)的长度 >= ((datalen+7)/8)*8,即比datalen大的且是8的倍数的最小正整数
// In 可以= Out,此时加/解密后将覆盖输入缓冲区(In)的内容
// 当keylen>8时系统自动使用3次DES加/解密,否则使用标准DES加/解密.超过16字节后只取前16字节
 
 
//加密解密函数:
bool DES_Act(char *Out,char *In,long datalen,const char *Key,int keylen,bool Type = ENCRYPT);
 
 
 
 
int main()
{
	
	LARGE_INTEGER t1, t2, tc;
	QueryPerformanceFrequency(&tc);
	printf("Frequency: %u/n", tc.QuadPart);
	cout<<endl;
	QueryPerformanceCounter(&t1);
	printf("Begin Time: %u/n", t1.QuadPart);
 	cout<<endl;
	
	
	char plain_text[100]="ABCDEFGH";                         // 设置明文
	char key[100]="ABCDEFGH" ;   // 密钥设置

 
	char encrypt_text[255];                       // 密文
	char decrypt_text[255];                       // 解密文
 
	memset(encrypt_text,0,sizeof(encrypt_text));//memset(a,b,c)函数,在a的地址开始到c的长度的字节都初始化为b
	memset(decrypt_text,0,sizeof(decrypt_text));
 
 
 
    // 进行DES加密:
	DES_Act(encrypt_text, plain_text, sizeof(plain_text), key, sizeof(key), ENCRYPT);
	printf("\nDES加密后的密文:\n");
	printf("%s\n\n",encrypt_text);
 
	// 进行DES解密:
	DES_Act(decrypt_text, encrypt_text, sizeof(plain_text), key, sizeof(key), DECRYPT);
	printf("\n解密后的输出:\n");
	printf("%s",decrypt_text);
 
 
    printf("\n\n");
	getchar();
	
	
	QueryPerformanceCounter(&t2);
    printf("End Time: %u/n", t2.QuadPart);
 	cout<<endl;
 	printf("Lasting Time: %u/n",( t2.QuadPart- t1.QuadPart));
	return 0;
}
 
 
//下面是DES算法中用到的各种表:
 
// 初始置换IP表
const static char IP_Table[64] =
{
	58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
	62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
	57, 49, 41, 33, 25, 17,  9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
    61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
};
 
 
// 逆初始置换IP1表
const static char IP1_Table[64] =
{
	40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
	38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
    36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
	34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41,  9, 49, 17, 57, 25
};
 
 
// 扩展置换E表
static const char Extension_Table[48] =
{
	32,  1,  2,  3,  4,  5,  4,  5,  6,  7,  8,  9,
	 8,  9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
	16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
	24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32,  1
};
 
 
// P盒置换表
const static char P_Table[32] =
{
	16, 7, 20, 21, 29, 12, 28, 17, 1,  15, 23, 26, 5,  18, 31, 10,
	2,  8, 24, 14, 32, 27, 3,  9,  19, 13, 30, 6,  22, 11, 4,  25
};
 
 
// 密钥置换表
const static char PC1_Table[56] =
{
	57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,
	10,  2, 59, 51, 43, 35, 27, 19, 11,  3, 60, 52, 44, 36,
	63, 55, 47, 39, 31, 23, 15,  7, 62, 54, 46, 38, 30, 22,
	14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 28, 20, 12,  4
};
 
 
// 压缩置换表
const static char PC2_Table[48] =
{
	14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
	23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
	41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
	44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
};
 
 
// 每轮移动的位数
const static char LOOP_Table[16] =
{
	1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
 
 
// S盒设计
const static char S_Box[8][4][16] =
{
	// S盒1
	14,	 4,	13,	 1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
	 0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
	 4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
    15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
	// S盒2
    15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
	 3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
	 0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
    13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
	// S盒3
    10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
	13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
	13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
     1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
	// S盒4
     7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
	13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
	10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
     3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
	// S盒5
     2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
	14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
	 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
    11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
	// S盒6
    12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
	10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
	 9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
     4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
	// S盒7
     4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
	13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
	 1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
     6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
	// S盒8
    13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
	 1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
	 7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
     2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
};
 
 
 
//下面是DES算法中调用的函数:
 
// 字节转换函数
void ByteToBit(bool *Out, const char *In, int bits)
{
    for(int i=0; i<bits; ++i)
        Out[i] = (In[i>>3]>>(i&7)) & 1;//In[i/8] 这个作用是取出1个字节:i=0~7的时候就取In[0], i=8~15的时候就取In[1],……
//In[i/8] >> (i%8),是把取出来的1个字节右移0~7位,也就是依次取出那个字节的每一个bit
//整个函数的作用是:把In里面的每个字节依次转换为8个bit,最后的结果存到Out里面
}
 
 
// 比特转换函数
void BitToByte(char *Out, const bool *In, int bits)
{
    memset(Out, 0, bits>>3);//把每个字节都初始化为0
    for(int i=0; i<bits; ++i)
        Out[i>>3] |= In[i]<<(i&7);//i>>3位运算,按位右移三位等于i除以8,i&7按位与运算等于i求余8;
}
 
 
// 变换函数
void Transform(bool *Out, bool *In, const char *Table, int len)
{
    for(int i=0; i<len; ++i)
        Tmp[i] = In[ Table[i]-1 ];
    memcpy(Out, Tmp, len);
}
 
 
// 异或函数的实现
void Xor(bool *InA, const bool *InB, int len)
{
    for(int i=0; i<len; ++i)
        InA[i] ^= InB[i];//异或运算,相同为0,不同为1
}
 
 
// 轮转函数
void RotateL(bool *In, int len, int loop)
{
    memcpy(Tmp, In, loop);//Tmp接受左移除的loop个字节
    memcpy(In, In+loop, len-loop);//In更新即剩下的字节向前移动loop个字节
    memcpy(In+len-loop, Tmp, loop);//左移除的字节添加到In的len-loop的位置
}
 
 
// S函数的实现
void S_func(bool Out[32], const bool In[48])  //将8组,每组6 bits的串,转化为8组,每组4 bits
{
    for(char i=0,j,k; i<8; ++i,In+=6,Out+=4)
	{
        j = (In[0]<<1) + In[5];//取第一位和第六位组成的二进制数为S盒的纵坐标
        k = (In[1]<<3) + (In[2]<<2) + (In[3]<<1) + In[4];//取第二、三、四、五位组成的二进制数为S盒的横坐标
		ByteToBit(Out, &S_Box[i][j][k], 4);
    }
}
 
 
// F函数的实现
void F_func(bool In[32], const bool Ki[48])
{
    static bool MR[48];
    Transform(MR, In, Extension_Table, 48);   //先进行 E 扩展
    Xor(MR, Ki, 48);                          //再异或
    S_func(In, MR);                           //各组字符串分别经过各自的 S 盒
    Transform(In, In, P_Table, 32);           //最后 P 变换
}
 
 
 
// 设置子密钥
void SetSubKey(PSubKey pSubKey, const char Key[8])
{
    static bool K[64], *KL=&K[0], *KR=&K[28]; //将64位密钥串去掉8位奇偶位后,分成两份
    ByteToBit(K, Key, 64);                    //转换格式
    Transform(K, K, PC1_Table, 56);
 
    for(int i=0; i<16; ++i)                   // 由56位密钥产生48位子密钥
	{
        RotateL(KL, 28, LOOP_Table[i]);       //两份子密钥分别进行左移转换
        RotateL(KR, 28, LOOP_Table[i]);
        Transform((*pSubKey)[i], K, PC2_Table, 48);
    }
}
 
 
// 设置密钥
void SetKey(const char* Key, int len)
{
	memset(deskey, 0, 16);
	memcpy(deskey, Key, len>16?16:len);//memcpy(a,b,c)函数,将从b地址开始到c长度的字节的内容复制到a
	SetSubKey(&SubKey[0], &deskey[0]);// 设置子密钥
	Is3DES = len>8 ? (SetSubKey(&SubKey[1], &deskey[8]), true) : false;
}
 
 
// DES加解密函数
void DES(char Out[8], char In[8], const PSubKey pSubKey, bool Type)
{
    static bool M[64], tmp[32], *Li=&M[0], *Ri=&M[32];  //64 bits明文 经过IP置换后,分成左右两份
    ByteToBit(M, In, 64);
    Transform(M, M, IP_Table, 64);
    if( Type == ENCRYPT )                               //加密
	{
        for(int i=0; i<16; ++i)                         //加密时:子密钥 K0~K15
		{
            memcpy(tmp, Ri, 32);
            F_func(Ri, (*pSubKey)[i]);                  // 调用F函数
            Xor(Ri, Li, 32);                            //Li与Ri异或
            memcpy(Li, tmp, 32);
        }
    }
	else                 //解密
	{
        for(int i=15; i>=0; --i)                        // 解密时:Ki的顺序与加密相反
		{
            memcpy(tmp, Li, 32);
            F_func(Li, (*pSubKey)[i]);
            Xor(Li, Ri, 32);
            memcpy(Ri, tmp, 32);
        }
	}
    Transform(M, M, IP1_Table, 64);                     //最后经过逆初始置换IP-1,得到密文/明文
    BitToByte(Out, M, 64);
}
 
 
// DES加解密函数(可以对长明文分段加密)
bool DES_Act(char *Out, char *In, long datalen, const char *Key, int keylen, bool Type)
{
    if( !( Out && In && Key && (datalen=(datalen+7)&0xfffffff8) ) )
		return false;
	SetKey(Key, keylen);
	if( !Is3DES )
	{                                                   // 1次DES
		for(long i=0,j=datalen>>3; i<j; ++i,Out+=8,In+=8)
			DES(Out, In, &SubKey[0], Type);
	}
	else
	{                // 3次DES 加密:加(key0)-解(key1)-加(key0) 解密::解(key0)-加(key1)-解(key0)
		for(long i=0,j=datalen>>3; i<j; ++i,Out+=8,In+=8) {
			DES(Out, In,  &SubKey[0], Type);
			DES(Out, Out, &SubKey[1], !Type);
			DES(Out, Out, &SubKey[0], Type);
		}
	}
	return true;
}

AES:

#include <cstdlib>
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
typedef unsigned char byte;
struct word
{
	byte wordKey[4];
};

class AES
{
public:
	AES(){
		initRcon();
	};
	// ~AES();
	void setCipherKey(byte key[]);
	void setPlainText(byte plain[]);

	//
	void keyExpansion(byte key[], word w[]);
	word rotWord(word w);
	word subWord(word w);
	word wordXOR(word w1, word w2);
	//functions in encryption and decryption
	void encryption();
	void processEncryption();
	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();
	void processDecryption();
	void invShiftRows(word in[]);
	void invSubByte(word in[]);
	void invMixColumn(word in[]);
	void initRcon();
	void showWord(word w[], int len);
	void showMesage();
private:
	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];
	static const byte invSBox[16][16];
	static const byte mixColumnMatrix[4][4];
	static const byte invmixColumnMatrix[4][4];
};

void AES::showWord(word w[], int len){
	int i,j;
	for(i=0; i<len; i++){
		for(j=0; j<4; j++){
			printf("%x ", w[i].wordKey[j]);
		}
	}
	cout<<endl;
}

void AES::showMesage(){
	cout<<"plainText:"<<endl;
	showWord(plainText, 4);
	cout<<"wordKey:"<<endl;
	showWord(wordKey, Nb*(Nr+1));
	cout<<"cipherText:"<<endl;
	showWord(cipherText, 4);
	cout<<"deCipherText:"<<endl;
	showWord(deCipherText, 4);
}
// initialize the plainText--trans plaintext from vector to state_matrix
void AES::setPlainText(byte plain[]){
	int i;
	for(i=0; i<16; i++){
		plainText[i/4].wordKey[i%4] = plain[i];
	}
}

//initialize the key--from vector to state_matrix
void AES::setCipherKey(byte key[]){
	int i;
	for(i=0; i<16; i++){
		cipherKey[i] = key[i];
	}
	keyExpansion(cipherKey, wordKey);
}

//initialize the 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;
}

//initialize the const of mixColumn and invMixColumn
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}
};

//initialize SBox
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}
};
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
};

//keyExpansion-get the round key
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++;
	}
}

// some sector in keyExpansion
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;
}

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;
}

//encryption
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 function
	addRoundKey(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];
		}
	}
	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];
		}
	}
}

//forexample: 0xaf * 0x25
byte AES::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::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];
		}
	}
}

//decryption
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];
		}
	}
	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[])
{
	
	LARGE_INTEGER t1, t2, tc;
	QueryPerformanceFrequency(&tc);
	printf("Frequency: %u/n", tc.QuadPart);
	cout<<endl;
	QueryPerformanceCounter(&t1);
	printf("Begin Time: %u/n", t1.QuadPart);
 	cout<<endl;
	
	
	int i;
    //设置明文和密钥
	byte plain[16], key[16];
	for(i=0; i<16; i++){
		plain[i] = byte(i);
		key[i] = 0x01;
	}
	AES aes;
	aes.setPlainText(plain);
	aes.setCipherKey(key);
	aes.encryption();
	aes.decryption();
	aes.showMesage();
	
	QueryPerformanceCounter(&t2);
    printf("End Time: %u/n", t2.QuadPart);
 	cout<<endl;
 	printf("Lasting Time: %u/n",( t2.QuadPart- t1.QuadPart));
	
	return 0;
}

SM4:

#pragma once
/**
 * \file sm4.h
 */
#ifndef XYSSL_SM4_H
#define XYSSL_SM4_H

#define SM4_ENCRYPT     1
#define SM4_DECRYPT     0

 /**
  * \brief          SM4 context structure
  */
typedef struct
{
    int mode;                   /*!<  encrypt/decrypt   */
    unsigned long sk[32];       /*!<  SM4 subkeys       */
}
sm4_context;


#ifdef __cplusplus
extern "C" {
#endif

    /**
     * \brief          SM4 key schedule (128-bit, encryption)
     *
     * \param ctx      SM4 context to be initialized
     * \param key      16-byte secret key
     */
    void sm4_setkey_enc(sm4_context* ctx, unsigned char key[16]);

    /**
     * \brief          SM4 key schedule (128-bit, decryption)
     *
     * \param ctx      SM4 context to be initialized
     * \param key      16-byte secret key
     */
    void sm4_setkey_dec(sm4_context* ctx, unsigned char key[16]);

    /**
     * \brief          SM4-ECB block encryption/decryption
     * \param ctx      SM4 context
     * \param mode     SM4_ENCRYPT or SM4_DECRYPT
     * \param length   length of the input data
     * \param input    input block
     * \param output   output block
     */
    void sm4_crypt_ecb(sm4_context* ctx,
        int mode,
        int length,
        unsigned char* input,
        unsigned char* output);

#ifdef __cplusplus
}
#endif

#endif /* sm4.h */




/*测试代码
 * SM4/SMS4 algorithm test programme
 * 2012-4-21
 */

#include <string.h>
#include <stdio.h>
#include "sm4.h"
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include<ctime> 

using namespace std;



 /*
  * 32-bit integer manipulation macros (big endian)
  */
#ifndef GET_ULONG_BE
#define GET_ULONG_BE(n,b,i)                             \
{                                                       \
    (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \
        | ( (unsigned long) (b)[(i) + 1] << 16 )        \
        | ( (unsigned long) (b)[(i) + 2] <<  8 )        \
        | ( (unsigned long) (b)[(i) + 3]       );       \
}
#endif


#ifndef PUT_ULONG_BE
#define PUT_ULONG_BE(n,b,i)                             \
{                                                       \
    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
}
#endif


  /*
   *rotate shift left marco definition
   *
   */
#define  SHL(x,n) (((x) & 0xFFFFFFFF) << n)
#define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n)))


#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; }


   /*
    * Expanded SM4 S-boxes
    /* Sbox table: 8bits input convert to 8 bits output*/

static const unsigned char SboxTable[16][16] =
{
{0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05},
{0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99},
{0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62},
{0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6},
{0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8},
{0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35},
{0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87},
{0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e},
{0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1},
{0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3},
{0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f},
{0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51},
{0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8},
{0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0},
{0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84},
{0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48}
};


/* System parameter */
static const unsigned long FK[4] = { 0xa3b1bac6,0x56aa3350,0x677d9197,0xb27022dc };


/* fixed parameter */
static const unsigned long CK[32] =
{
0x00070e15,0x1c232a31,0x383f464d,0x545b6269,
0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,
0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,
0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,
0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,
0x30373e45,0x4c535a61,0x686f767d,0x848b9299,
0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,
0x10171e25,0x2c333a41,0x484f565d,0x646b7279
};




/*
 * private function:
 * look up in SboxTable and get the related value.
 * args:    [in] inch: 0x00~0xFF (8 bits unsigned value).
 */
static unsigned char sm4Sbox(unsigned char inch)
{
    unsigned char* pTable = (unsigned char*)SboxTable;
    unsigned char retVal = (unsigned char)(pTable[inch]);
    return retVal;
}


/*
 * private F(Lt) function:
 * "T algorithm" == "L algorithm" + "t algorithm".
 * args:    [in] a: a is a 32 bits unsigned value;
 * return: c: c is calculated with line algorithm "L" and nonline algorithm "t"
 */
static unsigned long sm4Lt(unsigned long ka)
{
    unsigned long bb = 0;
    unsigned long c = 0;
    unsigned char a[4];
    unsigned char b[4];
    PUT_ULONG_BE(ka, a, 0)
        b[0] = sm4Sbox(a[0]);
    b[1] = sm4Sbox(a[1]);
    b[2] = sm4Sbox(a[2]);
    b[3] = sm4Sbox(a[3]);
    GET_ULONG_BE(bb, b, 0)
        c = bb ^ (ROTL(bb, 2)) ^ (ROTL(bb, 10)) ^ (ROTL(bb, 18)) ^ (ROTL(bb, 24));
    return c;
}


/*
 * private F function:
 * Calculating and getting encryption/decryption contents.
 * args:    [in] x0: original contents;
 * args:    [in] x1: original contents;
 * args:    [in] x2: original contents;
 * args:    [in] x3: original contents;
 * args:    [in] rk: encryption/decryption key;
 * return the contents of encryption/decryption contents.
 */
static unsigned long sm4F(unsigned long x0, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long rk)
{
    return (x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk));
}




/* private function:
 * Calculating round encryption key.
 * args:    [in] a: a is a 32 bits unsigned value;
 * return: sk[i]: i{0,1,2,3,...31}.
 */
static unsigned long sm4CalciRK(unsigned long ka)
{
    unsigned long bb = 0;
    unsigned long rk = 0;
    unsigned char a[4];
    unsigned char b[4];
    PUT_ULONG_BE(ka, a, 0)
        b[0] = sm4Sbox(a[0]);
    b[1] = sm4Sbox(a[1]);
    b[2] = sm4Sbox(a[2]);
    b[3] = sm4Sbox(a[3]);
    GET_ULONG_BE(bb, b, 0)
        rk = bb ^ (ROTL(bb, 13)) ^ (ROTL(bb, 23));
    return rk;
}


static void sm4_setkey(unsigned long SK[32], unsigned char key[16])
{
    unsigned long MK[4];
    unsigned long k[36];
    unsigned long i = 0;


    GET_ULONG_BE(MK[0], key, 0);
    GET_ULONG_BE(MK[1], key, 4);
    GET_ULONG_BE(MK[2], key, 8);
    GET_ULONG_BE(MK[3], key, 12);
    k[0] = MK[0] ^ FK[0];
    k[1] = MK[1] ^ FK[1];
    k[2] = MK[2] ^ FK[2];
    k[3] = MK[3] ^ FK[3];
    for (; i < 32; i++)
    {
        k[i + 4] = k[i] ^ (sm4CalciRK(k[i + 1] ^ k[i + 2] ^ k[i + 3] ^ CK[i]));
        SK[i] = k[i + 4];
    }


}


/*
 * SM4 standard one round processing
 *
 */
static void sm4_one_round(unsigned long sk[32],
    unsigned char input[16],
    unsigned char output[16])
{
    unsigned long i = 0;
    unsigned long ulbuf[36];


    memset(ulbuf, 0, sizeof(ulbuf));
    GET_ULONG_BE(ulbuf[0], input, 0)
        GET_ULONG_BE(ulbuf[1], input, 4)
        GET_ULONG_BE(ulbuf[2], input, 8)
        GET_ULONG_BE(ulbuf[3], input, 12)
        while (i < 32)
        {
            ulbuf[i + 4] = sm4F(ulbuf[i], ulbuf[i + 1], ulbuf[i + 2], ulbuf[i + 3], sk[i]);
            // #ifdef _DEBUG
            //        	printf("rk(%02d) = 0x%08x,  X(%02d) = 0x%08x \n",i,sk[i], i, ulbuf[i+4] );
            // #endif
            i++;
        }
    PUT_ULONG_BE(ulbuf[35], output, 0);
    PUT_ULONG_BE(ulbuf[34], output, 4);
    PUT_ULONG_BE(ulbuf[33], output, 8);
    PUT_ULONG_BE(ulbuf[32], output, 12);
}


/*
 * SM4 key schedule (128-bit, encryption)
 */
void sm4_setkey_enc(sm4_context* ctx, unsigned char key[16])
{
    ctx->mode = SM4_ENCRYPT;
    sm4_setkey(ctx->sk, key);
}


/*
 * SM4 key schedule (128-bit, decryption)
 */
void sm4_setkey_dec(sm4_context* ctx, unsigned char key[16])
{
    int i;
    ctx->mode = SM4_ENCRYPT;
    sm4_setkey(ctx->sk, key);
    for (i = 0; i < 16; i++)
    {
        SWAP(ctx->sk[i], ctx->sk[31 - i]);
    }
}




/*
 * SM4-ECB block encryption/decryption
 */


void sm4_crypt_ecb(sm4_context* ctx,
    int mode,
    int length,
    unsigned char* input,
    unsigned char* output)
{
    while (length > 0)
    {
        sm4_one_round(ctx->sk, input, output);
        input += 16;
        output += 16;
        length -= 16;
    }


}



int main()
{

    LARGE_INTEGER t1, t2, tc;
    QueryPerformanceFrequency(&tc);
    printf("Frequency: %u/n", tc.QuadPart);
    cout << endl;
    QueryPerformanceCounter(&t1);
    printf("Begin Time: %u/n", t1.QuadPart);
    cout << endl;


	unsigned char key[8] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef };
	unsigned char input[8] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef };
	unsigned char output[16];
	sm4_context ctx;
	unsigned long i;

	//encrypt standard testing vector
	sm4_setkey_enc(&ctx, key);
	sm4_crypt_ecb(&ctx, 1, 8, input, output);
	for (i = 0; i < 8; i++)
		printf("%02x ", output[i]);
	printf("\n");

	//decrypt testing
	sm4_setkey_dec(&ctx, key);
	sm4_crypt_ecb(&ctx, 0, 8, output, output);
	for (i = 0; i < 8; i++)
		printf("%02x ", output[i]);
	printf("\n");


    QueryPerformanceCounter(&t2);
    printf("End Time: %u/n", t2.QuadPart);
    cout << endl;
    printf("Lasting Time: %u/n", (t2.QuadPart - t1.QuadPart));
	return 0;
}

AES:


//aes.h

#pragma once
#pragma once
#ifndef MY_AES_H
#define MY_AES_H

/**
 * 参数 p: 明文的字符串数组。
 * 参数 plen: 明文的长度,长度必须为16的倍数。
 * 参数 key: 密钥的字符串数组。
 */
void aes(char* p, int plen, char* key);

/**
 * 参数 c: 密文的字符串数组。
 * 参数 clen: 密文的长度,长度必须为16的倍数。
 * 参数 key: 密钥的字符串数组。
 */
void deAes(char* c, int clen, char* key);

#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "aes.h"

/**
 * S盒
 */
static const int S[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盒
 */
static const int S2[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 };

/**
 * 获取整形数据的低8位的左4个位
 */
static int getLeft4Bit(int num) {
	int left = num & 0x000000f0;
	return left >> 4;
}

/**
 * 获取整形数据的低8位的右4个位
 */
static int getRight4Bit(int num) {
	return num & 0x0000000f;
}
/**
 * 根据索引,从S盒中获得元素
 */
static int getNumFromSBox(int index) {
	int row = getLeft4Bit(index);
	int col = getRight4Bit(index);
	return S[row][col];
}

/**
 * 把一个字符转变成整型
 */
static int getIntFromChar(char c) {
	int result = (int)c;
	return result & 0x000000ff;
}

/**
 * 把16个字符转变成4X4的数组,
 * 该矩阵中字节的排列顺序为从上到下,
 * 从左到右依次排列。
 */
static void convertToIntArray(char* str, int pa[4][4]) {
	int k = 0;
	int i, j;
	for (i = 0; i < 4; i++)
		for (j = 0; j < 4; j++) {
			pa[j][i] = getIntFromChar(str[k]);
			k++;
		}
}

/**
 * 打印4X4的数组
 */
static void printArray(int a[4][4]) {
	int i, j;
	for (i = 0; i < 4; i++) {
		for (j = 0; j < 4; j++)
			printf("a[%d][%d] = 0x%x ", i, j, a[i][j]);
		printf("\n");
	}
	printf("\n");
}

/**
 * 打印字符串的ASSCI,
 * 以十六进制显示。
 */
static void printASSCI(char* str, int len) {
	int i;
	for (i = 0; i < len; i++)
		printf("0x%x ", getIntFromChar(str[i]));
	printf("\n");
}

/**
 * 把连续的4个字符合并成一个4字节的整型
 */
static int getWordFromStr(char* str) {
	int one, two, three, four;
	one = getIntFromChar(str[0]);
	one = one << 24;
	two = getIntFromChar(str[1]);
	two = two << 16;
	three = getIntFromChar(str[2]);
	three = three << 8;
	four = getIntFromChar(str[3]);
	return one | two | three | four;
}

/**
 * 把一个4字节的数的第一、二、三、四个字节取出,
 * 入进一个4个元素的整型数组里面。
 */
static void splitIntToArray(int num, int array[4]) {
	int one, two, three;
	one = num >> 24;
	array[0] = one & 0x000000ff;
	two = num >> 16;
	array[1] = two & 0x000000ff;
	three = num >> 8;
	array[2] = three & 0x000000ff;
	array[3] = num & 0x000000ff;
}

/**
 * 将数组中的元素循环左移step位
 */
static void leftLoop4int(int array[4], int step) {
	int temp[4];
	int i;
	int index;
	for (i = 0; i < 4; i++)
		temp[i] = array[i];

	index = step % 4 == 0 ? 0 : step % 4;
	for (i = 0; i < 4; i++) {
		array[i] = temp[index];
		index++;
		index = index % 4;
	}
}

/**
 * 把数组中的第一、二、三和四元素分别作为
 * 4字节整型的第一、二、三和四字节,合并成一个4字节整型
 */
static int mergeArrayToInt(int array[4]) {
	int one = array[0] << 24;
	int two = array[1] << 16;
	int three = array[2] << 8;
	int four = array[3];
	return one | two | three | four;
}

/**
 * 常量轮值表
 */
static const int Rcon[10] = { 0x01000000, 0x02000000,
	0x04000000, 0x08000000,
	0x10000000, 0x20000000,
	0x40000000, 0x80000000,
	0x1b000000, 0x36000000 };
/**
 * 密钥扩展中的T函数
 */
static int T(int num, int round) {
	int numArray[4];
	int i;
	int result;
	splitIntToArray(num, numArray);
	leftLoop4int(numArray, 1);//字循环

	//字节代换
	for (i = 0; i < 4; i++)
		numArray[i] = getNumFromSBox(numArray[i]);

	result = mergeArrayToInt(numArray);
	return result ^ Rcon[round];
}

//密钥对应的扩展数组
static int w[44];
/**
 * 打印W数组
 */
static void printW() {
	int i, j;
	for (i = 0, j = 1; i < 44; i++, j++) {
		printf("w[%d] = 0x%x ", i, w[i]);
		if (j % 4 == 0)
			printf("\n");
	}
	printf("\n");
}


/**
 * 扩展密钥,结果是把w[44]中的每个元素初始化
 */
static void extendKey(char* key) {
	int i, j;
	for (i = 0; i < 4; i++)
		w[i] = getWordFromStr(key + i * 4);

	for (i = 4, j = 0; i < 44; i++) {
		if (i % 4 == 0) {
			w[i] = w[i - 4] ^ T(w[i - 1], j);
			j++;//下一轮
		}
		else {
			w[i] = w[i - 4] ^ w[i - 1];
		}
	}

}

/**
 * 轮密钥加
 */
static void addRoundKey(int array[4][4], int round) {
	int warray[4];
	int i, j;
	for (i = 0; i < 4; i++) {

		splitIntToArray(w[round * 4 + i], warray);

		for (j = 0; j < 4; j++) {
			array[j][i] = array[j][i] ^ warray[j];
		}
	}
}

/**
 * 字节代换
 */
static void subBytes(int array[4][4]) {
	int i, j;
	for (i = 0; i < 4; i++)
		for (j = 0; j < 4; j++)
			array[i][j] = getNumFromSBox(array[i][j]);
}

/**
 * 行移位
 */
static void shiftRows(int array[4][4]) {
	int rowTwo[4], rowThree[4], rowFour[4];
	int i;
	for (i = 0; i < 4; i++) {
		rowTwo[i] = array[1][i];
		rowThree[i] = array[2][i];
		rowFour[i] = array[3][i];
	}

	leftLoop4int(rowTwo, 1);
	leftLoop4int(rowThree, 2);
	leftLoop4int(rowFour, 3);

	for (i = 0; i < 4; i++) {
		array[1][i] = rowTwo[i];
		array[2][i] = rowThree[i];
		array[3][i] = rowFour[i];
	}
}

/**
 * 列混合要用到的矩阵
 */
static const int colM[4][4] = { 2, 3, 1, 1,
	1, 2, 3, 1,
	1, 1, 2, 3,
	3, 1, 1, 2 };

static int GFMul2(int s) {
	int result = s << 1;
	int a7 = result & 0x00000100;

	if (a7 != 0) {
		result = result & 0x000000ff;
		result = result ^ 0x1b;
	}

	return result;
}

static int GFMul3(int s) {
	return GFMul2(s) ^ s;
}

static int GFMul4(int s) {
	return GFMul2(GFMul2(s));
}

static int GFMul8(int s) {
	return GFMul2(GFMul4(s));
}

static int GFMul9(int s) {
	return GFMul8(s) ^ s;
}

static int GFMul11(int s) {
	return GFMul9(s) ^ GFMul2(s);
}

static int GFMul12(int s) {
	return GFMul8(s) ^ GFMul4(s);
}

static int GFMul13(int s) {
	return GFMul12(s) ^ s;
}

static int GFMul14(int s) {
	return GFMul12(s) ^ GFMul2(s);
}

/**
 * GF上的二元运算
 */
static int GFMul(int n, int s) {
	int result;

	if (n == 1)
		result = s;
	else if (n == 2)
		result = GFMul2(s);
	else if (n == 3)
		result = GFMul3(s);
	else if (n == 0x9)
		result = GFMul9(s);
	else if (n == 0xb)//11
		result = GFMul11(s);
	else if (n == 0xd)//13
		result = GFMul13(s);
	else if (n == 0xe)//14
		result = GFMul14(s);

	return result;
}
/**
 * 列混合
 */
static void mixColumns(int array[4][4]) {

	int tempArray[4][4];
	int i, j;
	for (i = 0; i < 4; i++)
		for (j = 0; j < 4; j++)
			tempArray[i][j] = array[i][j];

	for (i = 0; i < 4; i++)
		for (j = 0; j < 4; j++) {
			array[i][j] = GFMul(colM[i][0], tempArray[0][j]) ^ GFMul(colM[i][1], tempArray[1][j])
				^ GFMul(colM[i][2], tempArray[2][j]) ^ GFMul(colM[i][3], tempArray[3][j]);
		}
}
/**
 * 把4X4数组转回字符串
 */
static void convertArrayToStr(int array[4][4], char* str) {
	int i, j;
	for (i = 0; i < 4; i++)
		for (j = 0; j < 4; j++)
			*str++ = (char)array[j][i];
}
/**
 * 检查密钥长度
 */
static int checkKeyLen(int len) {
	if (len == 16)
		return 1;
	else
		return 0;
}


/**
 * 参数 p: 明文的字符串数组。
 * 参数 plen: 明文的长度。
 * 参数 key: 密钥的字符串数组。
 */
void aes(char* p, int plen, char* key) {

	int keylen = strlen(key);
	int pArray[4][4];
	int k, i;

	if (plen == 0 || plen % 16 != 0) {
		printf("明文字符长度必须为16的倍数!\n");
		exit(0);
	}

	if (!checkKeyLen(keylen)) {
		printf("密钥字符长度错误!长度必须为16。当前长度为%d\n", keylen);
		exit(0);
	}

	extendKey(key);//扩展密钥

	for (k = 0; k < plen; k += 16) {
		convertToIntArray(p + k, pArray);

		addRoundKey(pArray, 0);//一开始的轮密钥加

		for (i = 1; i < 10; i++) {

			subBytes(pArray);//字节代换

			shiftRows(pArray);//行移位

			mixColumns(pArray);//列混合

			addRoundKey(pArray, i);

		}

		subBytes(pArray);//字节代换

		shiftRows(pArray);//行移位

		addRoundKey(pArray, 10);

		convertArrayToStr(pArray, p + k);
	}
}
/**
 * 根据索引从逆S盒中获取值
 */
static int getNumFromS1Box(int index) {
	int row = getLeft4Bit(index);
	int col = getRight4Bit(index);
	return S2[row][col];
}
/**
 * 逆字节变换
 */
static void deSubBytes(int array[4][4]) {
	int i, j;
	for (i = 0; i < 4; i++)
		for (j = 0; j < 4; j++)
			array[i][j] = getNumFromS1Box(array[i][j]);
}
/**
 * 把4个元素的数组循环右移step位
 */
static void rightLoop4int(int array[4], int step) {
	int temp[4];
	int i;
	int index;
	for (i = 0; i < 4; i++)
		temp[i] = array[i];

	index = step % 4 == 0 ? 0 : step % 4;
	index = 3 - index;
	for (i = 3; i >= 0; i--) {
		array[i] = temp[index];
		index--;
		index = index == -1 ? 3 : index;
	}
}

/**
 * 逆行移位
 */
static void deShiftRows(int array[4][4]) {
	int rowTwo[4], rowThree[4], rowFour[4];
	int i;
	for (i = 0; i < 4; i++) {
		rowTwo[i] = array[1][i];
		rowThree[i] = array[2][i];
		rowFour[i] = array[3][i];
	}

	rightLoop4int(rowTwo, 1);
	rightLoop4int(rowThree, 2);
	rightLoop4int(rowFour, 3);

	for (i = 0; i < 4; i++) {
		array[1][i] = rowTwo[i];
		array[2][i] = rowThree[i];
		array[3][i] = rowFour[i];
	}
}
/**
 * 逆列混合用到的矩阵
 */
static const int deColM[4][4] = { 0xe, 0xb, 0xd, 0x9,
	0x9, 0xe, 0xb, 0xd,
	0xd, 0x9, 0xe, 0xb,
	0xb, 0xd, 0x9, 0xe };

/**
 * 逆列混合
 */
static void deMixColumns(int array[4][4]) {
	int tempArray[4][4];
	int i, j;
	for (i = 0; i < 4; i++)
		for (j = 0; j < 4; j++)
			tempArray[i][j] = array[i][j];

	for (i = 0; i < 4; i++)
		for (j = 0; j < 4; j++) {
			array[i][j] = GFMul(deColM[i][0], tempArray[0][j]) ^ GFMul(deColM[i][1], tempArray[1][j])
				^ GFMul(deColM[i][2], tempArray[2][j]) ^ GFMul(deColM[i][3], tempArray[3][j]);
		}
}
/**
 * 把两个4X4数组进行异或
 */
static void addRoundTowArray(int aArray[4][4], int bArray[4][4]) {
	int i, j;
	for (i = 0; i < 4; i++)
		for (j = 0; j < 4; j++)
			aArray[i][j] = aArray[i][j] ^ bArray[i][j];
}
/**
 * 从4个32位的密钥字中获得4X4数组,
 * 用于进行逆列混合
 */
static void getArrayFrom4W(int i, int array[4][4]) {
	int index, j;
	int colOne[4], colTwo[4], colThree[4], colFour[4];
	index = i * 4;
	splitIntToArray(w[index], colOne);
	splitIntToArray(w[index + 1], colTwo);
	splitIntToArray(w[index + 2], colThree);
	splitIntToArray(w[index + 3], colFour);

	for (j = 0; j < 4; j++) {
		array[j][0] = colOne[j];
		array[j][1] = colTwo[j];
		array[j][2] = colThree[j];
		array[j][3] = colFour[j];
	}

}

/**
 * 参数 c: 密文的字符串数组。
 * 参数 clen: 密文的长度。
 * 参数 key: 密钥的字符串数组。
 */
void deAes(char* c, int clen, char* key) {

	int cArray[4][4];
	int keylen, k;
	keylen = strlen(key);
	if (clen == 0 || clen % 16 != 0) {
		printf("密文字符长度必须为16的倍数!现在的长度为%d\n", clen);
		exit(0);
	}

	if (!checkKeyLen(keylen)) {
		printf("密钥字符长度错误!长度必须为16、24和32。当前长度为%d\n", keylen);
		exit(0);
	}

	extendKey(key);//扩展密钥

	for (k = 0; k < clen; k += 16) {
		int i;
		int wArray[4][4];

		convertToIntArray(c + k, cArray);





		addRoundKey(cArray, 10);

		for (i = 9; i >= 1; i--) {
			deSubBytes(cArray);

			deShiftRows(cArray);

			deMixColumns(cArray);
			getArrayFrom4W(i, wArray);
			deMixColumns(wArray);

			addRoundTowArray(cArray, wArray);
		}

		deSubBytes(cArray);

		deShiftRows(cArray);

		addRoundKey(cArray, 0);

		convertArrayToStr(cArray, c + k);

	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值