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