📄 des.cpp
字号:
*
* DESCRIPTION: Generate key schedule for given key and type of cryption.
*
* PARAMETERS: sw1 (in) == FALSE for ignoring parity
* == TRUE for checking parity
*
* sw2 (in) == FALSE for encryption
* == TRUE for decryption
*
* pkey (in) 64-bit key packed in 8 bytes
*
* RETURN: TRUE - if successful
* FALSE - if failed due to bad parity
*
* NOTES: none.
*
* ------------------------------------------------------------------------ */
byte DES_SetKey (byte sw1, byte sw2, byte *pkey)
{
byte i, j, k, t1, t2;
byte key[64];
byte CD[56];
/* Unpack KEY from 8 bits/byte into 1 bit/byte */
Unpack8(pkey, key);
/* Permute unpacked key with PC1 to generate C and D */
for (i = 0; i < 56; i++)
CD[i] = key[PC1[i]];
/* Rotate and permute C and D to generate 16 subkeys */
for (i = 0; i < 16; i++)
{
/* Rotate C and D */
for (j = 0; j < shifts[i]; j++)
{
t1 = CD[0];
t2 = CD[28];
for (k = 0; k < 27; k++)
{
CD[k] = CD[k + 1];
CD[k + 28] = CD[k + 29];
}
CD[27] = t1;
CD[55] = t2;
}
/* Set order of subkeys for type of cryption */
j = sw2 ? 15-i : i;
/* Permute C and D with PC2 to generate KS[j] */
#ifdef FASTER
t1 = 0;
for (k = 0; k < 2; k++)
{
usint Temp0, Temp1;
Temp0 = Temp1 = 0;
t2 = t1 + 6;
do {
Temp0 = Temp0 << 1 | CD[PC2[t1]];
Temp1 = Temp1 << 1 | CD[PC2[t1 + 6]];
} while (++t1 != t2);
t2 = (t1 += 6) + 6;
Temp0 <<= 2;
Temp1 <<= 2;
do {
Temp0 = Temp0 << 1 | CD[PC2[t1]];
Temp1 = Temp1 << 1 | CD[PC2[t1 + 6]];
} while (++t1 != t2);
KS[j][k] = Temp0;
KS[j][k + 2] = Temp1;
t1 += 6;
}
#else
for (k = 0; k < 48; k++)
KS[j][k] = CD[PC2[k]];
#endif
}
return TRUE;
}
/* --------------------------------------------------------------------------
*
* FUNCTION NAME: DES_DEA
*
* DESCRIPTION: Set key and Performes the encryption
* of a given block
*
* PARAMETERS: in (in) : packed 64-bit input block
*
* out (out) : packed 64-bit output block
*
* key (in) : packed 64-bit key blook
*
* RETURN: none.
*
* NOTES: none.
*
* ------------------------------------------------------------------------ */
void DES_DEA (byte *in, byte *out, byte *key)
{
DES_SetKey(0, 0, key); /* Encrypt - ignoring parity */
DES_DES(in, out);
}
/* --------------------------------------------------------------------------
*
* FUNCTION NAME: DES_UDEA
*
* DESCRIPTION: Set key and Performes the decryption
* of a given block
*
* PARAMETERS: in (in) : packed 64-bit input block
*
* out (out) : packed 64-bit output block
*
* key (in) : packed 64-bit key blook
*
* RETURN: none.
*
* NOTES: Added in Jun-24-1999 for PBOC
*
* ------------------------------------------------------------------------ */
void DES_UDEA (byte *in, byte *out, byte *key)
{
DES_SetKey(0, 1, key); /* decrypt - ignoring parity */
DES_DES(in, out);
}
/* --------------------------------------------------------------------------
*
* FUNCTION NAME: DES_DES
*
* DESCRIPTION: Performes the encryption or decription of a given block
*
* PARAMETERS: in (in) : packed 64-bit input block
*
* out (out) : packed 64-bit output block
*
* RETURN: none.
*
* NOTES: none.
*
* ------------------------------------------------------------------------ */
void DES_DES (byte *in, byte *out /* packed 64-bit INPUT/OUTPUT blocks */)
{
#ifdef FASTER
/* #define INTEL - For debugging only! (with borland) !!!!!!!!!! */
#ifdef INTEL /* (LSByte first) */
#define Swap4(indx) ((indx) > 1 ? 5 - (indx) : 1 - (indx))
#else /* MOTOROLA: (MSByte first) */
#define Swap4(indx) (indx)
#endif
byte L[4], R[4];
#define Lhigh (*(usint *)&L[0])
#define Llow (*(usint *)&L[2])
#define Rhigh (*(usint *)&R[0])
#define Rlow (*(usint *)&R[2])
{ /* Permute input to generate L and R: */
byte C, Mask;
Rhigh = Rlow = Lhigh = Llow = 0; /* Clear L and R: */
for (Mask = 1; Mask != 0; Mask <<= 1)
{
C = *in++; if (C & 0x80) R[Swap4(0)] |= Mask;
C <<= 1 ; if (C & 0x80) L[Swap4(0)] |= Mask;
C <<= 1 ; if (C & 0x80) R[Swap4(1)] |= Mask;
C <<= 1 ; if (C & 0x80) L[Swap4(1)] |= Mask;
C <<= 1 ; if (C & 0x80) R[Swap4(2)] |= Mask;
C <<= 1 ; if (C & 0x80) L[Swap4(2)] |= Mask;
C <<= 1 ; if (C & 0x80) R[Swap4(3)] |= Mask;
C <<= 1 ; if (C & 0x80) L[Swap4(3)] |= Mask;
}
}
{ /* Main processing: */
usint *KeyPtr, Tmp;
byte Sixes0[4], Sixes1[4], Count;
#define Sixes0high (*(usint *)&Sixes0[0])
#define Sixes0low (*(usint *)&Sixes0[2])
#define Sixes1high (*(usint *)&Sixes1[0])
#define Sixes1low (*(usint *)&Sixes1[2])
KeyPtr = &KS[0][0] - 1;
for (Count = 0; Count < 16; Count++)
{
KeyPtr++; Sixes0high = Rhigh >> 3 & 0x1F3F ^ *KeyPtr;
KeyPtr++; Sixes0low = Rlow >> 3 & 0x1F3F ^ *KeyPtr;
/* Completing the rotation: */
if (R[Swap4(1)] & 1)
Sixes0[Swap4(2)] ^= 0x20;
if (R[Swap4(3)] & 1)
Sixes0[Swap4(0)] ^= 0x20;
KeyPtr++; Sixes1high = Rhigh << 1 & 0x3F3E ^ *KeyPtr;
KeyPtr++; Sixes1low = Rlow << 1 & 0x3F3E ^ *KeyPtr;
/* Completing the rotation: */
if (R[Swap4(2)] & 0x80)
Sixes1[Swap4(1)] ^= 1;
if (R[Swap4(0)] & 0x80)
Sixes1[Swap4(3)] ^= 1;
Tmp = Rhigh;
Rhigh = Lhigh ^ SP00high[Sixes0[Swap4(0)]]
^ SP01high[Sixes1[Swap4(0)]]
^ SP10high[Sixes0[Swap4(1)]]
^ SP11high[Sixes1[Swap4(1)]]
^ SP20high[Sixes0[Swap4(2)]]
^ SP21high[Sixes1[Swap4(2)]]
^ SP30high[Sixes0[Swap4(3)]]
^ SP31high[Sixes1[Swap4(3)]];
Lhigh = Tmp;
Tmp = Rlow;
Rlow = Llow ^ SP00low[Sixes0[Swap4(0)]]
^ SP01low[Sixes1[Swap4(0)]]
^ SP10low[Sixes0[Swap4(1)]]
^ SP11low[Sixes1[Swap4(1)]]
^ SP20low[Sixes0[Swap4(2)]]
^ SP21low[Sixes1[Swap4(2)]]
^ SP30low[Sixes0[Swap4(3)]]
^ SP31low[Sixes1[Swap4(3)]];
Llow = Tmp;
}
}
{ /* Permute L and R to generate output: */
byte C, Mask;
for (Mask = 1; Mask != 0; Mask <<= 1)
{
C = (L[Swap4(0)] & Mask) == 0 ? 0 : 128;
if ((R[Swap4(0)] & Mask) != 0) C |= 64;
if ((L[Swap4(1)] & Mask) != 0) C |= 32;
if ((R[Swap4(1)] & Mask) != 0) C |= 16;
if ((L[Swap4(2)] & Mask) != 0) C |= 8;
if ((R[Swap4(2)] & Mask) != 0) C |= 4;
if ((L[Swap4(3)] & Mask) != 0) C |= 2;
if ((R[Swap4(3)] & Mask) != 0) C |= 1;
*out++ = C;
}
}
#else
byte i, j, k, t;
byte block[64]; /* unpacked 64-bit input/output block */
byte LR[64], f[32], preS[48];
/* Unpack the INPUT block */
Unpack8(in, block);
/* Permute unpacked input block with IP to generate L and R */
for (j = 0; j < 64; j++)
LR[j] = block[IP[j] - 1];
/* Perform 16 rounds */
for (i = 0; i < 16; i++)
{
/* Expand R to 48 bits with E and XOR with i-th subkey */
for (j = 0; j < 48; j++) preS[j] = LR[E[j]+31] ^ KS[i][j];
/* Map 8 6-bit blocks into 8 4-bit blocks using S-Boxes */
for (j = 0; j < 8; j++)
{
/* Compute index t into j-th S-box */
k = 6 * j;
t = preS[k];
t = (t << 1) | preS[k + 5];
t = (t << 1) | preS[k + 1];
t = (t << 1) | preS[k + 2];
t = (t << 1) | preS[k + 3];
t = (t << 1) | preS[k + 4];
/* Fetch t-th entry from j-th S-box */
t = S[j][t];
/* Generate 4-bit block from S-box entry */
k = 4 * j;
f[k] = (t >> 3) & 1;
f[k + 1] = (t >> 2) & 1;
f[k + 2] = (t >> 1) & 1;
f[k + 3] = t & 1;
}
for (j = 0; j < 32; j++)
{
/* Copy R */
t = LR[j + 32];
/* Permute f w/ P and XOR w/ L to generate new R */
LR[j + 32] = LR[j] ^ f[P[j] - 1];
/* Copy original R to new L */
LR[j] = t;
}
}
/* Permute L and R with reverse IP-1 to generate output block */
for (j = 0; j < 64; j++)
block[j] = LR[RFP[j] - 1];
/* Pack data into 8 bits per byte */
Pack8(out, block);
#endif
/*WATCH_DOG_RESET*/ /*Marked by BBM in July-15-1998*/
}
/*-----------------------------------------------------------------------
* FUNCTION NAME: DES_3DEA
* DESCRIPTION: perform 3 DEA
* PARAMETERS: s_in - source data (8 bytes)
* r_out - output result (8 bytes)
* key - key (16 bytes)
* RETURN: void
* NOTE: Added in Jun-24-1999 for PBOC
*----------------------------------------------------------------------*/
void DES_3DEA(byte *s_in, byte *r_out, byte *key)
{
unsigned char t_out1[8],
t_out2[8];
DES_DEA((unsigned char*)s_in, (unsigned char*)t_out1, (unsigned char*)&key[0]); /* Encrypt by left half Key */
DES_UDEA((unsigned char*)t_out1, (unsigned char*)t_out2, (unsigned char*)&key[8]); /* Decrypt by right half Key */
DES_DEA((unsigned char*)t_out2, (unsigned char*)r_out,(unsigned char*)&key[0]); /* Encrypt by left half Key */
}
/*-----------------------------------------------------------------------
* FUNCTION NAME: DES_3UDEA
* DESCRIPTION: unperform 3 DEA
* PARAMETERS: s_in - source data (8 bytes)
* r_out - output result (8 bytes)
* key - key (16 bytes)
* RETURN: void
* NOTE: Added in Jun-24-1999 for PBOC
*----------------------------------------------------------------------*/
void DES_3UDEA(byte *s_in, byte *r_out, byte *key)
{
unsigned char t_out1[8],
t_out2[8];
DES_UDEA((unsigned char*)s_in, (unsigned char*)t_out1, (unsigned char*)&key[0]); /* Encrypt by left half Key */
DES_DEA((unsigned char*)t_out1, (unsigned char*)t_out2, (unsigned char*)&key[8]); /* Decrypt by right half Key */
DES_UDEA((unsigned char*)t_out2, (unsigned char*)r_out,(unsigned char*)&key[0]); /* Encrypt by left half Key */
}
/* ======================================= *
* P R I V A T E F U N C T I O N S *
* ======================================= */
#ifndef FASTER
/* --------------------------------------------------------------------------
*
* FUNCTION NAME: Pack8
*
* DESCRIPTION: Pack 64 bytes at 1 bit/byte into 8 bytes at 8 bits/byte
*
* PARAMETERS: ascii (out) : packed block (8 bytes - 8 bits per byte)
*
* binary (in) : unpacked block (64 bytes - 1 bit per byte)
*
* RETURN: none.
*
* NOTES: none.
*
* ------------------------------------------------------------------------ */
void Pack8 (byte *ascii, byte *binary)
{
byte i, j, k;
for (i = 0; i < 8; i++)
{
k = 0;
for (j = 0; j < 8; j++)
k = (k << 1) + *binary++;
*ascii++ = k;
}
}
#endif
/* --------------------------------------------------------------------------
*
* FUNCTION NAME: Unpack8
*
* DESCRIPTION: Unpack 8 bytes at 8 bits/byte into 64 bytes at 1 bit/byte
*
* PARAMETERS: ascii (in) : packed block (8 bytes - 8 bits per byte)
*
* binary (out) : unpacked block (64 bytes - 1 bit per byte)
*
* RETURN: none.
*
* NOTES: none.
*
* ------------------------------------------------------------------------ */
void Unpack8 (byte *ascii, byte *binary)
{
byte i, j, k;
for (i = 0; i < 8; i++)
{
#if 1
j = 7;
k = *ascii++;
for (;;)
{
*binary++ = (k & 0x80) != 0;
if (j == 0)
break;
j--;
k <<= 1;
}
#else /* Slower method: */
k = *ascii++;
for (j = 0; j < 8; j++)
*binary++ = (k >> (7 - j)) & 1;
#endif
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -