private static int[][] subkey = new int[16][]; // [16][48] private static int[] Permute(int[] inputBits, int[] keyBits, bool isDecrypt) { // Initial permutation step takes input bits and permutes into the // newBits array int[] newBits = new int[inputBits.Length]; for (int index = 0; index < inputBits.Length; index++) { newBits[index] = inputBits[IP[index] - 1]; } // 16 rounds will start here // L and R arrays are created to store the Left and Right halves of the // subkey respectively int[] L = new int[32]; int[] R = new int[32]; int i; // Permuted Choice 1 is done here for (i = 0; i < 28; i++) { C[i] = keyBits[PC1[i] - 1]; } for (; i < 56; i++) { D[i - 28] = keyBits[PC1[i] - 1]; } // After PC1 the first L and R are ready to be used and hence looping // can start once L and R are initialized Array.Copy(newBits, 0, L, 0, 32); Array.Copy(newBits, 32, R, 0, 32); Console.Write("\nL0 = "); DisplayBits(L); Console.Write("R0 = "); DisplayBits(R); for (int n = 0; n < 16; n++) { Console.WriteLine("\n-------------"); Console.WriteLine("Round " + (n + 1) + ":"); // newR is the new R half generated by the Fiestel function. If it // is encrpytion then the KS method is called to generate the // subkey otherwise the stored subkeys are used in reverse order // for decryption. int[] newR = new int[0]; if (isDecrypt) { newR = Fiestel(R, subkey[15 - n]); Console.WriteLine("Round key = "); DisplayBits(subkey[15 - n]); } else { newR = Fiestel(R, KS(n, keyBits)); Console.Write("Round key = "); DisplayBits(subkey[n]); } // xor-ing the L and new R gives the new L value. new L is stored // in R and new R is stored in L, thus exchanging R and L for the // next round. int[] newL = XOR(L, newR); L = R; R = newL; Console.Write("L = "); DisplayBits(L); Console.Write("R = "); DisplayBits(R); } // R and L has the two halves of the output before applying the // permutation. This is called the "Preoutput". int[] output = new int[64]; Array.Copy(R, 0, output, 0, 32); Array.Copy(L, 0, output, 32, 32); int[] Output = new int[64]; // Applying FP table to the preoutput, we get the output: // Encryption => output is ciphertext // Decryption => output is plaintext for (i = 0; i < 64; i++) { Output[i] = output[FP[i] - 1]; } // Since the output is stored as an int array of bits, we convert // it into a hex string: string hex = string.Empty; for (i = 0; i < 16; i++) { string bin = string.Empty; for (int j = 0; j < 4; j++) { bin += Output[(4 * i) + j]; } int intValue = Convert.ToInt32(bin, 2); //Integer.parseInt(bin, 2); hex += HexConverter.IntToHex(intValue); // Integer.toHexString(intValue); } if (isDecrypt) { Console.Write("Decrypted text: "); } else { Console.Write("Encrypted text: "); } Console.WriteLine(hex.ToUpper()); return(Output); }