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); }
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); }
// 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); }
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); }
// 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)); }