Exemple #1
0
        public Matrix GetBasisOfWeight(Matrix B, int weight, int num)
        {
            Matrix res = new Matrix(), Bchange, B_copy = new Matrix(B);

            while (res.size[0] < num)
            {
                Bchange = MatrixFuncs.GenNoise(B.size[0]);
                B_copy  = Bchange * B_copy;
                for (int i = 0; i < B.size[0]; ++i)
                {
                    if (Common.wt(B_copy.data[i]) == weight)
                    {
                        if (MatrixFuncs.Gauss(res & new Vector(B_copy.data[i])) == res.size[0] + 1)
                        {
                            ;
                        }
                        res &= new Vector(B_copy.data[i]);
                    }
                    if (res.size[0] == num)
                    {
                        break;
                    }
                }
            }
            return(res);
        }
Exemple #2
0
        public static Matrix operator *(Code C1, Code C2)
        {
            if (C1.n != C2.n)
            {
                return(null);
            }
            List <List <int> > new_basis = new List <List <int> >();
            List <int>         item      = new List <int>();

            for (int i = 0; i < C1.k; ++i)
            {
                for (int j = 0; j < C2.k; ++j)
                {
                    item = new List <int>();
                    for (int s = 0; s < C2.n; ++s)
                    {
                        item.Add(C1.G.data[i][s] * C2.G.data[j][s]);
                    }
                    new_basis.Add(item);
                }
            }
            Matrix res = new Matrix(new_basis);

            MatrixFuncs.Gauss(res);
            return(res);
        }
Exemple #3
0
        bool checkP(Matrix Gp, Matrix P1_inv, Ham ham, Matrix Zero, int s, int n)
        {
            bool result = true;

            for (int i = 0; i < s - 1; ++i)
            {
                result &= MatrixFuncs.SubMatrix(Gp * P1_inv, i * n, (i + 1) * n) * MatrixFuncs.Transp(ham.H) == Zero;
            }
            return(result);
        }
Exemple #4
0
        // Find A^{-1}
        public static Matrix Invert(Matrix A)
        {
            Matrix E = new Matrix(A.size[0], A.size[0]);

            for (int i = 0; i < A.size[0]; ++i)
            {
                E.data[i][i] = 1;
            }
            return(MatrixFuncs.SolveEq(A, E));
        }
Exemple #5
0
        public Matrix R;  // secret key

        public double KeyGen(CodeType codetype, int[] param)
        {
            Code code = new Code();
            int  k = 0, n = 0, r, m, l = param[2];

            switch (codetype)
            {
            case CodeType.Hamming:
                r    = param[0];
                code = new Ham(r);
                break;

            case CodeType.RM:
                r    = param[0]; m = param[1];
                code = new RM(r, m);
                break;
            }
            k = code.G.size[0]; n = code.G.size[1];
            Stopwatch t = new Stopwatch(); t.Start();

            //Matrix N
            N = MatrixFuncs.GenNoise(k);

            //Matrix P
            int nn = n + l; P = new Matrix(nn, nn);

            int[] check = new int[nn]; int ind = 0;
            for (int i = 0; i < nn; ++i)
            {
                do
                {
                    ind = Common.GetRand() % nn;
                } while (check[ind] == 1);
                P.data[ind][i] = 1;
                check[ind]     = 1;
            }

            //Matrix R
            R = new Matrix(k, l);
            for (int i = 0; i < k; ++i)
            {
                for (int j = 0; j < l; ++j)
                {
                    R.data[i][j] = Common.GetRand() & 1;
                }
            }

            Gp = N * (code.G | R) * P;
            t.Stop();
            return(t.ElapsedMilliseconds / 1000.00);
        }
Exemple #6
0
        public Matrix P;        // secret key

        public double KeyGen(CodeType codetype, int[] param)
        {
            Code code = new Code();
            int  k, n, r = 0, s = 0, m, nn;

            switch (codetype)
            {
            case CodeType.Hamming:
                r    = param[0];
                s    = param[1];
                code = new Ham(r);
                break;

            case CodeType.RM:
                r    = param[0]; m = param[1]; s = param[2];
                code = new RM(r, m);
                break;
            }

            k = code.G.size[0]; n = code.G.size[1]; nn = n * s;
            Stopwatch t = new Stopwatch(); t.Start();

            //Matrix list N
            N = new List <Matrix>();
            Matrix N_i, NG = new Matrix();

            for (int ii = 0; ii < s; ++ii)
            {
                N_i = MatrixFuncs.GenNoise(k);
                N.Add(N_i);
                NG |= N_i * code.G;
            }

            //Matrix P
            P = new Matrix(nn, nn);
            int[] check = new int[nn]; int ind = 0;
            for (int i = 0; i < nn; ++i)
            {
                do
                {
                    ind = Common.GetRand() % nn;
                } while (check[ind] == 1);
                P.data[ind][i] = 1;
                check[ind]     = 1;
            }

            Gp = NG * P;
            t.Stop();
            return(t.ElapsedMilliseconds / 1000.00);
        }
Exemple #7
0
        // Generate a random invertible matrix
        public static Matrix GenNoise(int size)
        {
            Matrix res = new Matrix(size, size);

            do
            {
                for (int i = 0; i < size; ++i)
                {
                    for (int j = 0; j < size; ++j)
                    {
                        res.data[i][j] = Common.GetRand() & 1;
                    }
                }
            } while (MatrixFuncs.Gauss(new Matrix(res)) < size);
            return(res);
        }
Exemple #8
0
        public static Matrix DualMatrix(Matrix G1)
        {
            Matrix     G1_copy = new Matrix(G1);
            List <int> I, J; int k = G1_copy.size[0], n = G1_copy.size[1];
            Matrix     H1 = new Matrix(n - k, n);

            MatrixFuncs.Gauss_E(G1_copy, out I, out J);
            for (int s = 0; s < k; ++s)
            {
                for (int i = 0; i < n - k; ++i)
                {
                    H1.data[i][I[s]] = G1_copy.data[s][J[i]];
                }
            }
            for (int i = 0; i < n - k; ++i)
            {
                H1.data[i][J[i]] = 1;
            }
            return(H1);
        }
Exemple #9
0
        public Matrix P;  // secret key

        public double KeyGen(CodeType codetype, int[] param)
        {
            Code code = new Code();
            int  k = 0, n = 0, r, m;

            switch (codetype)
            {
            case CodeType.Hamming:
                r    = param[0];
                code = new Ham(r);
                break;

            case CodeType.RM:
                r    = param[0]; m = param[1];
                code = new RM(r, m);
                break;
            }

            k = code.G.size[0]; n = code.G.size[1];
            Stopwatch t = new Stopwatch(); t.Start();

            //Matrix N
            N = MatrixFuncs.GenNoise(k);

            //Matrix P
            P = new Matrix(n, n);
            int[] check = new int[n]; int ind = 0;
            for (int i = 0; i < n; ++i)
            {
                do
                {
                    ind = Common.GetRand() % n;
                } while (check[ind] == 1);
                P.data[ind][i] = 1;
                check[ind]     = 1;
            }
            Gp = N * code.G * P;
            t.Stop();
            return(t.ElapsedMilliseconds / 1000.00);
        }
Exemple #10
0
        public double AttackHam(out Matrix N1, out Matrix P1)
        {
            int k = Gp.size[0], n = Gp.size[1];

            N1 = new Matrix(k, k); P1 = new Matrix(n, n);
            Code code = new Code(Gp);
            // compute r
            int r = 0;

            while ((1 << r) - 1 < n)
            {
                ++r;
            }
            Stopwatch t = new Stopwatch(); t.Start();

            // Matrix P
            Ham ham = new Ham(r);
            IEnumerable <int> tmp1, tmp2;
            Matrix            P1_inv = new Matrix(n, n);

            for (int j = 0; j < n; ++j)
            {
                tmp1 = code.H.data.Select(x => x[j]);
                for (int jj = 0; jj < n; ++jj)
                {
                    tmp2 = ham.H.data.Select(x => x[jj]);
                    if (tmp1.SequenceEqual(tmp2))
                    {
                        P1.data[jj][j]     = 1;
                        P1_inv.data[j][jj] = 1;
                        break;
                    }
                }
            }
            // Matrix N
            code.G = code.G * P1_inv;
            N1     = MatrixFuncs.Transp(MatrixFuncs.SolveEq(MatrixFuncs.Transp(ham.G), MatrixFuncs.Transp(code.G)));
            t.Stop();
            return(t.ElapsedMilliseconds / 1000.00);
        }
