📄 dec5502_des.c
字号:
/* From-----指向密钥拷贝的源地址 */
/****************************************************************/
static void Cookey(register unsigned long *Raw1)
{
register unsigned long *Cook, *Raw0;
unsigned long Dough[32];
register int i;
Cook = Dough;
for( i = 0; i < 16; i++, Raw1++ )
{
Raw0 = Raw1++;
*Cook = (*Raw0 & 0x00FC0000L) << 6;
*Cook |= (*Raw0 & 0x00000FC0L) << 10;
*Cook |= (*Raw1 & 0x00FC0000L) >> 10;
*Cook++ |= (*Raw1 & 0x00000FC0L) >> 6;
*Cook = (*Raw0 & 0x0003F000L) << 12;
*Cook |= (*Raw0 & 0x0000003FL) << 16;
*Cook |= (*Raw1 & 0x0003F000L) >> 4;
*Cook++ |= (*Raw1 & 0x0000003FL);
}
// 将结果存入Knl
Usekey(Dough);
return;
}
/****************************************************************/
/* 函数名: Copykey() */
/* 功能: 实现密钥的拷贝,将存放在KnL中的密钥拷贝到目的地址*/
/* 参数: */
/* Into-----指向密钥拷贝的目的地址 */
/****************************************************************/
void Copykey(register unsigned long *Into)
{
register unsigned long *From, *EndPtr;
From = KnL, EndPtr = &KnL[32];
while( From < EndPtr )
*Into++ = *From++;
return;
}
/********************************************************************************/
/* 函数名: Scrunch() */
/* 功能: 将输入的8字节数据进行分组,相当于DES算法中的IP排列操作 */
/* 生成两个32Bits的Work[0]和Work[1](L0和R0) */
/* 参数: */
/* Outof----指向输入的8字节数据 */
/* Into-----指向存储两个32Bits数据的Work数组 */
/********************************************************************************/
static void Scrunch(register unsigned short int *Outof,register unsigned long *Into)
{
*Into = (*Outof++ & 0xFFL) << 24;
*Into |= (*Outof++ & 0xFFL) << 16;
*Into |= (*Outof++ & 0xFFL) << 8;
*Into++ |= (*Outof++ & 0xFFL);
*Into = (*Outof++ & 0xFFL) << 24;
*Into |= (*Outof++ & 0xFFL) << 16;
*Into |= (*Outof++ & 0xFFL) << 8;
*Into |= (*Outof & 0xFFL);
return;
}
/********************************************************************************/
/* 函数名: Unscrun() */
/* 功能: 将输入的两个32Bits的加密/解密后的数据重新组合成8字节的密文/明文 */
/* 参数: */
/* Outof----指向输入的存储两个32Bits数据的Work数组 */
/* Into-----指向输出的8字节密文/明文 */
/********************************************************************************/
static void Unscrun(register unsigned long *Outof,register unsigned short int *Into)
{
*Into++ = (unsigned short int)((*Outof >> 24) & 0xFFL);
*Into++ = (unsigned short int)((*Outof >> 16) & 0xFFL);
*Into++ = (unsigned short int)((*Outof >> 8) & 0xFFL);
*Into++ = (unsigned short int)( *Outof++ & 0xFFL);
*Into++ = (unsigned short int)((*Outof >> 24) & 0xFFL);
*Into++ = (unsigned short int)((*Outof >> 16) & 0xFFL);
*Into++ = (unsigned short int)((*Outof >> 8) & 0xFFL);
*Into = (unsigned short int)( *Outof & 0xFFL);
return;
}
/********************************************************************************/
/* 函数名: DesCore() */
/* 功能: 用Keys所指向的16个48位的加/解密子密钥,完成16次迭代加/解密 */
/* 是DES算法实现的核心部分 */
/* 参数: */
/* Block----指向输入的经排列组合后的明文数据的指针 */
/* Keys-----指向存储16个子密钥的数据结构的指针 */
/********************************************************************************/
static void DesCore(register unsigned long *Block,register unsigned long *Keys)
{
register unsigned long Temp, Work, Right, Left;
register int Round;
Left = Block[0];
Right = Block[1];
Work = ((Left >> 4) ^ Right) & 0x0F0F0F0FL;
Right ^= Work;
Left ^= (Work << 4);
Work = ((Left >> 16) ^ Right) & 0x0000FFFFL;
Right ^= Work;
Left ^= (Work << 16);
Work = ((Right >> 2) ^ Left) & 0x33333333L;
Left ^= Work;
Right ^= (Work << 2);
Work = ((Right >> 8) ^ Left) & 0x00FF00FFL;
Left ^= Work;
Right ^= (Work << 8);
Right = ((Right << 1) | ((Right >> 31) & 1L)) & 0xFFFFFFFFL;
Work = (Left ^ Right) & 0xAAAAAAAAL;
Left ^= Work;
Right ^= Work;
Left = ((Left << 1) | ((Left >> 31) & 1L)) & 0xFFFFFFFFL;
for( Round = 0; Round < 8; Round++ )
{
Work = (Right << 28) | (Right >> 4);
Work ^= *Keys++;
Temp = SP7[ Work & 0x3FL];
Temp |= SP5[(Work >> 8) & 0x3FL];
Temp |= SP3[(Work >> 16) & 0x3FL];
Temp |= SP1[(Work >> 24) & 0x3FL];
Work = Right ^ *Keys++;
Temp |= SP8[ Work & 0x3FL];
Temp |= SP6[(Work >> 8) & 0x3FL];
Temp |= SP4[(Work >> 16) & 0x3FL];
Temp |= SP2[(Work >> 24) & 0x3FL];
Left ^= Temp;
Work = (Left << 28) | (Left >> 4);
Work ^= *Keys++;
Temp = SP7[ Work & 0x3FL];
Temp |= SP5[(Work >> 8) & 0x3FL];
Temp |= SP3[(Work >> 16) & 0x3FL];
Temp |= SP1[(Work >> 24) & 0x3FL];
Work = Left ^ *Keys++;
Temp |= SP8[ Work & 0x3FL];
Temp |= SP6[(Work >> 8) & 0x3FL];
Temp |= SP4[(Work >> 16) & 0x3FL];
Temp |= SP2[(Work >> 24) & 0x3FL];
Right ^= Temp;
}
Right = (Right << 31) | (Right >> 1);
Work = (Left ^ Right) & 0xAAAAAAAAL;
Left ^= Work;
Right ^= Work;
Left = (Left << 31) | (Left >> 1);
Work = ((Left >> 8) ^ Right) & 0x00FF00FFL;
Right ^= Work;
Left ^= (Work << 8);
Work = ((Left >> 2) ^ Right) & 0x33333333L;
Right ^= Work;
Left ^= (Work << 2);
Work = ((Right >> 16) ^ Left) & 0x0000FFFFL;
Left ^= Work;
Right ^= (Work << 16);
Work = ((Right >> 4) ^ Left) & 0x0F0F0F0FL;
Left ^= Work;
Right ^= (Work << 4);
*Block++ = Right;
*Block = Left;
return;
}
/********************************************************************************/
/* 函数名: Des8() */
/* 功能: 实现Single-DES 算法,根据Mode生成16个48位的加/解密子密钥, */
/* 把待加/解密的数据分割成64位的块,逐块完成16次迭代加/解密, */
/* 加/解密后的结果存放在OutData所指向的内存中. */
/* 8字节待加/解密数据输入,8字节密钥、8字节加/解密后数据输出 */
/* 参数: */
/* InData----存放待加/解密的内存指针(长度为Readlen,可能经过填充) */
/* Key-------存放用户输入的密钥内存的指针 */
/* OutData---存放加/解密后的输出结果 */
/* Mode------加/解密选择(加密=EN0,解密=DE1) */
/* Readlen---待加/解密的长度(8字节的倍数,如:8字节数据readlen=1 */
/* 16字节数据readlen=2等等) */
/********************************************************************************/
extern void Des8(unsigned short int *InData,unsigned short int *Key,unsigned short int *OutData,short Mode,int Readlen)
{
int i=0;
unsigned long Work[2];
unsigned short int *InputPtr,*OutputPtr;
InputPtr = InData;
OutputPtr = OutData;
// 由八字节Key,根据Mode(加/解密=EN0/DE1=0/1)所指方式
// 生成16个48位的加/解密子密钥,密钥存入KnL中
Get_Subkey(Key,Mode);
for(i=0;i<Readlen;i++)
{
Scrunch(InputPtr,Work);
// 用KnL中的16个48位的加/解密子密钥,完成16次迭代加/解密
DesCore(Work,KnL);
Unscrun(Work,OutputPtr);
// 指向下一组数据
InputPtr+=8;
OutputPtr+=8;
}
}
/********************************************************************************/
/* 函数名: Des16() */
/* 功能: 实现Triple-DES 算法,根据Mode生成三组各16个48位的加/解密子密钥, */
/* 把待加/解密的数据分割成64位的块,逐块由key左右各半部分进行三遍 */
/* 16次迭代加/解密,加/解密后的结果存放在OutData所指向的内存中.8字 */
/* 节待加/解密数据输入,16字节密钥、8字节加/解密后数据输出 */
/* 参数: */
/* InData----存放待加/解密的内存指针(长度为Readlen,可能经过填充) */
/* Key-------存放用户输入的密钥内存的指针 */
/* OutData---存放加/解密后的输出结果 */
/* Mode------加/解密选择(加密=EN0,解密=DE1) */
/* Readlen---待加/解密的长度(8字节的倍数,如:8字节数据Readlen=1, */
/* 16字节数据Readlen=2等等) */
/********************************************************************************/
extern void Des16(unsigned short int *InData,unsigned short int *Key,unsigned short int *OutData,short Mode,int Readlen)
{
short Workmode;
int i=0;
unsigned long Work[2];
unsigned short int *InputPtr,*OutputPtr;
InputPtr = InData;
OutputPtr = OutData;
Workmode = (Mode == EN0) ? DE1 : EN0;
Get_Subkey(&Key[8], Workmode);
// 将KnL复制到KnR中
Copykey(KnR);
// 由十六字节key的左半部分,根据Mode(加/解密=EN0/DE1=0/1)所指方式,
// 生成16个48位的加/解密子密钥,子密钥存入KnL中
Get_Subkey(Key, Mode);
// 将KnL复制到Kn3中
Copykey(Kn3); // 此时KnL由key左半部分生成
// KnR由key右半部分生成
// Kn3由key左半部分生成,KnL==Kn3
for(i=0;i<Readlen;i++)
{
Scrunch(InputPtr, Work);
// 用KnL中的16个48位的加/解密子密钥,完成16次迭代加/解密
DesCore(Work, KnL);
// 用KnR中的16个48位的加/解密子密钥,完成16次迭代加/解密
DesCore(Work, KnR);
// 用Kn3中的16个48位的加/解密子密钥,完成16次迭代加/解密
DesCore(Work, Kn3);
Unscrun(Work, OutputPtr);
// 指向下一组数据
InputPtr+=8;
OutputPtr+=8;
}
}
/******************************************************************************/
/* No more */
/******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -