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 <Windows.h>
#include <stdlib.h>
#include <stdio.h>
#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;
}