⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idea.txt

📁 一个可以加密解密的算法
💻 TXT
字号:
// IDEA.cpp: implementation of the CIDEA class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DataSecu.h"
#include "IDEA.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CIDEA::CIDEA()
{

}

CIDEA::~CIDEA()
{

}

//IDEA加密主控函数,并作为类暴露出的方法
bool CIDEA::Crypto(BYTE Source[8], BYTE Dest[8], BYTE Key[16], int Flag)
{
	unsigned short int s_Data[4],d_Data[4],uskey[8];
	unsigned short int ek[7][10],dk[7][10];
	memcpy(s_Data,Source,8);
	memcpy(uskey,Key,16);

	en_Key(uskey,ek);  //生成加密子密钥
	de_Key(ek,dk);  //生成解密子密钥

	if (Flag==ENCIPHER)
		Iteration(s_Data,d_Data,ek);  //加密迭代
	else if (Flag==DECIPHER)
		Iteration(s_Data,d_Data,dk);  //解密迭代
	else
		return false;

	memcpy(Dest,d_Data,8);

	return true;
}

//加解密迭代函数
void CIDEA::Iteration(unsigned short int in_Data[4], unsigned short int out_Data[4], unsigned short int Z[7][10])
{
	unsigned short int r,x1,x2,x3,x4,kk,t1,t2,a;
	x1=in_Data[0]; x2=in_Data[1]; x3=in_Data[2]; x4=in_Data[3];  //64位数据分成4块
	for (r=1;r<=round;r++)
	{
		//对16位的四块进行分组运算
		x1=Mul(x1,Z[1][r]);  //第一块与第一个子密钥进行乘法运算
		x4=Mul(x4,Z[4][r]);  //第四块与第四个子密钥进行乘法运算
		x2=(x2+Z[2][r]) & one;   //第二块与第二个子密钥进行加法运算
		x3=(x3+Z[3][r]) & one;   //第三块与第三个子密钥进行加法运算

		//以下为MA结构的函数
		//x1和x3异或后再与第5个子密钥进行乘法运算
		kk=Mul(Z[5][r],(x1^x3));  
		//x2和x4异或后与kk做加法运算的结果再与第6个子密钥进行乘法运算
		t1=Mul(Z[6][r],(kk+(x2^x4))&one);  
		//kk与t1进行加法运算
		t2=(kk+t1) &one;

		//随机变换PI
		x1=x1^t1;   //x1与t1异或的结果做为下一个第一块
		x4=x4^t2;   //x4与t2异或的结果做为下一个第四块 
		a=x2^t2;  x2=x3^t1;   //x3与t1异或的结果做为下一个第二块
		x3=a;      //x2与t2异或的结果做为下一个第三块
		//因为x2与x3交叉使用,用a做为临时变量保存
	}

	//输出转换
	out_Data[0]=Mul(x1,Z[1][round+1]); //第一块与第一个子密钥进行乘法运算
	out_Data[3]=Mul(x4,Z[4][round+1]); //第四块与第四个子密钥进行乘法运算
	out_Data[1]=(x3+Z[2][round+1])&one;  //第二块与第二个子密钥进行加法运算
	out_Data[2]=(x2+Z[3][round+1])&one;  //第三块与第三个子密钥进行加法运算

}

