шифрованию.
--------------------------------------------------------------
*/
void DES_Encrypt(unsigned char* fpsbyteSource,
unsigned char* fpsbyteDestination,
unsigned char* fpsbyteKey,
int intBlocks);
/*
--------------------------------------------------------------
Дешифрование данных по алгоритму DES в режиме ECB.
--------------------------------------------------------------
fpsbyteSource - зашифрованные данные блоками по 8 байтов.
fpsbyteDestination - дешифрованные данные блоками по 8
байтов; устанавливается при завершении
функции.
fpsbyteKey - ключ шифрования длиной 8 байтов; из них реально
используются 56 битов.
intBlocks - количество блоков, подлежащих дешифрованию.
--------------------------------------------------------------
*/
void DES_Decrypt(unsigned char* fpsbyteSource,
unsigned char* fpsbyteDestination,
unsigned char* fpsbyteKey,
int intBlocks);
Файл des.c
#include "des.h"
#include <mem.h>
static unsigned char sbyteInitialSwapTable[65]=
{58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17, 9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7,0};
static unsigned char sbyteFinalSwapTable[65]=
{40,8,48,16,56,24,64,32,
39,7,47,15,55,23,63,31,
38,6,46,14,54,22,62,30,
37,5,45,13,53,21,61,29,
36,4,44,12,52,20,60,28,
35,3,43,11,51,19,59,27,
34,2,42,10,50,18,58,26,
33,1,41, 9,49,17,57,25,0};
static unsigned char sbyteE_SwapTable[49]=
{32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9,10,11,12,13,
12,13,14,15,16,17,
16,17,18,19,20,21,
20,21,22,23,24,25,
24,25,26,27,28,29,
28,29,30,31,32, 1,0};
static unsigned char sbyteP_SwapTable[33]=
{16, 7,20,21,
29,12,28,17,
1,15,23,26,
5,18,31,10,
2, 8,24,14,
32,27, 3, 9,
19,13,30, 6,
22,11, 4,25,0};
static unsigned char sbyteB_SwapTable[57]=
{57,49,41,33,25,17, 9,
1,58,50,42,34,26,18,
10, 2,59,51,43,35,27,
19,11, 3,60,52,44,36,
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14, 6,61,53,45,37,29,
21,13, 5,28,20,12, 4,0};
static unsigned char sbyteK_SwapTable[49]=
{14,17,11,24, 1, 5,
3,28,15, 6,21,10,
23,19,12, 4,26, 8,
16, 7,27,20,13, 2,
41,52,31,37,47,55,
30,40,51,45,33,48,
44,49,39,56,34,53,
46,42,50,36,29,32,0};
static unsigned char sbyteS_ShiftTable[16]=
{1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
static unsigned char sbyteTrans1_Table[8]=
{252,126,63,31,15,7,3,1};
static unsigned char sbyteTrans2_Table[5]=
{128,192,224,240,248};
static unsigned char sbyteS_Table[8][4][16]=
{
{{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},
{0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},
{4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},
{15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}},
{{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},
{3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},
{0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},
{13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}},
{{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},
{13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},
{13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},
{1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}},
{{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},
{13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},
{10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},
{3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}},
{{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},
{14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},
{4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},
{11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}},
{{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},
{10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},
{9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},
{4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}},
{{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},
{13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},
{1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},
{6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}},
{{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},
{1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},
{7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},
{2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}}};
static unsigned char sbyteSwapBitsShiftHashTable1[65]=
{0,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
static unsigned char sbyteSwapBitsShiftHashTable2[65]=
{0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7};
static unsigned char sbyteE_F_HashTable1[48]=
{0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5};
static unsigned char sbyteE_F_HashTable2[48]=
{0,1,2,3,4,5,6,7,
0,1,2,3,4,5,6,7,
0,1,2,3,4,5,6,7,
0,1,2,3,4,5,6,7,
0,1,2,3,4,5,6,7,
0,1,2,3,4,5,6,7};
static unsigned char sbyteE_F_HashTable3[48]=
{0, 1, 2, 3, 4, 5, 6, 7,
8, 9,10,11, 0, 1, 2, 3,
4, 5, 6, 7, 8, 9,10,11,
0, 1, 2, 3, 4, 5, 6, 7,
8, 9,10,11, 0, 1, 2, 3,
4, 5, 6, 7, 8, 9,10,11};
static unsigned char sbyteE_F_HashTable4[64]=
{0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,
2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3};
static void SwapBits(unsigned char* fpsbyteSourceBits,
unsigned char* fpsbyteDestinationBits,
unsigned char* fpsbyteSwapTable)
{
int intSourceBitNumber;
unsigned char byteDestinationBitMask=0;
unsigned char* fpbyteDestination=fpsbyteDestinationBits-1;
unsigned char* fpbyteSwapTable=fpsbyteSwapTable;
while ((intSourceBitNumber=*(fpbyteSwapTable++))!=0)
{
if (byteDestinationBitMask==0)
{
byteDestinationBitMask=0x80;
*(++fpbyteDestination)=0;
}
if (fpsbyteSourceBits[
sbyteSwapBitsShiftHashTable2[intSourceBitNumber]]&
sbyteSwapBitsShiftHashTable1[intSourceBitNumber])
*fpbyteDestination|=byteDestinationBitMask;
byteDestinationBitMask>>=1;
}
}
static void GenerateKiPrepare(unsigned char* fpsbyteKey,
unsigned char* fpsbyteInfo)
{
SwapBits(fpsbyteKey,&fpsbyteInfo[1],sbyteB_SwapTable);
fpsbyteInfo[0]=0;
}
static void GenerateKiNext(unsigned char* fpsbyteInfo,
unsigned char* fpsbyteDestination)
{
unsigned char byteHighBit1_0;
unsigned char byteHighBit1_1;
unsigned char byteHighBit1_2;
unsigned char byteHighBit1_3;
unsigned char byteHighBit2_0;
unsigned char byteHighBit2_1;
unsigned char byteHighBit2_2;
unsigned char byteHighBit2_3;
unsigned char sbyteC[4];
unsigned char sbyteD[4];
int intTotalShift;
int intShiftCounter;
sbyteC[0]=fpsbyteInfo[1];
sbyteC[1]=fpsbyteInfo[2];
sbyteC[2]=fpsbyteInfo[3];
sbyteC[3]=fpsbyteInfo[4];
sbyteD[0]=fpsbyteInfo[4];
sbyteD[1]=fpsbyteInfo[5];
sbyteD[2]=fpsbyteInfo[6];
sbyteD[3]=fpsbyteInfo[7];
intTotalShift=sbyteS_ShiftTable[fpsbyteInfo[0]];
fpsbyteInfo[0]++;
for (intShiftCounter=1;
intShiftCounter<=intTotalShift;
intShiftCounter++)
{
byteHighBit1_0=(unsigned char) ((sbyteC[0]&0x80)>>7);
byteHighBit1_1=(unsigned char) ((sbyteC[1]&0x80)>>7);
byteHighBit1_2=(unsigned char) ((sbyteC[2]&0x80)>>7);
byteHighBit1_3=(unsigned char) ((sbyteC[3]&0x80)>>7);
byteHighBit2_0=(unsigned char) ((sbyteD[0]&0x08)>>3);
byteHighBit2_1=(unsigned char) ((sbyteD[1]&0x80)>>7);
byteHighBit2_2=(unsigned char) ((sbyteD[2]&0x80)>>7);
byteHighBit2_3=(unsigned char) ((sbyteD[3]&0x80)>>7);
sbyteC[3]&=0xF0;
sbyteC[0]<<=1;
sbyteC[1]<<=1;
sbyteC[2]<<=1;
sbyteC[3]<<=1;
sbyteD[0]<<=1;
sbyteD[1]<<=1;
sbyteD[2]<<=1;
sbyteD[3]<<=1;
sbyteD[0]&=0x0F;
sbyteC[0]|=byteHighBit1_1;
sbyteC[1]|=byteHighBit1_2;
sbyteC[2]|=byteHighBit1_3;
sbyteC[3]|=(unsigned char) (byteHighBit1_0<<4);
sbyteD[0]|=byteHighBit2_1;
sbyteD[1]|=byteHighBit2_2;
sbyteD[2]|=byteHighBit2_3;
sbyteD[3]|=byteHighBit2_0;
}
fpsbyteInfo[1]=sbyteC[0];
fpsbyteInfo[2]=sbyteC[1];
fpsbyteInfo[3]=sbyteC[2];
fpsbyteInfo[4]=sbyteC[3];
fpsbyteInfo[4]|=sbyteD[0];
fpsbyteInfo[5]=sbyteD[1];
fpsbyteInfo[6]=sbyteD[2];
fpsbyteInfo[7]=sbyteD[3];
SwapBits(&fpsbyteInfo[1],fpsbyteDestination,sbyteK_SwapTable);
}
static void GenerateKiTable(unsigned char* fpsbyteKey,
unsigned char* fpsbyteKeyTable)
{
int intI;
unsigned char sbyteInfo[8];
GenerateKiPrepare(fpsbyteKey,sbyteInfo);
for (intI=0;intI<=15;intI++)
GenerateKiNext(sbyteInfo,&fpsbyteKeyTable[intI*6]);
}
static void EncryptionFn(unsigned char* fpsbyteSourceBits,
unsigned char* fpsbyteDestinationBits,
unsigned char* fpsbyteKey)
{
unsigned char sbyteSourceSwappedBits[6];
unsigned char sbyteDestinationNonSwappedBits[4];
unsigned char byteStr;
unsigned char byteCol;
unsigned char byteCurrentByte;
int intSourceBitNumber;
int intSourceBitDiv8;
int intSourceBitMod8;
int intDestinationByteNumber=0;
int intS_TableNumber=0;
memset(sbyteDestinationNonSwappedBits,0,4);
SwapBits(fpsbyteSourceBits,
sbyteSourceSwappedBits,
sbyteE_SwapTable);
((unsigned long*) sbyteSourceSwappedBits)[0]^=
((unsigned long*) fpsbyteKey)[0];
((unsigned short*) sbyteSourceSwappedBits)[2]^=
((unsigned short*) fpsbyteKey)[2];
for (intSourceBitNumber=0;
intSourceBitNumber<48;
intSourceBitNumber+=6)
{
intSourceBitDiv8=sbyteE_F_HashTable1[intSourceBitNumber];
intSourceBitMod8=sbyteE_F_HashTable2[intSourceBitNumber];
byteCurrentByte=
sbyteSourceSwappedBits[intSourceBitDiv8]&
sbyteTrans1_Table[intSourceBitMod8];
if (intSourceBitMod8<2)
byteCurrentByte>>=2-intSourceBitMod8;
else if (intSourceBitMod8>2)
{
byteCurrentByte<<=intSourceBitMod8-2;
byteCurrentByte|=(unsigned char)
((sbyteTrans2_Table[intSourceBitMod8-3]&
sbyteSourceSwappedBits[intSourceBitDiv8+1])>>
(10-intSourceBitMod8));
}
byteStr=sbyteE_F_HashTable4[byteCurrentByte];
byteCol=(unsigned char) ((byteCurrentByte&30)>>1);
byteCurrentByte=
sbyteS_Table[intS_TableNumber++][byteStr][byteCol];
if (sbyteE_F_HashTable3[intSourceBitNumber]==0)
byteCurrentByte<<=4;
sbyteDestinationNonSwappedBits[intDestinationByteNumber]|=
byteCurrentByte;
if (sbyteE_F_HashTable3[intSourceBitNumber]!=0)
intDestinationByteNumber++;
}
SwapBits(sbyteDestinationNonSwappedBits,
fpsbyteDestinationBits,
sbyteP_SwapTable);
}
static void Encrypt(unsigned char* fpsbyteSource,
unsigned char* fpsbyteDestination,
unsigned char* fpsbyteKeyTable)
{
unsigned char sbyteLeftBitsPrev[4];
unsigned char sbyteRightBitsPrev[4];
unsigned char sbyteLeftBitsCurrent[4];
unsigned char sbyteRightBitsCurrent[4];
unsigned char sbyteDestination[8];
int intIteration;
SwapBits(fpsbyteSource,sbyteDestination,sbyteInitialSwapTable);
memmove(sbyteLeftBitsPrev,&sbyteDestination[0],4);
memmove(sbyteRightBitsPrev,&sbyteDestination[4],4);
for (intIteration=1;
intIteration<=16;
intIteration++)
{
EncryptionFn(sbyteRightBitsPrev,
sbyteRightBitsCurrent,
&fpsbyteKeyTable[intIteration-1]);
((unsigned long*) sbyteLeftBitsCurrent)[0]=
((unsigned long*) sbyteRightBitsPrev)[0];
((unsigned long*) sbyteRightBitsCurrent)[0]^=
((unsigned long*) sbyteLeftBitsPrev)[0];
memmove(sbyteRightBitsPrev,sbyteRightBitsCurrent,4);
memmove(sbyteLeftBitsPrev,sbyteLeftBitsCurrent,4);
}
memmove(&sbyteDestination[0],sbyteRightBitsCurrent,4);
memmove(&sbyteDestination[4],sbyteLeftBitsCurrent,4);
SwapBits(sbyteDestination,fpsbyteDestination,sbyteFinalSwapTable);
}
static void Decrypt(unsigned char* fpsbyteSource,
unsigned char* fpsbyteDestination,
unsigned char* fpsbyteKeyTable)
{
unsigned char sbyteLeftBitsPrev[4];
unsigned char sbyteRightBitsPrev[4];
unsigned char sbyteLeftBitsCurrent[4];
unsigned char sbyteRightBitsCurrent[4];
unsigned char sbyteDestination[8];
int intIteration;
SwapBits(fpsbyteSource,sbyteDestination,sbyteInitialSwapTable);
memmove(sbyteRightBitsPrev,&sbyteDestination[0],4);
memmove(sbyteLeftBitsPrev,&sbyteDestination[4],4);
for (intIteration=16;
intIteration>=1;
intIteration--)
{
EncryptionFn(sbyteLeftBitsPrev,
sbyteLeftBitsCurrent,
&fpsbyteKeyTable[intIteration-1]);
((unsigned long*) sbyteRightBitsCurrent)[0]=
((unsigned long*) sbyteLeftBitsPrev)[0];
((unsigned long*) sbyteLeftBitsCurrent)[0]^=
((unsigned long*) sbyteRightBitsPrev)[0];
memmove(sbyteRightBitsPrev,sbyteRightBitsCurrent,4);
memmove(sbyteLeftBitsPrev,sbyteLeftBitsCurrent,4);
}
memmove(&sbyteDestination[0],sbyteLeftBitsCurrent,4);
memmove(&sbyteDestination[4],sbyteRightBitsCurrent,4);
SwapBits(sbyteDestination,fpsbyteDestination,sbyteFinalSwapTable);
}
void DES_Encrypt(unsigned char* fpsbyteSource,
unsigned char* fpsbyteDestination,
unsigned char* fpsbyteKey,
int intBlocks)
{
int intCurrentBlock;
unsigned char sbyteTableKey[96];
GenerateKiTable(fpsbyteKey,sbyteTableKey);
for (intCurrentBlock=0;
intCurrentBlock<intBlocks;
intCurrentBlock++)
Encrypt(&fpsbyteSource[intCurrentBlock*8],
&fpsbyteDestination[intCurrentBlock*8],
sbyteTableKey);
}
void DES_Decrypt(unsigned char* fpsbyteSource,
unsigned char* fpsbyteDestination,
unsigned char* fpsbyteKey,
int intBlocks)
{
int intCurrentBlock;
unsigned char sbyteTableKey[96];
GenerateKiTable(fpsbyteKey,sbyteTableKey);
for (intCurrentBlock=0;
intCurrentBlock<intBlocks;
intCurrentBlock++)
Decrypt(&fpsbyteSource[intCurrentBlock*8],
&fpsbyteDestination[intCurrentBlock*8],
sbyteTableKey);
}
Файл testdes.c
#include "des.h"
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
static int boolPerformDecryption;
static int intSourceFileHandle;
static int intDestinationFileHandle;
static int intKeyFileHandle;
static unsigned long dwordSourceFileLength;
static unsigned long dwordKeyFileLength;
static unsigned long dwordSourceFileOffset;
static char* fpszSourceFileName;
static char* fpszDestinationFileName;
static char* fpszKeyFileName;
static unsigned char sbyteSourceBuffer[8];
static unsigned char sbyteDestinationBuffer[8];
static unsigned char sbyteKeyBuffer[8];
static int OpenSourceFile(void)
{
intSourceFileHandle=open(fpszSourceFileName,O_RDONLY|O_BINARY);
if (intSourceFileHandle==-1)
{
perror("OpenSourceFile()");
return 1;
}
lseek(intSourceFileHandle,0,SEEK_END);
dwordSourceFileLength=tell(intSourceFileHandle);
lseek(intSourceFileHandle,0,SEEK_SET);
if (dwordSourceFileLength%8)
{
printf("OpenSourceFile(): длина исходного файла не кратна 8 байтам.\n");
return 1;
}
return 0;
}
static int OpenKeyFile(void)
{
intKeyFileHandle=open(fpszKeyFileName,O_RDONLY|O_BINARY);
if (intKeyFileHandle==-1)
{
perror("OpenKeyFile()");
return 1;
}
lseek(intKeyFileHandle,0,SEEK_END);
dwordKeyFileLength=tell(intKeyFileHandle);
lseek(intKeyFileHandle,0,SEEK_SET);
if (dwordKeyFileLength!=8)
{
printf("OpenKeyFile(): длина файла ключа шифрования не равна 8 байтам.\n");
return 1;
}
return 0;
}
static int ProcessSourceFile(void)
{
dwordSourceFileOffset=0;
if (read(intKeyFileHandle,sbyteKeyBuffer,8)!=8) return 1;
intDestinationFileHandle=
open(fpszDestinationFileName,
O_WRONLY|O_BINARY|O_CREAT|O_TRUNC,
S_IREAD|S_IWRITE);
if (intDestinationFileHandle==-1) return 1;
while (dwordSourceFileOffset<dwordSourceFileLength)
{
if (read(intSourceFileHandle,sbyteSourceBuffer,8)!=8)
return 1;
dwordSourceFileOffset+=8;
if (boolPerformDecryption)
DES_Decrypt(sbyteSourceBuffer,
sbyteDestinationBuffer,
sbyteKeyBuffer,
1);
else DES_Encrypt(sbyteSourceBuffer,
sbyteDestinationBuffer,
sbyteKeyBuffer,
1);
if (write(intDestinationFileHandle,
sbyteDestinationBuffer,
8)!=8) return 1;
}
return 0;
}
int main(int intArguments,char** fpArguments)
{
printf("\nШифрование данных по алгоритму DES в режиме ECB.\n\n\n");
if (intArguments==1)
{
printf("Использование: destest [-d] <исходный файл> <целевой файл> <ключ>\n\n");
printf(" <исходный файл> - имя исходного файла, длина файла должна быть кратна 8;\n");
printf(" <целевой файл> - имя целевого файла;\n");
printf(" <ключ> - имя файла с ключом шифрования длиной 8 байтов;\n");
printf(" -d - дешифровать, а не зашифровать исходный файл в целевой.\n");
return 0;
}
if (intArguments==5 && !strcmp(fpArguments[1],"-d"))
{
boolPerformDecryption=1;
fpszSourceFileName=fpArguments[2];
fpszDestinationFileName=fpArguments[3];
fpszKeyFileName=fpArguments[4];
}
else
{
boolPerformDecryption=0;
fpszSourceFileName=fpArguments[1];
fpszDestinationFileName=fpArguments[2];
fpszKeyFileName=fpArguments[3];
}
if ((intArguments!=4 && intArguments!=5) ||
(intArguments==5 && !boolPerformDecryption))
{
printf("main(): некорректный формат командной строки.\n");
return 0;
}
if (!OpenSourceFile() && !OpenKeyFile())
if (ProcessSourceFile()) perror("ProcessSourceFile()");
else printf("Обработка файла выполнена успешно.\n");
if (intSourceFileHandle!=-1) close(intSourceFileHandle);
if (intDestinationFileHandle!=-1) close(intDestinationFileHandle);
return 0;
}
Перелiк умовних позначень i скорочень
& | Логiчне I.
Логiчне АБО.
Додавання за модулем 2.
Додавання за модулем .
Адитивна iнверсiя за модулем 2.
Вiднiмання за модулем або адитивна iнверсiя за модулем .
Множення за модулем .
<<< | Циклiчний зсув улiво.
Примiтка. На малюнках можуть використовуватись iншi позначення.
Лiтература
C. Adams. Constructing Symmetric Ciphers Using the CAST Design Procedure. .
C. Adams. RFC 2144. The CAST-128 Encryption Algorithm. .
Alcourt. Differential Cryptanalysis. .
L. Brown. A Current Perspective on Encryption Algorithms. .
M. Curtin. Snake Oil Warning Signs: Encryption Software to Avoid. .
D. Eastlake, S. Crocker, J. Schiller. RFC 1750. Randomness Recommendations for Security. .
C. Ellison. Cryptographic Random Numbers. .
J. Kelsey, B. Schneier, D. Wagner, C. Hall. Cryptanalytic Attacks on Pseudorandom Number Generators. .
J. Savard. A Cryptographic Compendium. .
T. Ritter. Measuring Boolean Function Nonlinearity by Walsh Transform. .
Cryptography FAQ.