def incidence_matrix_from_multiplicities(n, mu): m = sum(mu.values()) A = Matrix(n, m) j = 0 for support, multiplicity in mu.items(): if multiplicity < 0: raise ValueError('invalid multiplicity') if any(x not in range(n) for x in support): raise ValueError('invalid support') col = [1 if i in support else 0 for i in range(n)] for _ in range(multiplicity): A.set_column(j, col) j += 1 return A
def are_CCZ_equivalent(s1, s2): s1, s2 = convert_sboxes(s1, s2) assert_equal_sizes(s1, s2) lin1 = s1.is_linear() lin2 = s2.is_linear() if lin1 ^ lin2: return False if lin1 and lin2: return True inp, out = s1.m, s1.n M1 = Matrix(GF(2), 1 + inp + out, 2**inp) M2 = Matrix(GF(2), 1 + inp + out, 2**inp) for x in range(2**inp): M1.set_column(x, tobin(1, 1) + tobin(x, inp) + tobin(s1[x], out)) M2.set_column(x, tobin(1, 1) + tobin(x, inp) + tobin(s2[x], out)) L1 = LinearCode(M1) L2 = LinearCode(M2) # Annoying: this is not checked in "is_permutation_equivalent" code! # raises a TypeError instead if L1.generator_matrix().nrows() != L2.generator_matrix().nrows(): return False return L1.is_permutation_equivalent(L2)