//生成加密子密钥函数
void CIDEA::en_Key(unsigned short int uskey[8], unsigned short int EK[7][10])
{
	unsigned short int S[54];  //保存总共所需的52个子密钥
	int i,j,r;

	//子密钥长16位,前8个子密钥是128位密钥的顺序8组即数组每一项为一组
	for (i=0;i<8;i++)   
		S[i]=uskey[i];
	
	//旋转128位密钥生成其余的54-8个子密钥(每轮旋转25Bit),其中只使用52个
	for(i=8;i<54;i++)
	{
		if ((i+2)%8==0)  //对于S[14],S[22],...进行计算
			//此子密钥由旋转前第八组的7位和第一组的9位组成
			S[i]=((S[i-7]<<9)^(S[i-6-8]>>7)) & one; 
		else
			//此子密钥由旋转前相邻两组的各7位和9位组成
			S[i]=((S[i-7]<<9)^(S[i-6]>>7)) & one;
	}

	//取得子密钥(加密过程有round轮迭代,每轮需6个子密钥,最后变换需4个子密钥)
	//Z是6*9的矩阵,每列为一轮的加密子密钥,最后一列中有4个子密钥在最后变换时使用
	for (r=1;r<=round+1;r++)
		for (j=1;j<7;j++)
			EK[j][r]=S[6*(r-1)+j-1];
}

//生成解密子密钥函数
void CIDEA::de_Key(unsigned short int EK[7][10], unsigned short int DK[7][10])
{
	int j;
	for (j=1;j<=round+1;j++)
	{
		//DK矩阵中第1、4行是Z矩阵相应行经计算其乘法(运算)逆而来
		//而列则颠倒过来
		DK[1][round-j+2]=Inv(EK[1][j]);  //使用应用密码学上提供的实现算法
		DK[4][round-j+2]=Inv(EK[4][j]);  //使用应用密码学上提供的实现算法

		//DK矩阵中第2行当是第1列和第round+1列时是由Z矩阵相应行经计算其加法(运算)逆而来
		//DK矩阵中第2行当非第1列和第round+1列时是由Z矩阵第3行经计算其加法(运算)逆而来
		//DK矩阵中第3行当是第1列和第round+1列时是由Z矩阵相应行经计算其加法(运算)逆而来
		//DK矩阵中第3行当非第1列和第round+1列时是由Z矩阵第2行经计算其加法(运算)逆而来
		//而列则颠倒过来
		//fuyi等于2的16次方,one等于2的16次方减1
		if (j==1 ||j==round+1)
		{
			DK[2][round-j+2]=(fuyi-EK[2][j])&one;
			DK[3][round-j+2]=(fuyi-EK[3][j])&one;
		}
		else
		{
			DK[2][round-j+2]=(fuyi-EK[3][j])&one;
			DK[3][round-j+2]=(fuyi-EK[2][j])&one;
		}
	}
	//DK矩阵中第5、6行是Z矩阵相应行而来
	//而列则颠倒过来
	for (j=1;j<=round+1;j++)
	{
		DK[5][round+1-j]=EK[5][j];
		DK[6][round+1-j]=EK[6][j];
	}
}

//用高低算法实现乘法运算
unsigned short int CIDEA::Mul(unsigned short int a, unsigned short int b)
{
	long int p;
	long unsigned q;
	if (a==0) p=maxim-b;
	else if(b==0) p=maxim-a;
	else
	{
		q=(unsigned long)a*(unsigned long)b;
		//q的低16位与maxim相除的余数为(q&one),q的高16位与maxim相除的余数为(q>>16)
		//两余数相减即为mod maxim后的最终结果
		p=(q&one)-(q>>16); 
		if (p<=0) p=p+maxim;  //(余数)不能为负
	}
	return (unsigned)(p&one);
}

//计算xin的乘法运算逆(From 应用密码学)
unsigned short int CIDEA::Inv(unsigned short int xin)
{
	unsigned short int t0,t1;
	unsigned short int q,y;
	if (xin<=1)
		return xin;    //0 and 1 are self-inverse
	t1=maxim/xin;  //Since xin>=2, this fites into 16 bits
	y=maxim%xin;
	if (y==1)
		return ((maxim-t1) & one);
	t0=1;
	do {
		q=xin/y;
		xin=xin%y;
		t0+=q*t1;
		if ((xin==1) | (xin==0))
			return t0;
		q=y/xin;
		y=y%xin;
		t1+=q*t0;
	}
	while (y!=1);
	return ((maxim-t1) & one);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -