Cryptography - Data Encryption Standard (DES)

Hello everyone. In this article, I will be discussing about first Symmetric Key Cryptography - Data Encryption Standard (DES) in detail. DES was developed by IBM in the 1970s and later standardized in public by the NSA in 1977. It is a block cipher. It encrypts the data in the blocks of size of 64 bits each. DES uses heavily bit operations. It uses a key of 56 bit length. The same algorithm and the key is used for decryption process.

Actually, the original key is of 64 bit length. For parity checking purposes, every 8th bit is discarded from the original key, making it a key of 56 bit length. Now, what I have done here is that I took ASCII value of each character from the plain text and the key and converted to the binary digits of 8 bit length. Now, this is what happens that the total length of the plain text and the key may not be an exact multiple of 64. Thus, I appended zeroes at the end of the plain text and the key in such a way that they become a multiple of 64. One important thing to note is that the key size cannot be greater than 8 characters. As each character represents 8 bits and the size of key cannot be greater than 64 bits, hence the key size cannot be more than 8 characters.

Now, divide the plain text in the blocks of 64 bits. Take each block, one by one. Start encrypting them with DES. DES involves the steps, given below.

studio

Note

All these values are the standard values and are publicly available to everyone.

  1. Initial Permutation

    As the name suggests, it rearranges the first plain text block bits according to IP table. The first bit of the permuted text block will be the 58th bit of the first plain text block, the second bit will be the 50th bit of the first plain text block and so on. Now, divide the permuted text into two halves - 32 bit Left Plain Text (LPT) and 32 bit Right Plain Text (RPT).
    studio
  2. 16 Rounds

    1. Key Transformation

      Divide the 56 bit Key into two halves - C Key (28 bit) and D Key (28 bit). Perform Left Circular Shift to C Key and D Key, according to the Circular Left Shift Table.



      After the shift, join C Key and D Key again to make Shifted Key of 56 bit.

    2. Compression Permutation

      This step involves the selection of 48 bits out of 56 bits of the shifted key. In other words, shifted key is compressed and permuted at the same time. It is done according to the Compression Permutation table.

      For example, the first bit of Compressed Key will be the 14th bit of the shifted key and so on.
      Rounds
    3. Expansion Permutation

      Recall that after initial Permutation, we had LPT and RPT, each of 32 bit length. During this step, RPT is expanded from 32 bit to 48 bit.

      Besides this, it is permuted as well. Hence, the Expansion Permutation. At first, 32 bit RPT is divided into 8 blocks of 4 bits each. Then each 4 bit block is expanded to 6 bit block by adding two more bits.

      One bit at the beginning of the 4 bit block and the other bit at the end of that 4 bit block.

      Rounds
      This is how it is done. For simplicity of the computation, this process has been stored in the Expansion Permutation table. After this step, RPT has 8 blocks of 6 bits each, making it a 48 bit Expanded RPT.

      Rounds
    4. XOR

      This step involves the bitwise XOR operation between the Expanded RPT of 48 bit length and the compressed key of 48 bit length. This results in the XORed RPT of 48 bit length. 

    5. S Box Substitution

      The XORed RPT is fed into the S Box Substitution step. Here, the XORed RPT is again divided into 8 blocks of 6 bits each. For each block, there is a separate S Box table which gives 4 bit output. Hence, there are 8 S Box tables corresponding to 8 blocks. For example, Block 1 will be fed to S Box 1, Block 2 to S Box 2 and so on. S Box tables consist of 4 rows and 16 columns. Each row contains 0 to 15 numbers in haphazard manner. These 0 to 15 numbers can be represented with 4 bits. As we know, each block contains 6 bits, these 6 bits tell us the row number and the column number of the S Box table corresponding to that block. The 1st bit and the 6th bit determines the row number whereas 2nd, 3rd, 4th and 5th bits determine the column number. The value that is obtained at the intersection of the row number and the column number is the 4 bit output of the S Box table. Thus, each of the 8 blocks gives 4 bit output, giving rise to 32 bit S Box RPT.

      Rounds

      Rounds
      Rounds
      Rounds
      Rounds
      Rounds
      Rounds
      Rounds
      Rounds
      Rounds
    6. P Box Permutation

      In this step, S Box RPT will be permuted according to the P Box table and gives rise to P Box RPT.

      Rounds
    7. XOR and Swap

      During all these operations, the LPT was left untouched so far. In this step, P Box RPT of 32 bit length and the untouched LPT of 32 bit length is XORed. The XORed text is stored in the RPT and the original RPT is stored in the LPT. After this, again the next round starts. Due to this, it is called 16 Rounds.

      Rounds
  3. At the end of the 16 rounds, the final Permutation is done on the combined LPT and RPT and gave rise to 64 bit first Cipher text block. It is done according to the final Permutation table.

    Rounds
    All the previous steps i.e. 1,2 and 3 are performed for all the other plain text blocks to get the corresponding Cipher text blocks. At the very end, all the Cipher text blocks are combined to obtain the final Cipher text.
C# code for BitArray helper class is given below.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6.   
  7. namespace WpfAppCryptography.Helpers  
  8. {  
  9.     public class BitArray  
  10.     {  
  11.         public static int[] ToBits(int decimalnumber, int numberofbits)  
  12.         {  
  13.             int[] bitarray = new int[numberofbits];  
  14.             int k = numberofbits-1;  
  15.             char[] bd = Convert.ToString(decimalnumber, 2).ToCharArray();  
  16.   
  17.             for (int i = bd.Length - 1; i >= 0; --i,--k)  
  18.             {  
  19.                 if (bd[i] == '1')  
  20.                     bitarray[k] = 1;  
  21.                 else  
  22.                     bitarray[k] = 0;  
  23.             }  
  24.   
  25.             while(k >= 0)  
  26.             {  
  27.                 bitarray[k] = 0;  
  28.                 --k;  
  29.             }  
  30.   
  31.             return bitarray;  
  32.         }  
  33.   
  34.         public static int ToDecimal(int[] bitsarray)  
  35.         {  
  36.             string stringvalue = "";  
  37.             for (int i = 0; i < bitsarray.Length; i++)  
  38.             {  
  39.                 stringvalue += bitsarray[i].ToString();  
  40.             }  
  41.             int DecimalValue = Convert.ToInt32(stringvalue, 2);  
  42.   
  43.             return DecimalValue;  
  44.         }  
  45.     }  
  46. }  

 C# code for DES is given below.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using WpfAppCryptography.Helpers;  
  7. using WpfAppCryptography.ViewModel;  
  8.   
  9. namespace WpfAppCryptography.Algorithms.KeyBased.Symmetric  
  10. {  
  11.     public class DES : Algorithm  
  12.     {  
  13.         public new string AlgorithmName = "Data Encryption Standard (DES)";  
  14.   
  15.         //Initial Permutation Table  
  16.         private int[] ip = new int[] { 58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,  
  17.                                        62,54,46,38,30,22,14,6,64,56,48,40,32,24,16,8,  
  18.                                        57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,  
  19.                                        61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7 };  
  20.   
  21.         //Circular Left shift Table (For Encryption)  
  22.         private int[] clst = new int[] { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };  
  23.   
  24.         //Circular Right shift Table (For Decryption)  
  25.         private int[] crst = new int[] { 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1 };  
  26.   
  27.         //Compression Permutation Table  
  28.         private int[] cpt = new int[] { 14,17,11,24,1,5,3,28,15,6,21,10,  
  29.                                         23,19,12,4,26,8,16,7,27,20,13,2,  
  30.                                         41,52,31,37,47,55,30,40,51,45,33,48,  
  31.                                         44,49,39,56,34,53,46,42,50,36,29,32 };  
  32.   
  33.         //Expansion Permutation Table  
  34.         private int[] ept = new int[] { 32,1,2,3,4,5,4,5,6,7,8,9,  
  35.                                         8,9,10,11,12,13,12,13,14,15,16,17,  
  36.                                         16,17,18,19,20,21,20,21,22,23,24,25,  
  37.                                         24,25,26,27,28,29,28,29,30,31,32,1 };  
  38.   
  39.         //S Box Tables ( Actual 2D S Box Tables have been converted to 1D S Box Tables for easier computation )  
  40.         private int[,] sbox = new int[8, 64] { { 14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,  
  41.                                                 0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,  
  42.                                                 4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,  
  43.                                                 15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13 },  
  44.                                               { 15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,  
  45.                                                 3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,  
  46.                                                 0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,  
  47.                                                 13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9 },  
  48.                                               { 10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,  
  49.                                                 13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,  
  50.                                                 13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,  
  51.                                                 1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12 },  
  52.                                               { 7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,  
  53.                                                 13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,  
  54.                                                 10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,  
  55.                                                 3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14 },  
  56.                                               { 2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,  
  57.                                                 14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,  
  58.                                                 4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,  
  59.                                                 11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3 },  
  60.                                               { 12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,  
  61.                                                 10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,  
  62.                                                 9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,  
  63.                                                 4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13 },  
  64.                                               { 4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,  
  65.                                                 13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,  
  66.                                                 1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,  
  67.                                                 6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12 },  
  68.                                               { 13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,  
  69.                                                 1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,  
  70.                                                 7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,  
  71.                                                 2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11 } };  
  72.   
  73.         //P Box Table  
  74.         private int[] pbox = new int[] { 16,7,20,21,29,12,28,17,1,15,23,26,5,18,31,10,  
  75.                                          2,8,24,14,32,27,3,9,19,13,30,6,22,11,4,25 };  
  76.   
  77.         //Final Permutation Table  
  78.         private int[] fp = new int[] { 40,8,48,16,56,24,64,32,39,7,47,15,55,23,63,31,  
  79.                                        38,6,46,14,54,22,62,30,37,5,45,13,53,21,61,29,  
  80.                                        36,4,44,12,52,20,60,28,35,3,43,11,51,19,59,27,  
  81.                                        34,2,42,10,50,18,58,26,33,1,41,9,49,17,57,25 };  
  82.   
  83.         int[] plaintextbin = new int[5000];  
  84.         char[] ptca;  
  85.         int[] ciphertextbin = new int[5000];  
  86.         char[] ctca;  
  87.         int[] keybin = new int[64];  
  88.         char[] kca;  
  89.         int[] ptextbitslice = new int[64];  
  90.         int[] ctextbitslice = new int[64];  
  91.         int[] ippt = new int[64];  
  92.         int[] ipct = new int[64];  
  93.         int[] ptLPT = new int[32];  
  94.         int[] ptRPT = new int[32];  
  95.         int[] ctLPT = new int[32];  
  96.         int[] ctRPT = new int[32];  
  97.         int[] changedkey = new int[56];  
  98.         int[] shiftedkey = new int[56];  
  99.         int[] tempRPT = new int[32];  
  100.         int[] tempLPT = new int[32];  
  101.         int[] CKey = new int[28];  
  102.         int[] DKey = new int[28];  
  103.         int[] compressedkey = new int[48];  
  104.         int[] ctExpandedLPT = new int[48];  
  105.         int[] ptExpandedRPT = new int[48];  
  106.         int[] XoredRPT = new int[48];  
  107.         int[] XoredLPT = new int[48];  
  108.         int[] row = new int[2];  
  109.         int rowindex;  
  110.         int[] column = new int[4];  
  111.         int columnindex;  
  112.         int sboxvalue;  
  113.         int[] tempsboxarray = new int[4];  
  114.         int[] ptSBoxRPT = new int[32];  
  115.         int[] ctSBoxLPT = new int[32];  
  116.         int[] ctPBoxLPT = new int[32];  
  117.         int[] ptPBoxRPT = new int[32];  
  118.         int[] attachedpt = new int[64];  
  119.         int[] attachedct = new int[64];  
  120.         int[] fppt = new int[64];  
  121.         int[] fpct = new int[64];  
  122.   
  123.         private int GetASCII(char ch)  
  124.         {  
  125.             int n = ch;  
  126.             return n;  
  127.         }  
  128.   
  129.         private int ConvertTextToBits(char[] chararray, int[] savedarray)  
  130.         {  
  131.             int j = 0;  
  132.             for (int i = 0; i < chararray.Length; ++i)  
  133.             {  
  134.                 int[] ba = BitArray.ToBits(GetASCII(chararray[i]), 8);  
  135.                 j = i * 8;  
  136.                 AssignArray1ToArray2b(ba, savedarray, j);  
  137.             }  
  138.   
  139.             return (j + 8);  
  140.         }  
  141.   
  142.         private void AssignArray1ToArray2b(int[] array1, int[] array2, int fromIndex)  
  143.         {  
  144.             int x, y;  
  145.             for (x = 0, y = fromIndex; x < array1.Length; ++x, ++y)  
  146.                 array2[y] = array1[x];  
  147.         }  
  148.   
  149.         private int AppendZeroes(int[] appendedarray, int len)  
  150.         {  
  151.             int zeroes;  
  152.             if (len % 64 != 0)  
  153.             {  
  154.                 zeroes = (64 - (len % 64));  
  155.   
  156.                 for (int i = 0; i < zeroes; ++i)  
  157.                     appendedarray[len++] = 0;  
  158.             }  
  159.             return len;  
  160.         }  
  161.   
  162.         private void Discard8thBitsFromKey()  
  163.         {  
  164.             for (int i = 0, j = 0; i < 64; i++)  
  165.             {  
  166.                 if ((i + 1) % 8 == 0)  
  167.                     continue;  
  168.                 changedkey[j++] = keybin[i];  
  169.             }  
  170.         }  
  171.   
  172.         private void AssignChangedKeyToShiftedKey()  
  173.         {  
  174.             for (int i = 0; i < 56; i++)  
  175.             {  
  176.                 shiftedkey[i] = changedkey[i];  
  177.             }  
  178.         }  
  179.   
  180.         private void InitialPermutation(int[] sentarray, int[] savedarray)  
  181.         {  
  182.             int tmp;  
  183.             for (int i = 0; i < 64; i++)  
  184.             {  
  185.                 tmp = ip[i];  
  186.                 savedarray[i] = sentarray[tmp - 1];  
  187.             }  
  188.         }  
  189.   
  190.         private void DivideIntoLPTAndRPT(int[] sentarray, int[] savedLPT, int[] savedRPT)  
  191.         {  
  192.             for (int i = 0, k = 0; i < 32; i++, ++k)  
  193.             {  
  194.                 savedLPT[k] = sentarray[i];  
  195.             }  
  196.   
  197.             for (int i = 32, k = 0; i < 64; i++, ++k)  
  198.             {  
  199.                 savedRPT[k] = sentarray[i];  
  200.             }  
  201.         }  
  202.   
  203.         private void SaveTemporaryHPT(int[] fromHPT, int[] toHPT)  
  204.         {  
  205.             for (int i = 0; i < 32; i++)  
  206.             {  
  207.                 toHPT[i] = fromHPT[i];  
  208.             }  
  209.         }  
  210.   
  211.         private void DivideIntoCKeyAndDKey()  
  212.         {  
  213.             for (int i = 0, j = 0; i < 28; i++, ++j)  
  214.             {  
  215.                 CKey[j] = shiftedkey[i];  
  216.             }  
  217.   
  218.             for (int i = 28, j = 0; i < 56; i++, ++j)  
  219.             {  
  220.                 DKey[j] = shiftedkey[i];  
  221.             }  
  222.         }  
  223.   
  224.         private void CircularLeftShift(int[] HKey)  
  225.         {  
  226.             int i, FirstBit = HKey[0];  
  227.             for (i = 0; i < 27; i++)  
  228.             {  
  229.                 HKey[i] = HKey[i + 1];  
  230.             }  
  231.             HKey[i] = FirstBit;  
  232.         }  
  233.   
  234.         private void AttachCKeyAndDKey()  
  235.         {  
  236.             int j = 0;  
  237.             for (int i = 0; i < 28; i++)  
  238.             {  
  239.                 shiftedkey[j++] = CKey[i];  
  240.             }  
  241.   
  242.             for (int i = 0; i < 28; i++)  
  243.             {  
  244.                 shiftedkey[j++] = DKey[i];  
  245.             }  
  246.         }  
  247.   
  248.         private void CompressionPermutation()  
  249.         {  
  250.             int temp;  
  251.             for (int i = 0; i < 48; i++)  
  252.             {  
  253.                 temp = cpt[i];  
  254.                 compressedkey[i] = shiftedkey[temp - 1];  
  255.             }  
  256.         }  
  257.   
  258.         private void ExpansionPermutation(int[] HPT, int[] ExpandedHPT)  
  259.         {  
  260.             int temp;  
  261.             for (int i = 0; i < 48; i++)  
  262.             {  
  263.                 temp = ept[i];  
  264.                 ExpandedHPT[i] = HPT[temp - 1];  
  265.             }  
  266.         }  
  267.   
  268.         private void XOROperation(int[] array1, int[] array2, int[] array3, int SizeOfTheArray)  
  269.         {  
  270.             for (int i = 0; i < SizeOfTheArray; i++)  
  271.             {  
  272.                 array3[i] = array1[i] ^ array2[i];  
  273.             }  
  274.         }  
  275.   
  276.         private void AssignSBoxHPT(int[] temparray, int[] SBoxHPTArray, int fromIndex)  
  277.         {  
  278.             int j = fromIndex;  
  279.             for (int i = 0; i < 4; i++)  
  280.             {  
  281.                 SBoxHPTArray[j++] = tempsboxarray[i];  
  282.             }  
  283.         }  
  284.   
  285.         private void SBoxSubstituion(int[] XoredHPT, int[] SBoxHPT)  
  286.         {  
  287.             int r, t, j = 0, q = 0;  
  288.             for (int i = 0; i < 48; i += 6)  
  289.             {  
  290.                 row[0] = XoredHPT[i];  
  291.                 row[1] = XoredHPT[i + 5];  
  292.                 rowindex = BitArray.ToDecimal(row);  
  293.   
  294.                 column[0] = XoredHPT[i + 1];  
  295.                 column[1] = XoredHPT[i + 2];  
  296.                 column[2] = XoredHPT[i + 3];  
  297.                 column[3] = XoredHPT[i + 4];  
  298.                 columnindex = BitArray.ToDecimal(column);  
  299.   
  300.                 t = ((16 * (rowindex)) + (columnindex));  
  301.   
  302.                 sboxvalue = sbox[j++, t];  
  303.   
  304.                 tempsboxarray = BitArray.ToBits(sboxvalue, 4);  
  305.   
  306.                 r = q * 4;  
  307.   
  308.                 AssignSBoxHPT(tempsboxarray, SBoxHPT, r);  
  309.   
  310.                 ++q;  
  311.             }  
  312.         }  
  313.   
  314.         private void PBoxPermutation(int[] SBoxHPT, int[] PBoxHPT)  
  315.         {  
  316.             int temp;  
  317.             for (int i = 0; i < 32; i++)  
  318.             {  
  319.                 temp = pbox[i];  
  320.                 PBoxHPT[i] = SBoxHPT[temp - 1];  
  321.             }  
  322.         }  
  323.   
  324.         private void Swap(int[] tempHPT, int[] HPT)  
  325.         {  
  326.             for (int i = 0; i < 32; i++)  
  327.             {  
  328.                 HPT[i] = tempHPT[i];  
  329.             }  
  330.         }  
  331.   
  332.         //Heart of DES  
  333.         private void SixteenRounds()  
  334.         {  
  335.             int n;  
  336.   
  337.             for (int i = 0; i < 16; i++)  
  338.             {  
  339.                 SaveTemporaryHPT(ptRPT, tempRPT);  
  340.   
  341.                 n = clst[i];  
  342.   
  343.                 DivideIntoCKeyAndDKey();  
  344.   
  345.                 for (int j = 0; j < n; j++)  
  346.                 {  
  347.                     CircularLeftShift(CKey);  
  348.                     CircularLeftShift(DKey);  
  349.                 }  
  350.   
  351.                 AttachCKeyAndDKey();  
  352.   
  353.                 CompressionPermutation();  
  354.   
  355.                 ExpansionPermutation(ptRPT, ptExpandedRPT);  
  356.   
  357.                 XOROperation(compressedkey, ptExpandedRPT, XoredRPT, 48);  
  358.   
  359.                 SBoxSubstituion(XoredRPT, ptSBoxRPT);  
  360.   
  361.                 PBoxPermutation(ptSBoxRPT, ptPBoxRPT);  
  362.   
  363.                 XOROperation(ptPBoxRPT, ptLPT, ptRPT, 32);  
  364.   
  365.                 Swap(tempRPT, ptLPT);  
  366.             }  
  367.         }  
  368.   
  369.         private void AttachLPTAndRPT(int[] savedLPT, int[] savedRPT, int[] AttachedPT)  
  370.         {  
  371.             int j = 0;  
  372.             for (int i = 0; i < 32; i++)  
  373.             {  
  374.                 AttachedPT[j++] = savedLPT[i];  
  375.             }  
  376.   
  377.             for (int i = 0; i < 32; i++)  
  378.             {  
  379.                 AttachedPT[j++] = savedRPT[i];  
  380.             }  
  381.         }  
  382.   
  383.         private void FinalPermutation(int[] fromPT, int[] toPT)  
  384.         {  
  385.             int temp;  
  386.             for (int i = 0; i < 64; i++)  
  387.             {  
  388.                 temp = fp[i];  
  389.                 toPT[i] = fromPT[temp - 1];  
  390.             }  
  391.         }  
  392.   
  393.         //DES Components  
  394.         private void StartEncryption()  
  395.         {  
  396.             InitialPermutation(ptextbitslice, ippt);  
  397.   
  398.             DivideIntoLPTAndRPT(ippt, ptLPT, ptRPT);  
  399.   
  400.             AssignChangedKeyToShiftedKey();  
  401.   
  402.             SixteenRounds();  
  403.   
  404.             AttachLPTAndRPT(ptLPT, ptRPT, attachedpt);  
  405.   
  406.             FinalPermutation(attachedpt, fppt);  
  407.         }  
  408.   
  409.         private string ConvertBitsToText(int[] sentarray, int len)  
  410.         {  
  411.             string finaltext = "";  
  412.             int j, k, decimalvalue;  
  413.             int[] tempbitarray = new int[8];  
  414.   
  415.             for (int i = 0; i < len; i += 8)  
  416.             {  
  417.                 for (k = 0, j = i; j < (i + 8); ++k, ++j)  
  418.                 {  
  419.                     tempbitarray[k] = sentarray[j];  
  420.                 }  
  421.   
  422.                 decimalvalue = BitArray.ToDecimal(tempbitarray);  
  423.   
  424.                 if (decimalvalue == 0)  
  425.                     break;  
  426.   
  427.                 finaltext += (char)decimalvalue;  
  428.             }  
  429.   
  430.             return finaltext;  
  431.         }  
  432.   
  433.         public override string Encrypt(string plaintext, string key)  
  434.         {  
  435.             string ciphertext = null;  
  436.   
  437.             ptca = plaintext.ToCharArray();  
  438.             kca = key.ToCharArray();  
  439.             int j, k;  
  440.   
  441.             //Converting plain text characters into binary digits  
  442.             int st = ConvertTextToBits(ptca, plaintextbin);  
  443.   
  444.             int fst = AppendZeroes(plaintextbin, st);  
  445.   
  446.             //Converting key characters into binary digits  
  447.             int sk = ConvertTextToBits(kca, keybin);  
  448.   
  449.             int fsk = AppendZeroes(keybin, sk);  
  450.   
  451.             Discard8thBitsFromKey();  
  452.   
  453.             for (int i = 0; i < fst; i += 64)  
  454.             {  
  455.                 for (k = 0, j = i; j < (i + 64); ++j, ++k)  
  456.                 {  
  457.                     ptextbitslice[k] = plaintextbin[j];  
  458.                 }  
  459.   
  460.                 StartEncryption();  
  461.   
  462.                 for (k = 0, j = i; j < (i + 64); ++j, ++k)  
  463.                 {  
  464.                     ciphertextbin[j] = fppt[k];  
  465.                 }  
  466.             }  
  467.   
  468.             ciphertext = ConvertBitsToText(ciphertextbin, fst);  
  469.   
  470.             return ciphertext;  
  471.         }  
  472.   
  473.         private void CircularRightShift(int[] HKey)  
  474.         {  
  475.             int i, LastBit = HKey[27];  
  476.             for (i = 27; i >= 1; --i)  
  477.             {  
  478.                 HKey[i] = HKey[i - 1];  
  479.             }  
  480.             HKey[i] = LastBit;  
  481.         }  
  482.   
  483.         private void ReversedSixteenRounds()  
  484.         {  
  485.             int n;  
  486.   
  487.             for (int i = 0; i < 16; i++)  
  488.             {  
  489.                 SaveTemporaryHPT(ctLPT, tempLPT);  
  490.   
  491.                 CompressionPermutation();  
  492.   
  493.                 ExpansionPermutation(ctLPT, ctExpandedLPT);  
  494.   
  495.                 XOROperation(compressedkey, ctExpandedLPT, XoredLPT, 48);  
  496.   
  497.                 SBoxSubstituion(XoredLPT, ctSBoxLPT);  
  498.   
  499.                 PBoxPermutation(ctSBoxLPT, ctPBoxLPT);  
  500.   
  501.                 XOROperation(ctPBoxLPT, ctRPT, ctLPT, 32);  
  502.   
  503.                 Swap(tempLPT, ctRPT);  
  504.   
  505.                 n = crst[i];  
  506.   
  507.                 DivideIntoCKeyAndDKey();  
  508.   
  509.                 for (int j = 0; j < n; j++)  
  510.                 {  
  511.                     CircularRightShift(CKey);  
  512.                     CircularRightShift(DKey);  
  513.                 }  
  514.   
  515.                 AttachCKeyAndDKey();  
  516.             }  
  517.         }  
  518.   
  519.         private void StartDecryption()  
  520.         {  
  521.             InitialPermutation(ctextbitslice, ipct);  
  522.   
  523.             DivideIntoLPTAndRPT(ipct, ctLPT, ctRPT);  
  524.   
  525.             AssignChangedKeyToShiftedKey();  
  526.   
  527.             ReversedSixteenRounds();  
  528.   
  529.             AttachLPTAndRPT(ctLPT, ctRPT, attachedct);  
  530.   
  531.             FinalPermutation(attachedct, fpct);  
  532.         }  
  533.   
  534.         public override string Decrypt(string ciphertext, string key)  
  535.         {  
  536.             string plaintext = null;  
  537.   
  538.             ctca = ciphertext.ToCharArray();  
  539.             kca = key.ToCharArray();  
  540.             int j, k;  
  541.   
  542.             //Converting plain text characters into binary digits  
  543.             int st = ConvertTextToBits(ctca, ciphertextbin);  
  544.   
  545.             int fst = AppendZeroes(ciphertextbin, st);  
  546.   
  547.             //Converting key characters into binary digits  
  548.             int sk = ConvertTextToBits(kca, keybin);  
  549.   
  550.             int fsk = AppendZeroes(keybin, sk);  
  551.   
  552.             Discard8thBitsFromKey();  
  553.   
  554.             for (int i = 0; i < fst; i += 64)  
  555.             {  
  556.                 for (k = 0, j = i; j < (i + 64); ++j, ++k)  
  557.                 {  
  558.                     ctextbitslice[k] = ciphertextbin[j];  
  559.                 }  
  560.   
  561.                 StartDecryption();  
  562.   
  563.                 for (k = 0, j = i; j < (i + 64); ++j, ++k)  
  564.                 {  
  565.                     plaintextbin[j] = fpct[k];  
  566.                 }  
  567.             }  
  568.   
  569.             plaintext = ConvertBitsToText(plaintextbin, fst);  
  570.   
  571.             return plaintext;  
  572.         }  
  573.     }  
  574. }  

Here is the theoretical video of DES.

Here is the working video of DES.

In this modern world, people don't use Single DES, as it is vulnerable to heavy attacks. Due to this, they prefer Double DES and Triple DES more. In Double DES, DES is done twice in two different keys.

Rounds

In Triple DES, DES is done thrice. Here, Triple DES can be performed with 3 keys or even 2 keys.

Rounds

Rounds

This is the end of this article. I hope, you found my article useful. Till then, stay tuned and keep coding.

Up Next
    Ebook Download
    View all
    Learn
    View all