Пример #1
0
        public static BitString16 forwardPermutation(BitString16 bitString)
        {
            String input  = bitString.BitString;
            String output = "";


            output += input[1 - 1]; //1st bit
            output += input[5 - 1]; //2nd bit
            output += input[9 - 1];
            output += input[13 - 1];
            output += input[2 - 1];
            output += input[6 - 1];
            output += input[10 - 1];
            output += input[14 - 1];
            output += input[3 - 1];
            output += input[7 - 1];
            output += input[11 - 1];
            output += input[15 - 1];
            output += input[4 - 1];
            output += input[8 - 1];
            output += input[12 - 1];
            output += input[16 - 1];

            return(new BitString16(output));
        }
Пример #2
0
        //Decrypt a ciphertext using a key and the 4 round SPN
        public static BitString16 Decrypt(BitString16 ciphertext, Key key)
        {
            SBox sbox = new SBox();

            //Pre
            BitString16 first_subkey = key.getDecryptionSubKey(1);
            BitString16 plaintext    = Util.xor(ciphertext, first_subkey);

            //Round 1
            BitString16 second_subkey = key.getDecryptionSubKey(2);

            plaintext = sbox.backwardsTransform(plaintext);
            plaintext = Util.xor(plaintext, second_subkey);

            //Rounds 2-4
            for (int round = 2; round < 5; ++round)
            {
                BitString16 subkey = key.getDecryptionSubKey(round + 1);
                plaintext = Permutation.backwardsPermutation(plaintext);
                plaintext = sbox.backwardsTransform(plaintext);
                plaintext = Util.xor(plaintext, subkey);
            }

            return(plaintext);
        }
Пример #3
0
        //Encrypt a message under a key using the 4 round SPN
        public static BitString16 Encrypt(BitString16 message, Key key)
        {
            SBox sbox = new SBox();

            //Rounds 1-3
            for (int round = 1; round < 4; ++round)
            {
                BitString16 subkey = key.getEncryptionSubKey(round);
                message = Util.xor(message, subkey);
                message = sbox.forwardTransform(message);
                message = Permutation.forwardPermutation(message);
            }

            //Round 4
            BitString16 subkey_4 = key.getEncryptionSubKey(4);

            message = Util.xor(message, subkey_4);
            message = sbox.forwardTransform(message);

            //Post
            BitString16 last_subkey = key.getEncryptionSubKey(5);

            message = Util.xor(message, last_subkey);

            return(message);
        }
Пример #4
0
        static void Main(string[] args)
        {
            Random rand = new Random(); //Random number generator which will be used to randomize the key

            /*
             * Generate the round keys. For this SPN the keys bits are random and independent.
             * However, we fix K5 such that [K(5,5)...K(5,8) , K(5,13)...K(5,16)] = [3,1]
             */
            List <BitString16> keys = new List <BitString16>(); //Temporary storage container for the keys

            keys.Add(new BitString16(rand));                    //Round 1 key (random)
            keys.Add(new BitString16(rand));                    //Round 2 key (random)
            keys.Add(new BitString16(rand));                    //Round 3 key (random)
            keys.Add(new BitString16(rand));                    //Round 4 key (random)
            keys.Add(new BitString16("0000001100000001"));      //Round 5 key (fixed)
            Key key = new Key(keys);

            //Create an instance of SBox which will be used by the SPN
            SBox sbox = new SBox();

            Dictionary <String, String> plain_cipher_pairs = new Dictionary <string, string>(); //Plaintext/Ciphertext pairs
            StreamWriter writer = new StreamWriter("pairs.txt");                                //Text writer

            //Generate 10,000 Plaintext/Ciphertext pairs
            while (plain_cipher_pairs.Keys.Count < 10000)
            {
                BitString16 message = new BitString16(rand); //Generate a random message to encrypt

                //Check if we have already encrypted this plaintext. If so, skip this iteration of the loop
                //Without this check we may end up with duplicate plain/ciphertext pairs
                if (plain_cipher_pairs.ContainsKey(message.BitString))
                {
                    continue;
                }

                //Encrypt the message via the four round SPN
                BitString16 encrypt_message = FourRoundSPN.Encrypt(message, key);

                //Extract the plaintext/ciphertext strings from the objects
                String plaintext  = message.BitString;
                String ciphertext = encrypt_message.BitString;

                //Write the pair to the textfile and store in the dictionary for further processing
                writer.WriteLine("{0},{1}", plaintext, ciphertext);
                plain_cipher_pairs.Add(plaintext, ciphertext);
            }
            writer.Close();

            //Using only the plaintext/ciphertext pairs, perform linear cryptanalysis
            BitString16 r5BitString = LinearCryptanalysis.PerformLinearCryptanalysis(plain_cipher_pairs);
            String      r5Key       = r5BitString.BitString;

            String subkey1 = r5Key.Substring(4, 4);
            String subkey2 = r5Key.Substring(12, 4);

            System.Console.WriteLine("RESULT OF LINEAR CRYPTANALYSIS:\nK[5,5]-K[5,8] = {0}\nK[5,13]-K[5,16] = {1}", subkey1, subkey2);
        }
Пример #5
0
        static void Main(string[] args)
        {
            Random rand = new Random(); //Random number generator which will be used to randomize the key

            /*
            * Generate the round keys. For this SPN the keys bits are random and independent.
            * However, we fix K5 such that [K(5,5)...K(5,8) , K(5,13)...K(5,16)] = [3,1]
            */
            List<BitString16> keys = new List<BitString16>(); //Temporary storage container for the keys
            keys.Add(new BitString16(rand)); //Round 1 key (random)
            keys.Add(new BitString16(rand)); //Round 2 key (random)
            keys.Add(new BitString16(rand)); //Round 3 key (random)
            keys.Add(new BitString16(rand)); //Round 4 key (random)
            keys.Add(new BitString16("0000001100000001")); //Round 5 key (fixed)
            Key key = new Key(keys);

            //Create an instance of SBox which will be used by the SPN
            SBox sbox = new SBox();

            Dictionary<String, String> plain_cipher_pairs = new Dictionary<string, string>();   //Plaintext/Ciphertext pairs
            StreamWriter writer = new StreamWriter("pairs.txt");                               //Text writer

            //Generate 10,000 Plaintext/Ciphertext pairs
            while (plain_cipher_pairs.Keys.Count < 10000)
            {
                BitString16 message = new BitString16(rand); //Generate a random message to encrypt

                //Check if we have already encrypted this plaintext. If so, skip this iteration of the loop
                //Without this check we may end up with duplicate plain/ciphertext pairs
                if (plain_cipher_pairs.ContainsKey(message.BitString))
                    continue;

                //Encrypt the message via the four round SPN
                BitString16 encrypt_message = FourRoundSPN.Encrypt(message, key);

                //Extract the plaintext/ciphertext strings from the objects
                String plaintext = message.BitString;
                String ciphertext = encrypt_message.BitString;

                //Write the pair to the textfile and store in the dictionary for further processing
                writer.WriteLine("{0},{1}", plaintext, ciphertext);
                plain_cipher_pairs.Add(plaintext, ciphertext);

            }
            writer.Close();

            //Using only the plaintext/ciphertext pairs, perform linear cryptanalysis
            BitString16 r5BitString = LinearCryptanalysis.PerformLinearCryptanalysis(plain_cipher_pairs);
            String r5Key = r5BitString.BitString;

            String subkey1 = r5Key.Substring(4, 4);
            String subkey2 = r5Key.Substring(12, 4);

            System.Console.WriteLine("RESULT OF LINEAR CRYPTANALYSIS:\nK[5,5]-K[5,8] = {0}\nK[5,13]-K[5,16] = {1}", subkey1, subkey2);
        }
Пример #6
0
        static BitString16 partial_decrypt(BitString16 ciphertext, BitString16 key)
        {
            SBox sbox = new SBox();

            //Pre
            BitString16 plaintext = Util.xor(ciphertext, key);

            //Round 1
            plaintext = sbox.backwardsTransform(plaintext);

            return plaintext;
        }
Пример #7
0
        public BitString16 forwardTransform(BitString16 bitString)
        {
            String input  = bitString.BitString;
            String output = "";

            for (int i = 0; i < 4; ++i)
            {
                String subBlock = input.Substring(i * 4, 4);
                output += sBoxMapping[subBlock];
            }
            return(new BitString16(output));
        }
        static BitString16 partial_decrypt(BitString16 ciphertext, BitString16 key)
        {
            SBox sbox = new SBox();

            //Pre
            BitString16 plaintext = Util.xor(ciphertext, key);

            //Round 1
            plaintext = sbox.backwardsTransform(plaintext);

            return(plaintext);
        }
Пример #9
0
        public BitString16 forwardTransform(BitString16 bitString)
        {
            String input = bitString.BitString;
            String output = "";

            for (int i = 0; i < 4; ++i)
            {
                String subBlock = input.Substring(i * 4, 4);
                output += sBoxMapping[subBlock];

            }
            return new BitString16(output);
        }
Пример #10
0
        public BitString16 backwardsTransform(BitString16 bitString)
        {
            String input  = bitString.BitString;
            String output = "";

            for (int i = 0; i < 4; ++i)
            {
                String subBlock = input.Substring(i * 4, 4);
                output += sBoxMapping.First(x => x.Value.Equals(subBlock)).Key;
            }

            return(new BitString16(output));
        }
Пример #11
0
        public BitString16 backwardsTransform(BitString16 bitString)
        {
            String input = bitString.BitString;
            String output = "";

            for (int i = 0; i < 4; ++i)
            {
                String subBlock = input.Substring(i * 4, 4);
                output += sBoxMapping.First(x => x.Value.Equals(subBlock)).Key;

            }

            return new BitString16(output);
        }
        static bool testPartialKey(BitString16 plaintext, BitString16 partialPlaintext)
        {
            String p = plaintext.BitString;
            String u = partialPlaintext.BitString;

            //Implementation of formula 5: U[4,6] XOR U[4,8] XOR U[4,14] XOR U[4,16] XOR P[5] XOR P[7] XOR P[8]
            char result = Util.bit_xor(u[5], Util.bit_xor(u[7], Util.bit_xor(u[13], Util.bit_xor(u[15], Util.bit_xor(p[4], Util.bit_xor(p[6], p[7]))))));

            if (result == '0')
            {
                return(true);
            }
            return(false);
        }
Пример #13
0
        public static BitString16 xor(BitString16 bs1, BitString16 bs2)
        {
            String output = "";

            String s1 = bs1.BitString;
            String s2 = bs2.BitString;

            for (int i = 0; i < s1.Length; ++i)
            {
                if (s1[i] != s2[i])
                    output += '1';
                else
                    output += '0';
            }

            return new BitString16(output);
        }
        public static BitString16 PerformLinearCryptanalysis(Dictionary <String, String> plain_cipher_pairs)
        {
            //Get the list of 256 possible subkeys
            List <BitString16> partialSubKeys = generateAllPartialSubkeys();

            double highestBias = 0;  //Keep track of the highest bias
            String subkey      = ""; //Keep track of the subkey with the highest bias


            //Iterate through each possible subkey and check which has the highest bias, this is the actual subkey.
            foreach (BitString16 partialSubKey in partialSubKeys)
            {
                int count = 0;

                foreach (var x in plain_cipher_pairs)
                {
                    BitString16 plaintext         = new BitString16(x.Key);
                    BitString16 ciphertext        = new BitString16(x.Value);
                    BitString16 partial_decrypted = partial_decrypt(ciphertext, partialSubKey);

                    //Check if the partially decrypted ciphertext satisfies equation 5
                    if (testPartialKey(plaintext, partial_decrypted))
                    {
                        count++;
                    }
                }
                double bias    = Math.Abs(count - 5000.0) / 10000.0; //Get this key's bias
                String _subkey = partialSubKey.BitString;            //Get this subkey

                System.Console.WriteLine("KEY: {1}, BIAS: {0}", bias, _subkey);

                //If this key has the highest bias so far, store it
                if (bias > highestBias)
                {
                    highestBias = bias;
                    subkey      = _subkey;
                }
            }

            //Return the best subkey we found
            return(new BitString16(subkey));
        }
