コード例 #1
0
ファイル: MD5.cs プロジェクト: Kamalc/SecurityPackage
        public string GetHash(string text)
        {
            //throw new NotImplementedException();
            MatrixOP m = new MatrixOP();

            return(m.tohexString(m.ComputeMD5(Encoding.ASCII.GetBytes(text))));
        }
コード例 #2
0
ファイル: AES.cs プロジェクト: Kamalc/SecurityPackage
        public override string Encrypt(string plainText, string key)
        {
            MatrixOP mp = new MatrixOP();

            string[,] S_Box = new string[, ]
            {
                { "63", "7c", "77", "7b", "f2", "6b", "6f", "c5", "30", "01", "67", "2b", "fe", "d7", "ab", "76" },
                { "ca", "82", "c9", "7d", "fa", "59", "47", "f0", "ad", "d4", "a2", "af", "9c", "a4", "72", "c0" },
                { "b7", "fd", "93", "26", "36", "3f", "f7", "cc", "34", "a5", "e5", "f1", "71", "d8", "31", "15" },
                { "04", "c7", "23", "c3", "18", "96", "05", "9a", "07", "12", "80", "e2", "eb", "27", "b2", "75" },
                { "09", "83", "2c", "1a", "1b", "6e", "5a", "a0", "52", "3b", "d6", "b3", "29", "e3", "2f", "84" },
                { "53", "d1", "00", "ed", "20", "fc", "b1", "5b", "6a", "cb", "be", "39", "4a", "4c", "58", "cf" },
                { "d0", "ef", "aa", "fb", "43", "4d", "33", "85", "45", "f9", "02", "7f", "50", "3c", "9f", "a8" },
                { "51", "a3", "40", "8f", "92", "9d", "38", "f5", "bc", "b6", "da", "21", "10", "ff", "f3", "d2" },
                { "cd", "0c", "13", "ec", "5f", "97", "44", "17", "c4", "a7", "7e", "3d", "64", "5d", "19", "73" },
                { "60", "81", "4f", "dc", "22", "2a", "90", "88", "46", "ee", "b8", "14", "de", "5e", "0b", "db" },
                { "e0", "32", "3a", "0a", "49", "06", "24", "5c", "c2", "d3", "ac", "62", "91", "95", "e4", "79" },
                { "e7", "c8", "37", "6d", "8d", "d5", "4e", "a9", "6c", "56", "f4", "ea", "65", "7a", "ae", "08" },
                { "ba", "78", "25", "2e", "1c", "a6", "b4", "c6", "e8", "dd", "74", "1f", "4b", "bd", "8b", "8a" },
                { "70", "3e", "b5", "66", "48", "03", "f6", "0e", "61", "35", "57", "b9", "86", "c1", "1d", "9e" },
                { "e1", "f8", "98", "11", "69", "d9", "8e", "94", "9b", "1e", "87", "e9", "ce", "55", "28", "df" },
                { "8c", "a1", "89", "0d", "bf", "e6", "42", "68", "41", "99", "2d", "0f", "b0", "54", "bb", "16" }
            };
            string[] Bin = new string[] { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010"
                                          , "1011", "1100", "1101", "1110", "1111" };
            string dec = "0123456789abcdef";

            string[,] Rcon = new string[, ] {
                { "01", "02", "04", "08", "10", "20", "40", "80", "1b", "36" },
                { "00", "00", "00", "00", "00", "00", "00", "00", "00", "00" },
                { "00", "00", "00", "00", "00", "00", "00", "00", "00", "00" },
                { "00", "00", "00", "00", "00", "00", "00", "00", "00", "00" }
            };
            Dictionary <char, string> Cov    = new Dictionary <char, string>();
            Dictionary <string, char> COVDec = new Dictionary <string, char>();
            Dictionary <char, int>    subB   = new Dictionary <char, int>();

            for (int i = 0; i < dec.Length; i++)
            {
                Cov[dec[i]]    = Bin[i];
                COVDec[Bin[i]] = dec[i];
                subB[dec[i]]   = i;
            }
            string[,] PLaintTextMat = new string[4, 4];
            string[,] KeyMat        = new string[4, 4];
            string[,] AddRoundKey   = new string[4, 4];
            string[,] SubBytes      = new string[4, 4];
            string[,] W             = new string[4, 4];
            string[,] Keycopy       = new string[4, 4];
            string[,] str           = new string[4, 4];
            int           len1          = (plainText.Length / 2 + (plainText.Length % 2 == 0 ? 0 : 1));
            int           len2          = (key.Length / 2 + (key.Length % 2 == 0 ? 0 : 1));
            List <string> KeyWithoutX   = new List <string>();
            List <string> plainWithoutX = new List <string>();

            ///////////////////////////////////////////////////////////
            for (int i = 0; i < len1; i++)
            {
                string ch = plainText.Substring(i * 2, i * 2 + 2 > plainText.Length ? 1 : 2).ToLower();
                if (ch == "0x")
                {
                    continue;
                }
                else
                {
                    plainWithoutX.Add(ch);
                }
            }
            for (int i = 0; i < len2; i++)
            {
                string ch = key.Substring(i * 2, i * 2 + 2 > key.Length ? 1 : 2).ToLower();
                if (ch == "0x")
                {
                    continue;
                }
                else
                {
                    KeyWithoutX.Add(ch);
                }
            }
            //////////////////////////////////////////////
            int cn = 0;

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    PLaintTextMat[j, i] = plainWithoutX[cn];
                    KeyMat[j, i]        = KeyWithoutX[cn];
                    cn++;
                }
            }
            /////////////////////Add Round Key/////////////////////////////
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    AddRoundKey[i, j] = COVDec[mp.XOR(Cov[PLaintTextMat[i, j][0]], Cov[KeyMat[i, j][0]])].ToString() +
                                        COVDec[mp.XOR(Cov[PLaintTextMat[i, j][1]], Cov[KeyMat[i, j][1]])].ToString();
                }
            }
            ///////////////////////////////rounds///////////////////////////////////////
            for (int round = 0; round < 9; round++)
            {
                /////////////////////////////SubBytes////////////////////////////
                for (int i = 0; i < 4; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        SubBytes[i, j] = S_Box[subB[AddRoundKey[i, j][0]], subB[AddRoundKey[i, j][1]]];
                    }
                }
                /////////////////////////////////////shiftRows//////////////////////////////////////////
                for (int i = 1; i < 4; i++)
                {
                    int c = i;
                    while (c > 0)
                    {
                        string temp = SubBytes[i, 0];
                        for (int j = 1; j < 4; j++)
                        {
                            SubBytes[i, j - 1] = SubBytes[i, j];
                        }
                        SubBytes[i, 3] = temp;
                        c--;
                    }
                }
                /////////////////////////////MixColumn////////////////////////////////////
                int[,] decnum = new int[4, 4];
                for (int i = 0; i < 4; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        int de = int.Parse(SubBytes[i, j], System.Globalization.NumberStyles.HexNumber);
                        decnum[i, j] = de;
                    }
                }

                byte[,] B = new byte[4, 4];
                for (int i = 0; i < 4; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        B[i, j] = byte.Parse(decnum[i, j].ToString());
                    }
                }
                byte[,] BB = mp.MixColumns(B);
                for (int i = 0; i < 4; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        if (BB[i, j].ToString("X").ToLower().Length < 2)
                        {
                            str[i, j] = "0" + BB[i, j].ToString("X").ToLower();
                        }
                        else
                        {
                            str[i, j] = BB[i, j].ToString("X").ToLower();
                        }
                    }
                }
                ///////////////////////////////AddRoundKey/////////////////////////////////
                for (int i = 0; i < 4; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        Keycopy[i, j] = KeyMat[i, j];
                    }
                }
                string tem = KeyMat[0, KeyMat.GetLength(0) - 1];
                for (int i = 1; i < 4; i++)
                {
                    KeyMat[i - 1, KeyMat.GetLength(0) - 1] = KeyMat[i, KeyMat.GetLength(0) - 1];
                }
                KeyMat[KeyMat.GetLength(0) - 1, KeyMat.GetLength(0) - 1] = tem;
                for (int i = 0; i < Rcon.GetLength(0); i++)
                {
                    KeyMat[i, KeyMat.GetLength(0) - 1] = S_Box[subB[KeyMat[i, KeyMat.GetLength(0) - 1][0]], subB[KeyMat[i, KeyMat.GetLength(0) - 1][1]]];
                }
                for (int i = 0; i < 4; i++)
                {
                    string c1 = COVDec[mp.XOR(Cov[KeyMat[i, 0][0]], Cov[KeyMat[i, KeyMat.GetLength(0) - 1][0]])].ToString();
                    string c2 = COVDec[mp.XOR(Cov[KeyMat[i, 0][1]], Cov[KeyMat[i, KeyMat.GetLength(0) - 1][1]])].ToString();
                    W[i, 0] = COVDec[mp.XOR(Cov[c1[0]], Cov[Rcon[i, round][0]])].ToString() + COVDec[mp.XOR(Cov[c2[0]], Cov[Rcon[i, round][1]])].ToString();
                }
                for (int i = 1; i < 4; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        string ch1 = COVDec[mp.XOR(Cov[Keycopy[j, i][0]], Cov[W[j, i - 1][0]])].ToString();
                        string ch2 = COVDec[mp.XOR(Cov[Keycopy[j, i][1]], Cov[W[j, i - 1][1]])].ToString();
                        W[j, i] = ch1 + ch2;
                    }
                }
                for (int i = 0; i < 4; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        KeyMat[i, j] = W[i, j];
                    }
                }
                for (int i = 0; i < 4; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        string cs1 = COVDec[mp.XOR(Cov[str[j, i][0]], Cov[KeyMat[j, i][0]])].ToString();
                        string cs2 = COVDec[mp.XOR(Cov[str[j, i][1]], Cov[KeyMat[j, i][1]])].ToString();
                        AddRoundKey[j, i] = cs1 + cs2;
                    }
                }
            }
            /////////////////////////////SubBytes////////////////////////////
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    SubBytes[i, j] = S_Box[subB[AddRoundKey[i, j][0]], subB[AddRoundKey[i, j][1]]];
                }
            }
            /////////////////////////////////////shiftRows//////////////////////////////////////////
            for (int i = 1; i < 4; i++)
            {
                int c = i;
                while (c > 0)
                {
                    string temp = SubBytes[i, 0];
                    for (int j = 1; j < 4; j++)
                    {
                        SubBytes[i, j - 1] = SubBytes[i, j];
                    }
                    SubBytes[i, 3] = temp;
                    c--;
                }
            }

            ///////////////////////////////////////////////////////////////
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    Keycopy[i, j] = KeyMat[i, j];
                }
            }
            string te = KeyMat[0, KeyMat.GetLength(0) - 1];

            for (int i = 1; i < 4; i++)
            {
                KeyMat[i - 1, KeyMat.GetLength(0) - 1] = KeyMat[i, KeyMat.GetLength(0) - 1];
            }
            KeyMat[KeyMat.GetLength(0) - 1, KeyMat.GetLength(0) - 1] = te;
            for (int i = 0; i < Rcon.GetLength(0); i++)
            {
                KeyMat[i, KeyMat.GetLength(0) - 1] = S_Box[subB[KeyMat[i, KeyMat.GetLength(0) - 1][0]], subB[KeyMat[i, KeyMat.GetLength(0) - 1][1]]];
            }
            for (int i = 0; i < 4; i++)
            {
                string c1 = COVDec[mp.XOR(Cov[KeyMat[i, 0][0]], Cov[KeyMat[i, KeyMat.GetLength(0) - 1][0]])].ToString();
                string c2 = COVDec[mp.XOR(Cov[KeyMat[i, 0][1]], Cov[KeyMat[i, KeyMat.GetLength(0) - 1][1]])].ToString();
                W[i, 0] = COVDec[mp.XOR(Cov[c1[0]], Cov[Rcon[i, 9][0]])].ToString() + COVDec[mp.XOR(Cov[c2[0]], Cov[Rcon[i, 9][1]])].ToString();
            }
            for (int i = 1; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    string ch1 = COVDec[mp.XOR(Cov[Keycopy[j, i][0]], Cov[W[j, i - 1][0]])].ToString();
                    string ch2 = COVDec[mp.XOR(Cov[Keycopy[j, i][1]], Cov[W[j, i - 1][1]])].ToString();
                    W[j, i] = ch1 + ch2;
                }
            }
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    KeyMat[i, j] = W[i, j];
                }
            }
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    string cs1 = COVDec[mp.XOR(Cov[SubBytes[j, i][0]], Cov[KeyMat[j, i][0]])].ToString();
                    string cs2 = COVDec[mp.XOR(Cov[SubBytes[j, i][1]], Cov[KeyMat[j, i][1]])].ToString();
                    AddRoundKey[j, i] = cs1 + cs2;
                }
            }
            string CipherText = "";

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    CipherText += AddRoundKey[j, i];
                }
            }
            return("0x" + CipherText.ToUpper());
        }
コード例 #3
0
        public string Analyse3By3Key(string plainText, string cipherText)
        {
            //throw new NotImplementedException();
            MatrixOP r = new MatrixOP();
            Dictionary <char, int> DT = new Dictionary <char, int>();
            Dictionary <int, char> CT = new Dictionary <int, char>();
            int cnt = 0;

            for (char c = 'a'; c <= 'z'; c++)
            {
                DT[c]   = cnt;
                CT[cnt] = c;
                cnt++;
            }
            string[] split = new string[plainText.Length / 3 + (plainText.Length % 3 == 0 ? 0 : 1)];
            for (int i = 0; i < split.Length; i++)
            {
                split[i] = plainText.Substring(i * 3, i * 3 + 3 > plainText.Length ? 1 : 3);
            }
            string[] splitc = new string[cipherText.Length / 3 + (cipherText.Length % 3 == 0 ? 0 : 1)];
            for (int i = 0; i < splitc.Length; i++)
            {
                splitc[i] = cipherText.ToLower().Substring(i * 3, i * 3 + 3 > cipherText.Length ? 1 : 3);
            }
            List <string> PermKey = new List <string>();
            List <string> ciph    = new List <string>();

            for (int i = 0; i < split.Length; i++)
            {
                string perm = "";
                string ch   = "";
                for (int j = i + 2; j < split.Length; j++)
                {
                    perm += split[i] + split[j - 1] + split[j];
                    ch   += splitc[i] + splitc[j - 1] + splitc[j];
                    PermKey.Add(perm);
                    ciph.Add(ch);
                    perm = "";
                    ch   = "";
                }
            }
            List <int> In = new List <int>();

            for (int i = 0; i < PermKey.Count; i++)
            {
                In.Add(r.Inversekey(PermKey[i]));
            }
            int cnterr = 0;

            for (int i = 0; i < In.Count; i++)
            {
                if (In[i] < 0)
                {
                    cnterr++;
                }
            }
            if (cnterr == In.Count)
            {
                throw new InvalidAnlysisException();
            }
            int    invMul = 0;
            string pl     = "";
            string ct     = "";

            for (int i = 0; i < In.Count; i++)
            {
                if (In[i] > 0)
                {
                    invMul = In[i];
                    pl     = PermKey[i];
                    ct     = ciph[i];
                    break;
                }
            }
            double[,] keymat = new double[3, 3];
            int[,] Ciphermat = new int[3, 3];
            int rp = 0;

            for (int i = 0; i < 3; i++)
            {
                int cc = rp;
                for (int j = 0; j < 3; j++)
                {
                    keymat[i, j] = DT[pl[cc]];
                    rp++;
                    cc++;
                }
                cc = rp;
            }
            rp = 0;
            for (int i = 0; i < 3; i++)
            {
                int cc = rp;
                for (int j = 0; j < 3; j++)
                {
                    Ciphermat[i, j] = DT[ct[cc]];
                    rp++;
                    cc++;
                }
                cc = rp;
            }
            /////////////////////////cofactors///////////////////////////////
            int[,] matl = new int[3, 3];
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    matl[i, j] = int.Parse(Math.Floor((Math.Pow(-1, i + j) * (int.Parse(Matrix.Determinant(r.CreateSmallerMatrix(keymat, i, j)).ToString())))).ToString());
                    while (matl[i, j] < 0)
                    {
                        matl[i, j] += 26;
                    }
                    while (matl[i, j] > 26)
                    {
                        matl[i, j] -= 26;
                    }
                }
            }
            //////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////
            int[,] matKeyinverse = new int[3, 3];
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    matKeyinverse[i, j] = matl[j, i];
                    matKeyinverse[i, j] = (invMul * matKeyinverse[i, j]) % 26;
                }
            }
            //////////////////////////////////inverse///////////////////////////////////
            int[,] matRes = new int[3, 3];
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    int sum = 0;
                    for (int k = 0; k < 3; k++)
                    {
                        sum += matKeyinverse[i, k] * Ciphermat[k, j];
                    }
                    matRes[i, j] = sum % 26;
                }
            }
            string key = "";

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    key += CT[matRes[j, i]];
                }
            }
            return(key);
        }
コード例 #4
0
        public string Decrypt(string cipherText, string key)
        {
            MatrixOP mp = new MatrixOP();
            Dictionary <char, int> DT = new Dictionary <char, int>();
            Dictionary <int, char> CT = new Dictionary <int, char>();
            int cnt = 0;

            for (char c = 'a'; c <= 'z'; c++)
            {
                DT[c]   = cnt;
                CT[cnt] = c;
                cnt++;
            }
            int n = key.Length;

            if (key.Length % 2 == 0)
            {
                n = n / 2;
            }
            else
            {
                n = (n / 2) - 1;
            }
            int m = (cipherText.Length / n);

            double[,] matKey = new double[n, n];
            int[,] matPlain  = new int[n, m];
            int[,] matRes    = new int[n, m];
            int rp = 0;

            for (int i = 0; i < n; i++)
            {
                int cc = rp;
                for (int j = 0; j < n; j++)
                {
                    matKey[i, j] = DT[key[cc]];
                    rp++;
                    cc++;
                }
                cc = rp;
            }
            rp = 0;
            for (int i = 0; i < m; i++)
            {
                int cc = rp;
                for (int j = 0; j < n; j++)
                {
                    matPlain[j, i] = DT[cipherText.ToLower()[cc]];
                    rp++;
                    cc++;
                }
                cc = rp;
            }

            int mat = int.Parse(Matrix.Determinant(matKey).ToString()) % 26;

            //Console.WriteLine(mat);
            while (mat < 0)
            {
                mat += 26;
            }
            int x = 0;

            for (int b = 0; b < 26; b++)
            {
                if ((b * mat) % 26 == 1)
                {
                    x = b;
                    break;
                }
            }
            //Console.WriteLine(x);
            int[,] matl = new int[n, n];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    matl[i, j] = int.Parse(Math.Floor((Math.Pow(-1, i + j) * (int.Parse(Matrix.Determinant(mp.CreateSmallerMatrix(matKey, i, j)).ToString()))) % 26).ToString());
                    if (matl[i, j] % 26 < 0)
                    {
                        matl[i, j] += 26;
                    }
                }
            }

            /////////////////////////////////
            int[,] matKeyinverse = new int[n, n];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    matKeyinverse[i, j] = matl[j, i];
                    matKeyinverse[i, j] = (x * matKeyinverse[i, j]) % 26;
                }
            }
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < m; j++)
                {
                    int sum = 0;
                    for (int k = 0; k < n; k++)
                    {
                        sum += matKeyinverse[i, k] * matPlain[k, j];
                    }
                    matRes[i, j] = sum % 26;
                }
            }
            string PlaintText = "";

            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    PlaintText += CT[matRes[j, i]];
                }
            }
            return(PlaintText.ToLower());
        }
コード例 #5
0
        public List <int> Decrypt(List <int> cipherText, List <int> key)
        {
            //throw new NotImplementedException();
            MatrixOP mp = new MatrixOP();
            int      n  = key.Count;

            if (key.Count % 2 == 0)
            {
                n = n / 2;
            }
            else
            {
                n = (n / 2) - 1;
            }
            int m = (cipherText.Count / n);

            double[,] matKey = new double[n, n];
            int[,] matPlain  = new int[n, m];
            int[,] matRes    = new int[n, m];
            int rp = 0;

            for (int i = 0; i < n; i++)
            {
                int cc = rp;
                for (int j = 0; j < n; j++)
                {
                    matKey[i, j] = key[cc];
                    rp++;
                    cc++;
                }
                cc = rp;
            }
            rp = 0;
            for (int i = 0; i < m; i++)
            {
                int cc = rp;
                for (int j = 0; j < n; j++)
                {
                    matPlain[j, i] = cipherText[cc];
                    rp++;
                    cc++;
                }
                cc = rp;
            }

            int mat = int.Parse(Matrix.Determinant(matKey).ToString());

            //Console.WriteLine(mat);
            while (mat < 0)
            {
                mat += 26;
            }
            while (mat > 26)
            {
                mat -= 26;
            }
            ////////////////checking valid///////////////
            ExtendedEuclid e      = new ExtendedEuclid();
            int            mulinv = e.GetMultiplicativeInverse(mat, 26);

            if (mulinv == -1)
            {
                throw new InvalidAnlysisException();
            }
            int[,] matl = new int[n, n];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    matl[i, j] = int.Parse(Math.Floor((Math.Pow(-1, i + j) * (int.Parse(Matrix.Determinant(mp.CreateSmallerMatrix(matKey, i, j)).ToString()))) % 26).ToString());
                    if (matl[i, j] % 26 < 0)
                    {
                        matl[i, j] += 26;
                    }
                }
            }

            /////////////////////////////////
            int[,] matKeyinverse = new int[n, n];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    matKeyinverse[i, j] = matl[j, i];
                    matKeyinverse[i, j] = (mulinv * matKeyinverse[i, j]) % 26;
                }
            }
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < m; j++)
                {
                    int sum = 0;
                    for (int k = 0; k < n; k++)
                    {
                        sum += matKeyinverse[i, k] * matPlain[k, j];
                    }
                    matRes[i, j] = sum % 26;
                }
            }
            List <int> PlaintText = new List <int>();

            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    PlaintText.Add(matRes[j, i]);
                }
            }
            return(PlaintText);
        }
コード例 #6
0
        public string Analyse(string plainText, string cipherText)
        {
            MatrixOP r = new MatrixOP();
            //throw new NotImplementedException();
            Dictionary <char, int> DT = new Dictionary <char, int>();
            Dictionary <int, char> CT = new Dictionary <int, char>();
            int cnt = 0;

            for (char c = 'a'; c <= 'z'; c++)
            {
                DT[c]   = cnt;
                CT[cnt] = c;
                cnt++;
            }
            string[] split = new string[plainText.Length / 2 + (plainText.Length % 2 == 0 ? 0 : 1)];
            for (int i = 0; i < split.Length; i++)
            {
                split[i] = plainText.Substring(i * 2, i * 2 + 2 > plainText.Length ? 1 : 2);
            }
            string[] splitc = new string[cipherText.Length / 2 + (cipherText.Length % 2 == 0 ? 0 : 1)];
            for (int i = 0; i < splitc.Length; i++)
            {
                splitc[i] = cipherText.ToLower().Substring(i * 2, i * 2 + 2 > cipherText.Length ? 1 : 2);
            }
            List <string> PermKey = new List <string>();
            List <string> ciph    = new List <string>();

            for (int i = 0; i < split.Length; i++)
            {
                string perm = "";
                string ch   = "";
                for (int j = i + 1; j < split.Length; j++)
                {
                    perm += split[i] + split[j];
                    ch   += splitc[i] + splitc[j];
                    PermKey.Add(perm);
                    ciph.Add(ch);
                    perm = "";
                    ch   = "";
                }
            }
            List <int> CalInverse = new List <int>();

            for (int i = 0; i < PermKey.Count; i++)
            {
                CalInverse.Add(r.calculateInverse(PermKey[i]));
            }
            int cnterr = 0;

            for (int i = 0; i < CalInverse.Count; i++)
            {
                if (CalInverse[i] < 0)
                {
                    cnterr++;
                }
            }
            if (cnterr == CalInverse.Count)
            {
                throw new InvalidAnlysisException();
            }
            int    invMul = 0;
            string pl     = "";
            string ct     = "";

            for (int i = 0; i < CalInverse.Count; i++)
            {
                if (CalInverse[i] > 0)
                {
                    invMul = CalInverse[i];
                    pl     = PermKey[i];
                    ct     = ciph[i];
                    break;
                }
            }
            ////////////////////plaintext/////////////////////
            int[,] keymat = new int[2, 2];
            int idx = 0;

            for (int i = 0; i < 2; i++)
            {
                int cc = idx;
                for (int j = 0; j < 2; j++)
                {
                    keymat[i, j] = DT[pl[idx]];
                    idx++;
                    cc++;
                }
                cc = idx;
            }
            ////////////////////ciphertext//////////////////
            int[,] cimat = new int[2, 2];
            idx          = 0;
            for (int i = 0; i < 2; i++)
            {
                int cc = idx;
                for (int j = 0; j < 2; j++)
                {
                    cimat[j, i] = DT[ct[idx]];
                    idx++;
                    cc++;
                }
                cc = idx;
            }
            ///////////////////cofactors//////////////////
            int A = keymat[0, 0];
            int B = keymat[0, 1];
            int C = keymat[1, 0];
            int D = keymat[1, 1];

            keymat[0, 0] = invMul * D;
            keymat[1, 1] = invMul * A;
            keymat[1, 0] = invMul * (B * -1);
            keymat[0, 1] = invMul * (C * -1);
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    while (keymat[i, j] < 0)
                    {
                        keymat[i, j] += 26;
                    }
                    while (keymat[i, j] > 26)
                    {
                        keymat[i, j] -= 26;
                    }
                }
            }
            int[,] Mulapp = new int[2, 2];
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    int sum = 0;
                    for (int k = 0; k < 2; k++)
                    {
                        sum += cimat[i, k] * keymat[k, j];
                    }
                    Mulapp[i, j] = sum % 26;
                }
            }
            string key = "";

            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    key += CT[Mulapp[i, j]];
                }
            }
            return(key);
        }