IDEA加密算法(c实现)

vs2013环境下面成功编译并且运行
IDEA算法,全称是Internationale Data Encrypt Algorithm 一种国际数据加密算法 至今为止都很安全,是一种块加密算法。
密钥长度为128bit(16字节),以每64bit(8字节)为单位进行加密。
算法主要流程:

1.首先进行密钥拓展,加密一个块需要52个密钥(48 + 4)
1.1采用每次循环左移25位的方式,每次生成16bit的密钥8个,循环6次
1.2最后的时候再循环一次,取前四个16bit作为最后4个密钥
2.对明文进行加密
2.1将64bit明文拆分成4个16bit形式,进行异或,模加法,模乘法,输出到 缓冲区中
2.2最后一次的时候与最后四个密钥进行模加法和模乘法运算

#include 
#include 
#include 
#define IDEA_ADD_MODULAR    65536  
#define IDEA_MP_MODULAR     65537

unsigned char key[] = "1234567812345678";//密钥
unsigned char plaintext[] = "1234567812345678";//明文
unsigned short subKey[52];

inline unsigned short add_mod(unsigned short a, unsigned short b) //模65536的加法
{
	unsigned long tmp = a + b;
	unsigned short ret = tmp % IDEA_ADD_MODULAR;
	return ret;
}

inline unsigned short multi_mod(unsigned short a, unsigned short b)//模65537乘
{
	unsigned long long tmp, tmp_a, tmp_b; //if both a and b are 2^16, the result will be 2^32 which will exceed a 32-bit int  
	tmp_a = a == 0 ? (1 << 16) : a;
	tmp_b = b == 0 ? (1 << 16) : b;
	tmp = (tmp_a * tmp_b) % IDEA_MP_MODULAR;
	return (unsigned short)(tmp);
}

void RolLeft(unsigned short tmpKey[])//循环左移
{
	unsigned highPart = tmpKey[0] >> (16 - 5);

	for (int i = 0; i < 7; i++) {
		tmpKey[i] = (tmpKey[i] << 5) | (tmpKey[i + 1] >> (16 - 5));
	}

	tmpKey[7] = (tmpKey[7] << 5) | highPart;
}

//产生52个16位子密钥 所有的子密钥都是由这128位key而来的 首先128 = 16 * 8 初始有8个子密钥
void ExtendKey()//扩展key
{
	unsigned short tmpKey[8];
	int i;

	printf("Extended Key : \n");
	for (i = 0; i < 8; i++) {
		subKey[i] = (key[2 * i] << 8) | (key[2 * i + 1]);//获得初始的8个subkey
		tmpKey[i] = (key[2 * i] << 8) | (key[2 * i + 1]);
		printf("%04x\n", subKey[i]);
	}

	//前48个
	for (i = 1; i <= 5; i++) {
		for (int k = 0; k < 5; k++)//每次移动五位 移动五次
			RolLeft(tmpKey);
		for (int j = 0; j < 8; j++) {
			subKey[8 * i + j] = tmpKey[j];
			printf("%04x\n", tmpKey[j]);
		}
	}

	//最后四个
	for (int k = 0; k < 5; k++)//每次移动五位 移动五次
		RolLeft(tmpKey);
	for (i = 0; i < 4; i++) {
		subKey[48 + i] = tmpKey[i];
		printf("%04x\n", tmpKey[i]);
	}

}

//对于密文
//以8个字节为一组进行加密 首先被分成4个16位为x1,x2,x3,x4 每一轮需要6个密钥 共计8轮 最后的4个子密钥用于变换输出
void IDEARound(unsigned short x[], int round)
{
	int i;
	unsigned short temp;
	unsigned short tmp[4];
	unsigned short out[6];

	for (i = 0; i < 4; i++)
		tmp[i] = x[i];

	tmp[0] = multi_mod(x[0], subKey[6 * round]);//1
	tmp[1] = add_mod(x[1], subKey[6 * round + 1]);//2
	tmp[2] = add_mod(x[2], subKey[6 * round + 2]);//3
	tmp[3] = multi_mod(x[3], subKey[6 * round + 3]);//4


	out[0] = tmp[0] ^ tmp[2];//5
	out[1] = tmp[1] ^ tmp[3];//6

	out[2] = multi_mod(out[0], subKey[6 * round + 4]);//7
	out[3] = add_mod(out[1], out[2]);//8

	out[4] = multi_mod(out[3], subKey[6 * round + 5]);//9
	out[5] = add_mod(out[2], out[4]);//10

	out[0] = tmp[0] ^ out[4];//11
	out[1] = tmp[1] ^ out[5];//12

	out[2] = tmp[2] ^ out[4];//13
	out[3] = tmp[3] ^ out[5];//14

	//交换中间两个分组
	temp = out[1];
	out[1] = out[2];
	out[2] = temp;

	for (i = 0; i < 4; i++) {
		x[i] = out[i];//重新赋值
		
	}

}

void IDEAEncrypt()
{
	int i;
	DWORD len;
	unsigned short temp;
	unsigned short x[4];
	unsigned char *data = plaintext;

	ExtendKey();//IDEA算法首先扩展key 大部分加密算法都要扩展key 以保证能匹配加密轮数
	
	printf("\n\n");
	if (strlen((const char *)plaintext) % 8 != 0) {
		printf("Error in alignment of plain text!\n");
		return;
	}

	len = strlen((const char *)plaintext) / 8;//加密组数

	printf("cipher result : ");
	for (int count = 0; count < len; count++) {
		for (i = 0; i < 4; i++) {//将明文分割成16位一组
			x[i] = (data[2 * i] << 8) | data[2 * i + 1];
		}

		for (int j = 0; j < 8; j++) {
			IDEARound(x, j);
		}

		//最后一轮不进行变换 故再交换一次
		temp = x[1];
		x[1] = x[2];
		x[2] = temp;

		//第九轮变换 需要用到最后的4个子密钥了
		x[0] = multi_mod(x[0], subKey[48]);
		x[1] = add_mod(x[1], subKey[49]);
		x[2] = add_mod(x[2], subKey[50]);
		x[3] = multi_mod(x[3], subKey[51]);

		for (i = 0; i < 4; i++) {
			data[2 * i] = x[i] >> 8;
			data[2 * i + 1] = x[i] & 0xff;
			printf("%02x%02x", data[2 * i], data[2 * i+1]);
		}

		data += 8;//移动到下个块
	}
}

int main()
{
	IDEAEncrypt();
	return 0;
}

你可能感兴趣的:(密码学)