Exemple #11
0
        public List <int>[] GetHamIndices(Code code, Ham ham, int r, int s, int n, int k)
        {
            int               hweight = 1 << (r - 1);
            Matrix            Bchange = MatrixFuncs.GenNoise(n * s - k), Hsub = GetBasisOfWeight(code.H, s * hweight, n - k);
            IEnumerable <int> hcol1, hcol2;
            List <int>        check = Enumerable.Range(0, n * s).ToList();

            List <int>[] res_idx = new List <int> [n];

            for (int j = 0; j < n; ++j)
            {
                res_idx[j] = new List <int>();
                hcol1      = ham.H.data.Select(x => x[j]);
                for (int jj = 0; jj < check.Count; ++jj)
                {
                    hcol2 = Hsub.data.Select(x => x[check[jj]]);
                    if (hcol2.SequenceEqual(hcol1))
                    {
                        res_idx[j].Add(check[jj]);
                        check.RemoveAt(jj);
                        --jj;
                    }
                    if (res_idx[j].Count > s)
                    {
                        break;
                    }
                }
                if (res_idx[j].Count != s)
                {
                    Hsub    = GetBasisOfWeight(code.H, s * hweight, n - k);
                    res_idx = new List <int> [n];
                    check   = Enumerable.Range(0, n * s).ToList();
                    j       = -1;
                }
            }
            return(res_idx);
        }
Exemple #12
0
        // Find vector by weight in a code
        public static Vector FindWeight_simple(Matrix G1, int w)
        {
            int        tmp, k = G1.size[0], n = G1.size[1];
            List <int> I = new List <int>(), J = new List <int>(); int[] check;
            Random     rnd = new Random();

            while (true)
            {
                check = new int[n];
                while (I.Count < k)
                {
                    tmp = Math.Abs(Common.GetRand()) % n; // rnd.Next(0, n);
                    if (check[tmp] == 0)
                    {
                        I.Add(tmp);
                        check[tmp] = 1;
                    }
                }
                for (int i = 0; i < check.Length; ++i)
                {
                    if (check[i] == 0)
                    {
                        J.Add(i);
                    }
                }
                MatrixFuncs.Gauss_on_I(G1, I, J);
                for (int i = 0; i < G1.size[0]; ++i)
                {
                    if (Common.wt(G1.data[i]) <= w)
                    {
                        return(new Vector(G1.data[i]));
                    }
                }
                I.Clear(); J.Clear();
            }
        }
Exemple #13
0
        public double AttackHam(out List <Matrix> Nlist, out Matrix P1)
        {
            int k = Gp.size[0], nn = Gp.size[1];

            Nlist = new List <Matrix>(); P1 = new Matrix(nn, nn);
            int r = (int)Math.Log((nn + 2) / 2, 2);
            int tmp = nn % ((1 << r) - 1), s;

            while (tmp != 0)
            {
                --r;
                tmp = nn % ((1 << r) - 1);
            }
            s = nn / ((1 << r) - 1); int n = nn / s;
            Matrix Ni = new Matrix(k, k); P1 = new Matrix(nn, nn); Matrix P1_inv = new Matrix(nn, nn);
            Code   code = new Code(Gp);
            Ham    ham  = new Ham(r);

            Stopwatch t = new Stopwatch(); t.Start();

            // Matrix P1
            List <int>[] ham_idx = GetHamIndices(code, ham, r, s, n, k);
            Matrix       Zero = new Matrix(k, n - k);
            BigInteger   iter_count = 0, max_iter_num = 1, ind_count = 0;

            List <int>[] idx_copy = new List <int> [n]; int[][] indices = new int[s][];
            for (int i = 0; i < s; ++i)
            {
                indices[i]   = new int[n];
                max_iter_num = BigInteger.Multiply(max_iter_num, BigInteger.Pow(s - i, n));
            }
            do
            {
                ++iter_count; ++ind_count;
                if (iter_count > max_iter_num)
                {
                    ham_idx = GetHamIndices(code, ham, r, s, n, k);
                    for (int i = 0; i < s; ++i)
                    {
                        indices[i] = new int[n];
                    }
                    iter_count = 1; ind_count = 1;
                }
                idx_copy = ham_idx.Select(x => new List <int>(x)).ToArray();
                P1       = new Matrix(nn, nn); P1_inv = new Matrix(nn, nn);
                for (int i = 0; i < s; i++)
                {
                    for (int j = 0; j < n; ++j)
                    {
                        P1.data[i * n + j][idx_copy[j][indices[i][j]]]     = 1;
                        P1_inv.data[idx_copy[j][indices[i][j]]][i * n + j] = 1;
                        idx_copy[j].RemoveAt(indices[i][j]);
                    }
                }
                Common.NextSet(indices[0], s, n);
                if (ind_count == BigInteger.Pow(s, n))
                {
                    indices[0] = new int[n];
                    Common.NextSet(indices[1], s - 1, n);
                    ind_count = 0;
                }
            } while (checkP(Gp, P1_inv, ham, Zero, s, n) == false);

            // Matrices N
            Matrix NG = Gp * P1_inv;

            for (int i = 0; i < s; ++i)
            {
                Ni = MatrixFuncs.SolveEq(MatrixFuncs.Transp(ham.G), MatrixFuncs.Transp(MatrixFuncs.SubMatrix(NG, i * n, (i + 1) * n)));
                var ttt = MatrixFuncs.Transp(Ni) * ham.G == MatrixFuncs.SubMatrix(NG, i * n, (i + 1) * n);
                Nlist.Add(MatrixFuncs.Transp(Ni));
            }
            NG = new Matrix();
            for (int i = 0; i < Nlist.Count; ++i)
            {
                NG |= Nlist[i] * ham.G;
            }
            t.Stop();
            return(t.ElapsedMilliseconds / 1000.00);
        }
Exemple #14
0
        // Reduction on r-parameter (for RM-codes)
        public static Code Reduction(Code code_r, int r, int m)
        {
            int    k = code_r.G.size[0], n = code_r.G.size[1];
            Matrix res = new Matrix();

            int    sz = code_r.G.size[0] - Common.C(m, r);
            Vector x; List <int> ind_f = new List <int>(); List <List <int> > ind_sets = new List <List <int> >();
            int    w = 1 << (m - r), wmin = (1 << r) - 1;

            Matrix H_short;

            while (res.size[0] < sz)
            {
                x       = Code.FindWeight_simple(code_r.G, w);
                H_short = new Matrix(n - k, n - w);
                int c = 0; ind_f.Clear();
                for (int j = 0; j < n; ++j)
                {
                    if (x.data[j] == 0)
                    {
                        for (int i = 0; i < code_r.H.size[0]; ++i)
                        {
                            H_short.data[i][c] = code_r.H.data[i][j];
                        }
                        ind_f.Add(j);
                        ++c;
                    }
                }
                MatrixFuncs.Gauss(H_short);         //выделяем максимальную л.н. подсистему

                Ind_set(H_short, ind_f, r, m, (long)n, ind_sets);
                List <Vector> vecs = new List <Vector>();
                for (int i = 0; i < wmin; ++i)
                {
                    vecs.Add(new Vector(n));
                    for (int j = 0; j < w; j++)
                    {
                        vecs[i].data[ind_sets[i][j]] = 1;
                    }
                }
                for (int i = 0; i < wmin; ++i)
                {
                    for (int j = 0; j < n; j++)
                    {
                        if (x.data[j] != 0)
                        {
                            vecs[i].data[j] = 1;
                        }
                    }

                    if (code_r.IsCodeWord(vecs[i]))
                    {
                        if (res.size[0] == 0 || MatrixFuncs.Gauss(res & vecs[i]) == res.size[0] + 1)
                        {
                            res &= vecs[i];
                        }
                    }
                    if (res.size[0] == sz)
                    {
                        return(new Code(res));
                    }
                }
                ind_f.Clear();
            }
            return(new Code(res));
        }
Exemple #15
0
        //Gaussian elimination
        public static int Gauss(Matrix A)
        {
            if (A == null || A.size[0] == 0)
            {
                return(0);
            }
            int  k = A.size[0], n = A.size[1];
            bool flag = true; int rank = 0;

            for (int i = 0, j = 0; i < k && j < n; ++i, ++j)//c - для инф. окна
            {
                if (i == k - 1)
                {
                    if (A.data[k - 1][j] != 0)
                    {
                        for (int ii = 0; ii < k - 1; ++ii)
                        {
                            if (A.data[ii][j] != 0)
                            {
                                for (int s = 0; s < n; ++s)
                                {
                                    A.data[ii][s] = (A.data[ii][s] + A.data[k - 1][s]) & 1;
                                }
                            }
                        }
                        ++rank;
                        break;
                    }
                    else
                    {
                        i--;
                    }
                }
                else
                {
                    if (A.data[i][j] == 0)
                    {
                        flag = false;
                        for (int s = i + 1; s < k; ++s)
                        {
                            if (A.data[s][j] != 0)
                            {
                                flag = true;
                                MatrixFuncs.SwapRows(A, i, s);
                                break;
                            }
                        }
                    }
                    if (flag)
                    {
                        for (int s = 0; s < k; ++s)
                        {
                            if (s != i && A.data[s][j] != 0)
                            {
                                for (int q = 0; q < n; q++)
                                {
                                    A.data[s][q] = (A.data[s][q] + A.data[i][q]) & 1;
                                }
                            }
                        }
                        ++rank;
                    }
                    else
                    {
                        i--; flag = true;
                    }
                }
            }
            //избавление от нулевых строк
            for (int i = rank; i < k; ++i)
            {
                A -= rank;
            }
            return(rank);
        }
Exemple #16
0
        public double AttackRM(out Matrix N1, out Matrix P1)
        {
            int k = Gp.size[0], n = Gp.size[1];

            N1 = new Matrix(k, k); P1 = new Matrix(n, n);
            Code code = new Code(Gp); Code Gp_reduced;
            // Compute r, m
            int r = -1, m = (int)Math.Log(n, 2), k1 = 0;

            while (k1 < k)
            {
                ++r;
                k1 += Common.C(m, r);
            }

            RM        rm = new RM(r, m);
            Stopwatch t  = new Stopwatch(); t.Start();

            // Reduction
            //2 * r >= m => reduction on dual code
            if (2 * r < m || m - r == 1)
            {
                Gp_reduced = new Code(code.G);
            }
            else
            {
                Gp_reduced = new Code(code.H);
                r          = m - r - 1;
            }
            while (r > 1)
            {
                Gp_reduced = AttackFuncs.Reduction(Gp_reduced, r, m);
                --r;
            }

            // Matrix P
            Matrix Tmp; int idx = -1;
            Vector e = new Vector(Enumerable.Repeat(1, n).ToList());

            do
            {
                ++idx;
                Tmp = (new Matrix(Gp_reduced.G) - idx) & e;
            }while (MatrixFuncs.Gauss(Tmp) < m + 1);
            Tmp = Gp_reduced.G; Tmp -= idx; Matrix RM_1 = (new RM(1, m)).G -= 0;
            IEnumerable <int> tmp1, tmp2;
            Matrix            P1_inv = new Matrix(n, n);

            for (int j = 0; j < n; ++j)
            {
                tmp1 = Tmp.data.Select(x => x[j]);
                for (int jj = 0; jj < n; ++jj)
                {
                    tmp2 = RM_1.data.Select(x => x[jj]);
                    if (tmp1.SequenceEqual(tmp2))
                    {
                        P1.data[jj][j]     = 1;
                        P1_inv.data[j][jj] = 1;
                        break;
                    }
                }
            }
            // Matrix N
            code.G = code.G * P1_inv;
            N1     = MatrixFuncs.Transp(MatrixFuncs.SolveEq(MatrixFuncs.Transp(rm.G), MatrixFuncs.Transp(code.G)));

            t.Stop();
            return(t.ElapsedMilliseconds / 1000.00);
        }
Exemple #17
0
        //Gaussian elimination with information window
        public static int Gauss_E(Matrix A, out List <int> I, out List <int> J)
        {
            I = new List <int>(); J = new List <int>();
            if (A == null || A.size[0] == 0)
            {
                return(0);
            }
            int k = A.size[0], n = A.size[1];

            if (k <= n)
            {
                bool flag = true;
                for (int i = 0, c = 0, j = 0; i < k && j < n; ++i, ++c, ++j)//c - для инф. окна
                {
                    if (i == k - 1)
                    {
                        if (A.data[k - 1][j] != 0)
                        {
                            for (int ii = 0; ii < k - 1; ++ii)
                            {
                                if (A.data[ii][j] != 0)
                                {
                                    for (int s = 0; s < n; ++s)
                                    {
                                        A.data[ii][s] = (A.data[ii][s] + A.data[k - 1][s]) & 1;
                                    }
                                }
                            }
                            I.Add(j); ++j;
                            while (j < n)
                            {
                                J.Add(j); ++j;
                            }
                            break;
                        }
                        else
                        {
                            i--; J.Add(j);
                        }
                    }
                    else
                    {
                        if (A.data[i][j] == 0)
                        {
                            flag = false;
                            for (int s = i + 1; s < k; ++s)
                            {
                                if (A.data[s][j] != 0)
                                {
                                    flag = true;
                                    MatrixFuncs.SwapRows(A, i, s);
                                    break;
                                }
                            }
                        }
                        if (flag)
                        {
                            for (int s = 0; s < k; ++s)
                            {
                                if (s != i && A.data[s][j] != 0)
                                {
                                    for (int q = 0; q < n; q++)
                                    {
                                        A.data[s][q] = (A.data[s][q] + A.data[i][q]) & 1;
                                    }
                                }
                            }
                            I.Add(j);
                        }
                        else
                        {
                            c--; i--; J.Add(j); flag = true;
                        }
                    }
                }
                //избавление от нулевых строк
                for (int i = I.Count; i < A.size[0]; ++i)
                {
                    A -= I.Count;
                }
                return(I.Count);
            }
            return(-1);
        }