📄 des.c
字号:
/*
This is a 'C' implementation of the National Bureau of Statistics
Data Encryption Standard.
All attempts have been made to use standard C facilities to maintain
transportability.
The DES procedure accepts 64-bits of data, 64-bits of key, an
indication of whether the required function is an ENCRYPT or DECRYPT,
and a 52 word work area.
The output from the DES procedure is the data (which is now
ENCRYPTed or DECRYPTed according to the input parameters).
The work area is used for efficiency reasons, and may be used to avoid
recalculating the subkeys if a single key is used repeatedly (as is the
case in MAC processing).
C Language Function Definition :
DES( data, key, encode, work )
unsigned int data[4],
key[4],
encrypt,
work[52];
where the following rules apply :
in: data 64 bits of data to be encrypted or decrypted. The most
significant byte is data[0]; the least significant byte
is data[3].
key 64 bits of encryption key. This routine does not check
the parity of the key before using it; It is the
responsibility of the calling routine to ensure that the
key is in good working order.
encrypt FALSE (zero) - selects a DECRYPT operation
TRUE (non-zero) - selects an ENCRYPT operation
work This area is used to store the sub-keys for the supplied
key. If the same key is being used repeatedly, savings
can be made by eliminating the recalculation of the
sub-keys for each operation by passing the same work
area back to this function, without modifying any of the
work area between calls.
out: data The output of the encryption or decryption process.
The original data is destroyed.
key Unchanged.
encrypt Unchanged.
work Contains the key and the subkeys from the operation
just performed.
NOTE: The work area should be zeroed if there is no need
to use the same key in the next operation (for security
reasons)
*/
/**/
/*
Calling this routine from a C environment :
A sample program is listed below :
*/
#include <stdio.h>
#define TRUE -1
#define FALSE 0
#if 1
unsigned int key[] = { 0x0000, 0x0000, 0x0000, 0x0000 },
data[]= { 0x3131, 0x3131, 0x3131, 0x3131 },
work[52];
#endif
#if 0
unsigned int key[] = { 0x3131, 0x3131, 0x3131, 0x3131 },
data[]= { 0x3131, 0x3131, 0x3131, 0x3131 },
work[52];
#endif
#if 0
unsigned int key[] = { 0x0123, 0x4567, 0x89ab, 0xcdef },
data[]= { 0x4e6f, 0x7720, 0x6973, 0x2074 },
work[52];
#endif
void DES( unsigned int* text, unsigned int* key, unsigned int encrypt, unsigned int* work);
void ROL8(unsigned int* text)
{
unsigned char t;
t=text[0]>>8;
text[0]=text[0]<<8|text[1]>>8;
text[1]=text[1]<<8|text[2]>>8;
text[2]=text[2]<<8|text[3]>>8;
text[3]=text[3]<<8|t;
}
void ROR8(unsigned int* text)
{
unsigned t;
t=(text[3]&0xff)<<8;
text[3]=text[3]>>8|text[2]<<8;
text[2]=text[2]>>8|text[1]<<8;
text[1]=text[1]>>8|text[0]<<8;
text[0]=text[0]>>8|t;
}
void XOR(unsigned int* text1, unsigned int* text2)
{
text1[0]=text1[0]^text2[0];
text1[1]=text1[1]^text2[1];
text1[2]=text1[2]^text2[2];
text1[3]=text1[3]^text2[3];
}
void main (void)
{
int i,j;
char str[50];
unsigned int RandA[] = {0x1212, 0x1212, 0x1212, 0x1212};
unsigned int RandB[] = {0x0000, 0x0000, 0x0000, 0x0000};
printf("Key= %04X%04X%04X%04X\n", key[0], key[1], key[2], key[3]);
printf("Data: ");
gets(str);
if (strlen(str)==16) {
for (i=0; i<4; i++) {
j=3-i;
sscanf(&str[j*4],"%04x",data+j);
str[j*4]='\0';
}
}
#if 0
printf("DES(RANDB) =%04X%04X%04X%04X\n", data[0], data[1], data[2], data[3]);
DES(data, key, FALSE, work);
printf(" RANDB =%04X%04X%04X%04X\n", data[0], data[1], data[2], data[3]);
ROL8(data);
printf("ROL8(RANDB) =%04X%04X%04X%04X\n", data[0], data[1], data[2], data[3]);
printf("RANDA=%04X%04X%04X%04X\n", RandA[0], RandA[1], RandA[2], RandA[3]);
DES(RandA, key, TRUE, work);
printf("block1=%04X%04X%04X%04X\n", RandA[0], RandA[1], RandA[2], RandA[3]);
XOR(data,RandA);
printf("XOR =%04X%04X%04X%04X\n", data[0], data[1], data[2], data[3]);
DES(data, key, FALSE, work);
printf("block2=%04X%04X%04X%04X\n", data[0], data[1], data[2], data[3]);
printf("Challenge=%04X%04X%04X%04X%04X%04X%04X%04X\n",
RandA[0], RandA[1], RandA[2], RandA[3],
data[0], data[1], data[2], data[3]);
printf("Response: ");
gets(str);
if (strlen(str)==16) {
for (i=0; i<4; i++) {
j=3-i;
sscanf(&str[j*4],"%04x",data+j);
str[j*4]='\0';
}
}
DES(data, key, FALSE, work);
printf("DES-1(RESP)=%04X%04X%04X%04X\n", data[0], data[1], data[2], data[3]);
#else
printf( " Plain Text Cipher Text Decipher text \n" );
printf( "---------------- ---------------- ----------------\n" );
printf( "%04X%04X%04X%04X ", data[0], data[1], data[2], data[3] );
DES( data, key, TRUE, work );
printf( "%04X%04X%04X%04X ", data[0], data[1], data[2], data[3] );
DES( data, key, FALSE, work );
DES( data, key, FALSE, work );
printf( "%04X%04X%04X%04X\n", data[0], data[1], data[2], data[3] );
#endif
}
/*
The output should look like
Plain Text Cipher Text Decipher text
---------------- ---------------- ----------------
4E6F772069732074 3FA40E8A984D4815 4E6F772069732074
Calling this function from a non-C environment :
In C, when an array is passed as an argument, the address of the
start of the array is placed on the stack. When an int value is
passed as a parameter, the value of that variable is placed on the
stack.
For this function, there will be three addresses ( for data, key,
and work) and one value ( for encrypt ).
It is necessary to establish exactly how the C compiler used to
compile this function expects to see the parameters on the stack
before being able to call this function from any non-C environment.
*/
/**/
/*
Offsets to tranformation rules
*/
#define IP 0 /* Initial Permutation 64 * 64 */
#define IP_1 65 /* Inverse Initial Permutation 64 * 64 */
#define E 130 /* E Function 32 * 48 */
#define P 179 /* P Function 32 * 32 */
#define PC1A 212 /* Permutation Choice 1 - C0 64 * 28 */
#define PC1B 245 /* Permutation Choice 1 - D0 64 * 28 */
#define PC2 278 /* Permutation Choice 2 56 * 48 */
/*
General defines
*/
#define TRUE -1
#define FALSE 0
typedef unsigned char byte; /* If not defined as standard */
/*
The Microsoft C compiler will only support 8 parameters, so the
tform macro has been split into two separate macros. The net effect
is the same
*/
#define tform1(a,b,c,d,e,f,g,h) a-1, b-1, c-1, d-1, e-1, f-1, g-1, h-1,
#define tform2(a,b,c,d,e,f,g,h) a-1, b-1, c-1, d-1, e-1, f-1, g-1, h-1 | 0x80,
/**/
static byte rules[] = {
/* 0 Initial Permutation 64 * 64 */
tform1( 58, 50, 42, 34, 26, 18, 10, 2)tform2( 60, 52, 44, 36, 28, 20, 12, 4)
tform1( 62, 54, 46, 38, 30, 22, 14, 6)tform2( 64, 56, 48, 40, 32, 24, 16, 8)
tform1( 57, 49, 41, 33, 25, 17, 9, 1)tform2( 59, 51, 43, 35, 27, 19, 11, 3)
tform1( 61, 53, 45, 37, 29, 21, 13, 5)tform2( 63, 55, 47, 39, 31, 23, 15, 7)
0xFF,
/* 65 Inverse Initial Permutation 64 * 64 */
tform1( 40, 8, 48, 16, 56, 24, 64, 32)tform2( 39, 7, 47, 15, 55, 23, 63, 31)
tform1( 38, 6, 46, 14, 54, 22, 62, 30)tform2( 37, 5, 45, 13, 53, 21, 61, 29)
tform1( 36, 4, 44, 12, 52, 20, 60, 28)tform2( 35, 3, 43, 11, 51, 19, 59, 27)
tform1( 34, 2, 42, 10, 50, 18, 58, 26)tform2( 33, 1, 41, 9, 49, 17, 57, 25)
0xFF,
/* 130 E Function 32 * 48 */
tform1( 32, 1, 2, 3, 4, 5, 4, 5)tform2( 6, 7, 8, 9, 8, 9, 10, 11)
tform1( 12, 13, 12, 13, 14, 15, 16, 17)tform2( 16, 17, 18, 19, 20, 21, 20, 21)
tform1( 22, 23, 24, 25, 24, 25, 26, 27)tform2( 28, 29, 28, 29, 30, 31, 32, 1)
0xFF,
/* 179 P Function 32 * 32 */
tform1( 16, 7, 20, 21, 29, 12, 28, 17)tform2( 1, 15, 23, 26, 5, 18, 31, 10)
tform1( 2, 8, 24, 14, 32, 27, 3, 9)tform2( 19, 13, 30, 6, 22, 11, 4, 25)
0xFF,
/* 212 Permutation Choice 1 - C0 64 * 28 */
tform1( 57, 49, 41, 33, 25, 17, 9, 1)tform2( 58, 50, 42, 34, 26, 18, 10, 2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -