0% found this document useful (0 votes)
113 views

Data Encryption Standard

The document provides a detailed explanation of the Data Encryption Standard (DES) algorithm, which was adopted by the U.S. government in 1977. It describes the key components of DES including: 1) The key schedule which generates subkeys from the original key through permutations and shifts. 2) The encryption process which applies the subkeys to blocks of plaintext using substitution boxes and permutations to produce ciphertext blocks. 3) The decryption process which is similar but applies the subkeys in reverse order. It also discusses padding, modes of operation like electronic codebook (ECB) and cipher block chaining (CBC), and using DES to generate checksums. An implementation of DES in C is provided

Uploaded by

Hotland Sitorus
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
113 views

Data Encryption Standard

The document provides a detailed explanation of the Data Encryption Standard (DES) algorithm, which was adopted by the U.S. government in 1977. It describes the key components of DES including: 1) The key schedule which generates subkeys from the original key through permutations and shifts. 2) The encryption process which applies the subkeys to blocks of plaintext using substitution boxes and permutations to produce ciphertext blocks. 3) The decryption process which is similar but applies the subkeys in reverse order. It also discusses padding, modes of operation like electronic codebook (ECB) and cipher block chaining (CBC), and using DES to generate checksums. An implementation of DES in C is provided

Uploaded by

Hotland Sitorus
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 15

Data Encryption Standard(DES) Algorithm Explained

Encryption has become a part and parcel of our lives and we have accepted the fact that data
is going to encrypted and decrypted at various stages. However, there is not a single
encryption algorithm followed everywhere. There are a number of algorithms existing, and I
feel there is a need to understand how they work. So this text explains a number of popular
encryption algorithms and makes you look at them as mathematical formulas.

Data Encryption Standard or DES


The U.S government in 1977 adopted the Data Encryption Standard (DES) algorithm.
According to its developer the DES algorithm is:
It is a block cipher system which transforms 64-bit data blocks under a 56-bit secret key
under a 56-bit secret key, by means of permutation and substitution.
Now, this tutorial will guide you through the various steps of the DES encryption algorithm
making you more confident in dealing with DES encryption.
The following is a step by step guide to the DES algorithm, which was originally written by
Matthew Fischer and has been edited by me-:
1.) Firstly, we need to process the key.
1.1 Get a 64-bit key from the user. (Every 8th bit is considered a parity bit. For a key to have
correct parity, each byte should contain an odd number of "1" bits.)
1.2 Calculate the key schedule.
1.2.1 Perform the following permutation on the 64-bit key. (The parity bits are discarded,
reducing the key to 56 bits. Bit 1 of the permuted block is bit 57 of the original key, bit 2 is
bit 49, and so on with bit
56 being bit 4 of the original key.)
Permuted Choice 1 (PC-1)
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
1.2.2 Split the permuted key into two halves. The first 28 bits are called C[0] and the last 28
bits are called D[0].
1.2.3 Calculate the 16 subkeys. Start with i = 1.
1.2.3.1 Perform one or two circular left shifts on both C[i-1] and D[i-1] to get C[i] and D[i],
respectively. The number of shifts per iteration are given in the table below.
Iteration # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Left Shifts 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1
1.2.3.2 Permute the concatenation C[i]D[i] as indicated below. This will yield K[i], which is
48 bits long.
Permuted Choice 2 (PC-2)
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
1.2.3.3 Loop back to 1.2.3.1 until K[16] has been calculated.
2 Process a 64-bit data block.
2.1 Get a 64-bit data block. If the block is shorter than 64 bits, it should be padded as
appropriate for the application.
2.2 Perform the following permutation on the data block.
Initial Permutation (IP)
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
2.3 Split the block into two halves. The first 32 bits are called L[0], and the last 32 bits are
called R[0].
2.4 Apply the 16 subkeys to the data block. Start with i = 1.
2.4.1 Expand the 32-bit R[i-1] into 48 bits according to the bit-selection function below.
Expansion (E)
32 1 2 3 4 5
456789
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
2.4.2 Exclusive-or E(R[i-1]) with K[i].
2.4.3 Break E(R[i-1]) xor K[i] into eight 6-bit blocks. Bits 1-6 are B[1], bits 7-12 are B[2],
and so on with bits 43-48 being B[8].
2.4.4 Substitute the values found in the S-boxes for all B[j]. Start with j = 1. All values in the
S-boxes should be considered 4 bits wide.
2.4.4.1 Take the 1st and 6th bits of B[j] together as a 2-bit value (call it m) indicating the row
in S[j] to look in for the substitution.
2.4.4.2 Take the 2nd through 5th bits of B[j] together as a 4-bit value (call it n) indicating the
column in S[j] to find the substitution.
2.4.4.3 Replace B[j] with S[j][m][n].
Substitution Box 1 (S[1])
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
S[2]
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
S[3]
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
S[4]
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
S[5]
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
S[6]
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
S[7]
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
S[8]
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
2.4.4.4 Loop back to 2.4.4.1 until all 8 blocks have been replaced.
2.4.5 Permute the concatenation of B[1] through B[8] as indicated below.
Permutation P
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
2.4.6 Exclusive-or the resulting value with L[i-1]. Thus, all together, your R[i] = L[i-1] xor
P(S[1](B[1])...S[8](B[8])), where B[j] is a 6-bit block of E(R[i-1]) xor K[i]. (The function for
R[i] is written as, R[i] = L[i-1] xor f(R[i-1], K[i]).)
2.4.7 L[i] = R[i-1].
2.4.8 Loop back to 2.4.1 until K[16] has been applied.
2.5 Perform the following permutation on the block R[16]L[16].
Final Permutation (IP**-1)
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
This has been a description of how to use the DES algorithm to encrypt one 64-bit block. To
decrypt, use the same process, but just use the keys K[i] in reverse order. That is, instead of
applying K[1] for the first iteration, apply K[16], and then K[15] for the second, on down to
K[1].

Summaries:
Key schedule:
C[0]D[0] = PC1(key)
for 1 <= i <= 16
C[i] = LS[i](C[i-1])
D[i] = LS[i](D[i-1])
K[i] = PC2(C[i]D[i])
Encipherment:
L[0]R[0] = IP(plain block)
for 1 <= i <= 16
L[i] = R[i-1]
R[i] = L[i-1] xor f(R[i-1], K[i])
cipher block = FP(R[16]L[16])
Decipherment:
R[16]L[16] = IP(cipher block)
for 1 <= i <= 16
R[i-1] = L[i]
L[i-1] = R[i] xor f(L[i], K[i])
plain block = FP(L[0]R[0])

To encrypt or decrypt more than 64 bits there are four official modes (defined in FIPS PUB
81). One is to go through the above-described process for each block in succession. This is
called Electronic Codebook (ECB) mode. A stronger method is to exclusive-or each plaintext
block with the preceding ciphertext block prior to encryption. (The first block is exclusive-
or'ed with a secret 64-bit initialization vector (IV).) This is called Cipher Block Chaining
(CBC) mode. The other two modes are Output Feedback (OFB) and Cipher Feedback (CFB).

When it comes to padding the data block, there are several options. One is to simply append
zeros. Two suggested by FIPS PUB 81 are, if the data is binary data, fill up the block with
bits that are the opposite of the last bit of data, or, if the data is ASCII data, fill up the block
with random bytes and put the ASCII character for the number of pad bytes in the last byte of
the block. Another technique is to pad the block with random bytes and in the last 3 bits store
the original number of data bytes.

The DES algorithm can also be used to calculate checksums up to 64 bits long (see FIPS
PUB 113). If the number of data bits to be check summed is not a multiple of 64, the last data
block should be padded with zeros. If the data is ASCII data, the first bit of each byte should
be set to 0. The data is then encrypted in CBC mode with IV = 0. The leftmost n bits (where
16 <= n <= 64, and n is a multiple of 8) of the final ciphertext block are an n-bit checksum.

Wow, that was one heck of a paper on DES. That would be all you need to implement DES.
Well, if you still have not understood how the DES algorithm is implemented, then I suggest
you go through the following C program:
#include <stdio.h>
static int keyout[17][48];
void des_init(),lshift(),cypher(),des_encrypt(),des_descrypt();
void des_init(unsigned char *key){
unsigned char c[28],d[28];
static int pc1[56] = {57,49,41,33,25,17,9,
01,58,50,42,34,26,18,
10,02,59,51,43,35,27,
19,11,03,60,52,44,36,
63,55,47,39,31,23,15,
07,62,54,46,38,30,22,
14,06,61,53,45,37,29,
21,13,05,28,20,12,04};
static int pc2[48] = {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};
static int nls[17] = {
0,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
static int cd[56],keyb[64];
static int cnt,n=0;
register int i,j;
for(i=0;i<8;i++) /*Read in key*/
for(j=0;j<8;j++) keyb[n++]=(key[i]>>j&0x01);
for(i=0;i<56;i++) /*Permuted choice 1*/
cd[i]=keyb[pc1[1]-1];
for(i=0;i<28;i++){
c[i]=cd[i];
d[i]=cd[i+28];
}
for(cnt=1;cnt<=16;cnt++){
for(i=0;i<nls[cnt];i++){
lshift(c); lshift(d);
}
for(i=0;i<28;i++){
cd[i]=c[i];
cd[i+28]=d[i];
}
for(i=0;i<48;i++) /*Permuted Choice 2*/
keyout[cnt][i]=cd[pc2[i]-1];
}
}
static void lshift(unsigned char shft[]){
register int temp,i;
temp=shft[0];
for(i=0;i<27;i++) shft[i]=shft[i+1];
shft[27]=temp;
}
static void cypher(int *r, int cnt, int *fout){
static int expand[48],b[8][6],sout[8],pin[48];
register int i,j;
static int n,row,col,scnt;
static int p[32]={
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};
static int e[48] = {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};
static char s[8][64] = {
14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7, /*s1*/
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, /*s2*/
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, /*s3*/
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,/*s4*/
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,/*s5*/
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, /*s6*/
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,/*s7*/
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, /*s8*/
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
};
for(i=0;i<48;i++) expand[i]=r[e[i]-1]; /*Expansion Function*/
for(i=n=0;i<8;i++) {
for(j=0;j<6;j++,n++) b[i][j]=expand[n]^keyout[cnt][n];
}
/*Selection functions*/
for(scnt=n=0;scnt<8;scnt++){
row=(b[scnt][0]<<1)+b[scnt][5];
col=(b[scnt][1]<<3)+(b[scnt][2]<<2)+(b[scnt][3]<<1)+b[scnt][4];
sout[scnt]=s[scnt][(row<<4)+col];
for(i=3;i>=0;i--){
pin[n]=sout[scnt]>>i;
sout[scnt]=sout[scnt]-(pin[n++]<<i);
}
}
for(i=0;i<32;i++) fout[i]=pin[p[i]-1]; /*Permutation Function*/
}
static int p[64] = {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,
5 = {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};
static int invp[64]={
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};
void des_encrypt(unsigned char *input){
static unsigned char out[64];
static int inputb[64],lr[64],l[32],r[32];
static int fn[32];
static int cnt,n;
register int i,j;
for(i=n=0;i<8;i++)
for(j=0;j<8;j++) inputb[n++]=(input[i]>>j&0x01);
for(i=0;i<64;i++){ /*Initial Permutation*/
lr[i]=inputb[p[i]-1];
if(i<32) l[i]=lr[i];
else r[i-32]=lr[i];
}
for(cnt=1;cnt<=16;cnt++){ /*Main encryption loop*/
cypher(r,cnt,fn);
for(i=0;i<32;i++){
j=r[i];
r[i]=l[i]^fn[i];
l[i]=j;
}
}
for(i=0;i<32;i++){
lr[i]=r[i];
lr[i+32]=l[i];
}
for(i=0;i<64;i++) out[i]=lr[invp[i]-1]; /*Inverse IP*/
for(i=1;i<=8;i++)
for(j=1;j<=8;j++) input[i-1]=(input[i-1]<<1)|out[i*8-j];
}
void des_decrypt(unsigned char *input){
static unsigned char out[64];
static int inputb[64],lr[64],l[32],r[32];
static int fn[32];
static int cnt,rtemp,n;
register int i,j;
for(i=n=0;i<8;i++)
for(j=0;j<8;j++) inputb[n++]=(input[i]>>j&0x01);
for(i=0;i<64;i++){ /*Initial Permutation*/
lr[i]=inputb[p[i]-1];
if(i<32) l[i]=lr[i];
else r[i-32]=lr[i];
}
for(cnt=16;cnt>0;cnt--){ /*Main decryption loop*/
cypher(r,cnt,fn);
for(i=0;i<32;i++){
rtemp=r[i];
if(l[i]==1 && fn[i]==1) r[i]=0;
else r[i]=(l[i] || fn[i]);
l[i]=rtemp;
}
}
for(i=0;i<32;i++){
lr[i]=r[i];
lr[i+32]=l[i];
}
for(i=0;i<64;i++) out[i]=lr[invp[i]-1]; /*Inverse IP*/
for(i=1;i<=8;i++)
for(j=1;j<=8;j++) input[i-1]=(input[i-1]<<1) | out[i*8-j];
}
int main(int argc, char *argv[]){
unsigned char *key;
unsigned char data[8];
int n;
FILE *in;
FILE *out;
if (argc!=4) {
printf("\r\nUsage: des [e][d] <source file> <destination file>\r\n");
return 1;
}
key=(unsigned char*)getpass("Enter Key:");
des_init(key);
if((in=fopen(argv[2],"rb"))==NULL){
fprintf(stderr,"\r\nCould not open input file: %s",argv[2]);
return 2;
}
if((out=fopen(argv[3],"wb"))==NULL){
fprintf(stderr,"\r\nCould not open output file: %s",argv[3]);
return 3;
}
if(argv[1][0]=='e'){
while ((n=fread(data,1,8,in)) >0){
des_encrypt(data);
printf("data enctyted");
if(fwrite(data,1,8,out) < 8){
fprintf(stderr,"\r\nError writing to output file\r\n");
return(3);
}
}
}
if(argv[1][0]=='d'){
while ((n=fread(data,1,8,in)) >0){
des_decrypt(data);
if(fwrite(data,1,8,out) < 8){
fprintf(stderr,"\r\nError writing to output file\r\n");
return(3);
}
}
}
fclose(in); fclose(out);
return 0;
}ntf(stderr,"\r\nError writing to output file\r\n");
return(3);
}
}
}
fclose(in); fclose(out);
return 0;
}
[Sources: Ankit Fadias Algorithms Explained]

You might also like