📄 idea.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 + -