📄 h_des.cpp
字号:
if (doEncrypt)
{
/* Do the 16 rounds */
for (i = 0; i < 16; i++)
Round(i, work);
/* Left/right half swap */
tmp = work[0];
work[0] = work[1];
work[1] = tmp;
} /* end of if */
else
{
/* Left/right half swap */
tmp = work[0];
work[0] = work[1];
work[1] = tmp;
/* Do the 16 rounds in reverse order */
for (i = 15; i >= 0; i--)
Round(i, work);
} /* end of else */
work[0] = ByteSwap(work[0]);
work[1] = ByteSwap(work[1]);
/* Inverse initial permutation */
Permute((BYTE *)work, fperm, data);
} /* DES() */
/************************************************************************
* Function name : SetKey
* Description : initialize key schedule array
* :
* Parameters : key
* Returns : -
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 20Jan99 RCS Created.
************************************************************************/
static void SetKey(const IN BYTE *key)
{
char pc1m[56]; /* Place to modify pc1 into */
char pcr[56]; /* Place to rotate pc1 into */
register int i ,j , k;
int m;
#if 0
/*
In mode 2, the 128 bytes of subkey are set directly from the
user's key, allowing him to use completely independent
subkeys for each round. Note that the user MUST specify a
full 128 bytes.
I would like to think that this technique gives the NSA a real
headache, but I'm not THAT naive.
*/
if (desmode == 2)
{
for (i = 0; i < 16; i++)
{
for (j = 0; j < 8; j++)
kn[i][j] = *key++;
} /* end of for i */
return;
} /* end of if */
#endif
/* Clear key schedule */
for (i = 0; i < 16; i++)
{
for (j = 0; j < 8; j++)
kn[i][j] = 0;
} /* end of for i */
/* Convert pc1 to bits of key */
for (j = 0; j < 56; j++)
{
k = pc1[j] - 1; /* Integer bit location */
m = k & 07; /* find bit */
/*
Find which key byte l is in and which bit of that byte
and store 1-bit result
*/
pc1m[j] = (key[k >> 3] & byteBit[m]) ? 1 : 0;
} /* end of for j */
/* Key chunk for each iteration */
for (i = 0; i < 16; i++)
{
/* rotate pc1 the right amount */
for (j = 0; j < 56; j++)
{
k = j + totRot[i];
pcr[j] = pc1m[(k < (j < 28 ? 28 : 56)) ? k : k - 28];
} /* end of for j */
/* Rotate left and right halves independently */
for (j=0; j<48; j++)
{
/* Select bits individually, check bit that goes to kn[j] */
if (pcr[pc2[j] - 1])
{
/* mask it in if it's there */
k = j % 6;
kn[i][j / 6] |= byteBit[k] >> 2;
} /* end of if */
} /* end of j */
} /* end of for i */
return;
} /* SetKey() */
/************************************************************************
* Function name : Permute
* Description :
* :
* Parameters : inBlock -
* : perm -
* : outBlock -
* Returns : -
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 20Jan99 RCS Created.
************************************************************************/
static void Permute(BYTE *inBlock, char perm[16][16][8],
BYTE *outBlock
)
{
int i;
int j;
char *p;
char *q;
BYTE *oBlock;
if (perm == NULL)
{
/* No permutation, just copy */
for (i = 8; i != 0; i--)
*outBlock++ = *inBlock++;
return;
} /* end of if */
/* Clear output block */
memset(outBlock, 0, 8);
for (j = 0; j < 16; j += 2)
{
oBlock = outBlock;
/* For each input nibble and each output byte, OR the masks together */
p = perm[j][(*inBlock >> 4) & 017];
q = perm[j + 1][*inBlock & 017];
for (i = 8; i != 0; i--)
*oBlock++ |= *p++ | *q++;
inBlock++;
} /* end of for j */
return;
} /* Permute() */
/************************************************************************
* Function name : Round
* Description : Do one DES cipher round
* :
* Parameters : num -
* : block -
* Returns : -
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 20Jan99 RCS Created.
************************************************************************/
static void Round(int num, DWORD *block)
{
/*
The rounds are numbered from 0 to 15. On even rounds
the right half is fed to f() and the result exclusive-ORs
the left half; on odd rounds the reverse is done.
*/
if (num & 1)
block[1] ^= F_DES(block[0], kn[num]);
else
block[0] ^= F_DES(block[1], kn[num]);
return;
} /* Round() */
/************************************************************************
* Function name : F_DES
* Description : The nonlinear function F(r, k), the heart of DES
* :
* Parameters : r -
* : subKey -
* Returns : ...
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 20Jan99 RCS Created.
************************************************************************/
static long F_DES(DWORD r, BYTE subKey[8])
{
DWORD rVal, rt;
/*
Run E(R) ^ K through the combined S & P boxes
This code takes advantage of a convenient regularity in
E, namely that each group of 6 bits in E(R) feeding
a single S-box is a contiguous segment of R.
*/
rt = (r >> 1) | ((r & 1) ? 0x80000000 : 0);
rVal = 0;
rVal |= sp[0][((rt >> 26) ^ *subKey++) & 0x3f];
rVal |= sp[1][((rt >> 22) ^ *subKey++) & 0x3f];
rVal |= sp[2][((rt >> 18) ^ *subKey++) & 0x3f];
rVal |= sp[3][((rt >> 14) ^ *subKey++) & 0x3f];
rVal |= sp[4][((rt >> 10) ^ *subKey++) & 0x3f];
rVal |= sp[5][((rt >> 6) ^ *subKey++) & 0x3f];
rVal |= sp[6][((rt >> 2) ^ *subKey++) & 0x3f];
rt = (r << 1) | ((r & 0x80000000) ? 1 : 0);
rVal |= sp[7][(rt ^ *subKey) & 0x3f];
return rVal;
} /* F_DES() */
/************************************************************************
* Function name : PermInit
* Description : Initialize a perm array
* :
* Parameters :
* Returns :
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 20Jan99 RCS Created.
************************************************************************/
static void PermInit(char perm[16][16][8], const char p[64])
{
int i, j, k, m, n;
/* Clear the permutation array */
for (i = 0; i < 16; i++)
{
for (j = 0; j < 16; j++)
{
for (k = 0; k < 8; k++)
perm[i][j][k]=0;
} /* end of for j */
} /* end of for i */
for (i = 0; i < 16; i++) /* Each input nibble position */
{
for (j = 0; j < 16; j++) /* Each possible input nibble */
{
for (k = 0; k < 64; k++) /* Each output bit position */
{
n = p[k] - 1;
/* Does this bit come from input position ? */
if ((n >> 2) != i)
continue; /* No, bit k is 0 */
if (!(j & nibbleBit[n & 3]))
continue;
m = k & 07; /* Which bit is this in the byte */
perm[i][j][k >> 3] |= byteBit[m];
} /* end of for k */
} /* end of for j */
} /* end of for i */
return;
} /* PermInit() */
/************************************************************************
* Function name : SPInit
* Description : Initialize the lookup table for the combined S and P
* : boxes
* Parameters : -
* Returns : -
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 20Jan99 RCS Created.
************************************************************************/
static void SPInit(void)
{
char pBox[32];
int p, i, s, j, rowCol;
long val;
/* Compute pbox, the inverse of p32i. This is easier to work with. */
for (p = 0; p < 32; p++)
{
for (i = 0;i < 32; i++)
{
if (p32i[i] - 1 == p)
{
pBox[p] = i;
break;
} /* end of if */
} /* end of for i */
} /* end of for p */
for (s = 0; s < 8; s++) /* For each S-box */
{
for(i = 0; i < 64; i++) /* For each possible input */
{
val = 0;
/*
The row number is formed from the first and last
bits; the column number is from the middle 4.
*/
rowCol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf);
for (j = 0; j < 4; j++) /* For each output bit */
{
if (si[s][rowCol] & (8 >> j))
val |= 1L << (31 - pBox[4 * s + j]);
} /* end of for */
sp[s][i] = val;
} /* end of for */
} /* end of for s */
return;
} /* SPInit() */
/************************************************************************
* Function name : ByteSwap
* Description : Byte swap a long
* :
* Parameters : x
* Returns : ...
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 20Jan99 RCS Created.
************************************************************************/
static DWORD ByteSwap(DWORD x)
{
char tmp;
char *cp;
cp = (char *)&x;
tmp = cp[3];
cp[3] = cp[0];
cp[0] = tmp;
tmp = cp[2];
cp[2] = cp[1];
cp[1] = tmp;
return x;
} /* ByteSwap() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -