def dot_product(matrix1, matrix2): rows = [row1 & row2 for row1 in matrix1 for row2 in matrix2] new_pub = mx.from_vectors([ row for row in mx.from_vectors(rows).gaussian_elimination() if len(row.support) ]) return new_pub
def circle_dot_prod(self, generator1, generator2): product_list = [] for row1 in generator1: for row2 in generator2: product_list.append(row1 & row2) prod_g = matrix.from_vectors(product_list) prod_g = prod_g.gaussian_elimination() res_g = [] for row in prod_g: if row.hamming_weight: res_g.append(row) return matrix.from_vectors(res_g)
def find_nonsingular(self, generator, g_mul_perm): M = [] for i in range(generator.nrows): M.append(g_mul_perm.T.solve(generator[i])[1]) return matrix.from_vectors(M)
def test_init_by_vectors(self): """Init by list of vectors.""" matr = matrix.from_vectors([Vector(0b011, 3), Vector(0b1110, 4), Vector(0b01, 2)]) self.assertEqual(matr.shapes, (3, 4)) self.assertEqual(list(matr), [Vector(0b011, 4), Vector(0b1110, 4), Vector(0b01, 4)])
def test_solving_linear_equation(self): """Test solving of linear equation.""" vec = Vector(0b1010, 4) matr_max_rank = matrix.Matrix(self.matr_max_rank, 4) fundamental, vec_solve = matr_max_rank.solve(vec) self.assertFalse(fundamental) self.assertEqual( matr_max_rank * matrix.from_vectors([vec_solve]).transpose(), matrix.from_vectors([vec]).transpose()) vec = Vector(0b1010, 4) matr_non_max_rank1 = matrix.Matrix(self.matr_non_max_rank1, 5) fundamental, vec_solve = matr_non_max_rank1.solve(vec) self.assertFalse(fundamental) self.assertFalse(vec_solve) vec = Vector(0b1110, 4) fundamental, vec_solve = matr_non_max_rank1.solve(vec) self.assertEqual(fundamental, matrix.Matrix([0b11010, 0b01101], 5)) self.assertEqual( matr_non_max_rank1 * matrix.from_vectors([vec_solve]).transpose(), matrix.from_vectors([vec]).transpose())
def find_permutation(matrix, m): a = matrix.T.solve(vector.from_support_supplement(2**m))[1] removing_num = a.support[0] if len(a.support) else 0 logger.debug(f'removing {removing_num}...') a_rows = [a] for i in range(m + 1): if i != removing_num: a_rows.append(a ^ vector.from_support(m + 1, [i])) a_rows = (mx.from_vectors(a_rows) * matrix)[1:] return mx.permutation([row.value for row in a_rows.T])
def syndrome(parity_check, vec): """Return the syndrome of `vec` using parity check matrix.""" try: return (parity_check * matrix.from_vectors([vec]).T).T[0] except TypeError: pass except IndexError: return None try: return (parity_check * vec.T).T[0] except IndexError: pass return None
def encode(generator, vec): """Encode the `vec` using generator matrix `generator` of code.""" try: return (matrix.from_vectors([vec]) * generator)[0] except TypeError: pass except IndexError: return None try: return (vec * generator)[0] except IndexError: pass return None
def hadamard_product(generator_a, generator_b): """Evaluate the generator matrix of Hadamard product code. :param: Matrix generator_a - the generator matrix of the first code; :param: Matrix generator_b - the generator matrix of the second code. :return: Matrix generator - the generator matrix of Hadamard product of the first and the second codes. """ hadamard_dict = {} # {index of the fist 1 in the row: row} hadamard = [] for row_a in generator_a: for row_b in generator_b: row = row_a * row_b test_row = row.copy() for i, row_h in hadamard_dict.items(): if test_row[i]: test_row += row_h if test_row.value: hadamard_dict[test_row.support[0]] = test_row hadamard.append(row) return matrix.from_vectors(hadamard)
def attack(self, generator): rm_subcode_basis = matrix.Matrix() rm_subcode_dim = 0 for i in range(self.r): rm_subcode_dim += self.binomial_coef(self.m, i) while rm_subcode_basis.nrows < rm_subcode_dim: min_weight_codeword = self.min_weight_sample(generator) shortened_g = tools.truncate(generator, min_weight_codeword) inner_sets = self.decompose_inner_sets(shortened_g) f_vecs = [ vector.from_support(2**self.m, min_weight_codeword + s) for s in inner_sets ] rm_subcode_basis = tools.union(rm_subcode_basis, matrix.from_vectors(f_vecs)) return rm_subcode_basis
def find_permutation(self, generator): onev = vector.from_support_supplement(2**m) a = generator.T.solve(onev)[1] removing_num = 0 if len(a.support): removing_num = a.support[0] A_rows = [a] for i in range(0, m + 1): if i != removing_num: A_rows.append(a ^ vector.from_support(m + 1, [i])) ag = matrix.from_vectors(A_rows) * generator A_rows = ag[1:] return matrix.permutation([row.value for row in A_rows.T])
def attack(self, pub_key): B = matrix.Matrix() B_size = 0 for i in range(self.r): B_size += binom(self.m, i) codeword_support_list = [] while B.nrows < B_size: codeword_support = self \ ._gauss_codeword_support(pub_key, codeword_support_list) codeword_support_list.append(codeword_support) pub_key_truncated = tools.truncate(pub_key, codeword_support) inner_sets = self._decompose_inner_sets(pub_key_truncated) f_vecs = [ vector.from_support(2**self.m, codeword_support + s) for s in inner_sets ] B = tools.union(B, matrix.from_vectors(f_vecs)) return B
def find_nonsingular(public, permuted_rm): rows = [permuted_rm.T.solve(row)[1] for row in iter(public)] return mx.from_vectors(rows)