Mastering Algorithms With C - Kyle Loudon [187]
* *
*****************************************************************************/
memset(temp, 0, (int)ceil(n / 8));
for (i = 0; i < n; i++)
bit_set(temp, i, bit_get(bits, mapping[i] - 1));
memcpy(bits, temp, (int)ceil(n / 8));
return;
}
/*****************************************************************************
* *
* ------------------------------- des_main ------------------------------- *
* *
*****************************************************************************/
static int des_main(const unsigned char *source, unsigned char *target, const
unsigned char *key, DesEorD direction) {
static unsigned char subkeys[16][7];
unsigned char temp[8],
lkey[4],
rkey[4],
lblk[6],
rblk[6],
fblk[6],
xblk[6],
sblk;
int row,
col,
i,
j,
k,
p;
/*****************************************************************************
* *
* If key is NULL, use the subkeys as computed in a previous call. *
* *
*****************************************************************************/
if (key != NULL) {
/**************************************************************************
* *
* Make a local copy of the key. *
* *
**************************************************************************/
memcpy(temp, key, 8);
/**************************************************************************
* *
* Permute and compress the key into 56 bits. *
* *
**************************************************************************/
permute(temp, DesTransform, 56);
/**************************************************************************
* *
* Split the key into two 28-bit blocks. *
* *
**************************************************************************/
memset(lkey, 0, 4);
memset(rkey, 0, 4);
for (j = 0; j < 28; j++)
bit_set(lkey, j, bit_get(temp, j));
for (j = 0; j < 28; j++)
bit_set(rkey, j, bit_get(temp, j + 28));
/**************************************************************************
* *
* Compute the subkeys for each round. *
* *
**************************************************************************/
for (i = 0; i < 16; i++) {
/***********************************************************************
* *
* Rotate each block according to its round. *
* *
***********************************************************************/
bit_rot_left(lkey, 28, DesRotations[i]);
bit_rot_left(rkey, 28, DesRotations[i]);
/***********************************************************************
* *
* Concatenate the blocks into a single subkey. *
* *
***********************************************************************/
for (j = 0; j < 28; j++)
bit_set(subkeys[i], j, bit_get(lkey, j));
for (j = 0; j < 28; j++)
bit_set(subkeys[i], j + 28, bit_get(rkey, j));
/***********************************************************************
* *
* Do the permuted choice permutation. *
* *
***********************************************************************/
permute(subkeys[i], DesPermuted, 48);
}
}
/*****************************************************************************
* *
* Make a local copy of the source text. *
* *
*****************************************************************************/
memcpy(temp, source, 8);
/*****************************************************************************
* *
* Do the initial permutation. *
* *
*****************************************************************************/
permute(temp, DesInitial, 64);
/*****************************************************************************
* *
* Split the source text into a left and right block of 32 bits. *
* *
*****************************************************************************/
memcpy(lblk, &temp[0], 4);
memcpy(rblk, &temp[4], 4);
/*****************************************************************************
* *
* Encipher or decipher the source text. *
* *
*****************************************************************************/
for (i = 0; i < 16;