Пример #15
0
        public static BitString16 xor(BitString16 bs1, BitString16 bs2)
        {
            String output = "";

            String s1 = bs1.BitString;
            String s2 = bs2.BitString;

            for (int i = 0; i < s1.Length; ++i)
            {
                if (s1[i] != s2[i])
                {
                    output += '1';
                }
                else
                {
                    output += '0';
                }
            }

            return(new BitString16(output));
        }
Пример #16
0
        public static BitString16 PerformLinearCryptanalysis(Dictionary<String, String> plain_cipher_pairs)
        {
            //Get the list of 256 possible subkeys
            List<BitString16> partialSubKeys = generateAllPartialSubkeys();

            double highestBias = 0; //Keep track of the highest bias
            String subkey = "";     //Keep track of the subkey with the highest bias

            //Iterate through each possible subkey and check which has the highest bias, this is the actual subkey.
            foreach (BitString16 partialSubKey in partialSubKeys)
            {
                int count = 0;

                foreach (var x in plain_cipher_pairs)
                {
                    BitString16 plaintext = new BitString16(x.Key);
                    BitString16 ciphertext = new BitString16(x.Value);
                    BitString16 partial_decrypted = partial_decrypt(ciphertext, partialSubKey);

                    //Check if the partially decrypted ciphertext satisfies equation 5
                    if (testPartialKey(plaintext, partial_decrypted))
                        count++;
                }
                double bias = Math.Abs(count - 5000.0) / 10000.0;   //Get this key's bias
                String _subkey = partialSubKey.BitString;      //Get this subkey

                System.Console.WriteLine("KEY: {1}, BIAS: {0}", bias, _subkey);

                //If this key has the highest bias so far, store it
                if (bias > highestBias)
                {
                    highestBias = bias;
                    subkey = _subkey;
                }
            }

            //Return the best subkey we found
            return new BitString16(subkey);
        }
Пример #17
0
        //Encrypt a message under a key using the 4 round SPN
        public static BitString16 Encrypt(BitString16 message, Key key)
        {
            SBox sbox = new SBox();

            //Rounds 1-3
            for (int round = 1; round < 4; ++round)
            {
                BitString16 subkey = key.getEncryptionSubKey(round);
                message = Util.xor(message, subkey);
                message = sbox.forwardTransform(message);
                message = Permutation.forwardPermutation(message);
            }

            //Round 4
            BitString16 subkey_4 = key.getEncryptionSubKey(4);
            message = Util.xor(message, subkey_4);
            message = sbox.forwardTransform(message);

            //Post
            BitString16 last_subkey = key.getEncryptionSubKey(5);
            message = Util.xor(message, last_subkey);

            return message;
        }
Пример #18
0
        //Decrypt a ciphertext using a key and the 4 round SPN
        public static BitString16 Decrypt(BitString16 ciphertext, Key key)
        {
            SBox sbox = new SBox();

            //Pre
            BitString16 first_subkey = key.getDecryptionSubKey(1);
            BitString16 plaintext = Util.xor(ciphertext, first_subkey);

            //Round 1
            BitString16 second_subkey = key.getDecryptionSubKey(2);
            plaintext = sbox.backwardsTransform(plaintext);
            plaintext = Util.xor(plaintext, second_subkey);

            //Rounds 2-4
            for (int round = 2; round < 5; ++round)
            {
                BitString16 subkey = key.getDecryptionSubKey(round + 1);
                plaintext = Permutation.backwardsPermutation(plaintext);
                plaintext = sbox.backwardsTransform(plaintext);
                plaintext = Util.xor(plaintext, subkey);
            }

            return plaintext;
        }
Пример #19
0
        static bool testPartialKey(BitString16 plaintext, BitString16 partialPlaintext)
        {
            String p = plaintext.BitString;
            String u = partialPlaintext.BitString;

            //Implementation of formula 5: U[4,6] XOR U[4,8] XOR U[4,14] XOR U[4,16] XOR P[5] XOR P[7] XOR P[8]
            char result = Util.bit_xor(u[5], Util.bit_xor(u[7], Util.bit_xor(u[13], Util.bit_xor(u[15], Util.bit_xor(p[4], Util.bit_xor(p[6], p[7]))))));
            if (result == '0')
                return true;
            return false;
        }