def tu_decomposition(s, v, verbose=False): """Using the knowledge that v is a subspace of Z_s of dimension n, a TU-decomposition (as defined in [Perrin17]) of s is performed and T and U are returned. """ N = int(log(len(s), 2)) # building B basis = extract_basis(v[0], N) t = len(basis) basis = complete_basis(basis, N) B = Matrix(GF(2), N, N, [tobin(x, N) for x in reversed(basis)]) if verbose: print "B= (rank={})\n{}".format(B.rank(), B.str()) # building A basis = complete_basis(extract_basis(v[1], N), N) A = Matrix(GF(2), N, N, [tobin(x, N) for x in reversed(basis)]) if verbose: print "A= (rank={})\n{}".format(A.rank(), A.str()) # building linear equivalent s_prime s_prime = [ apply_bin_mat(s[apply_bin_mat(x, A.inverse())], B) for x in xrange(0, 2**N) ] # TU decomposition of s' T, U = get_tu_open(s_prime, t) if verbose: print "T=[" for i in xrange(0, 2**(N - t)): print " {} {}".format(T[i], is_permutation(T[i])) print "]\nU=[" for i in xrange(0, 2**t): print " {} {}".format(U[i], is_permutation(U[i])) print "]" return T, U
def get_T1(K, S, unit_first=True, verbose=False): # Sx is a list of generators of K(S,2) with the unit first or last, assuming h(K)=1 u = -1 if K==QQ else K(K.unit_group().torsion_generator()) from KSp import IdealGenerator Sx = [IdealGenerator(P) for P in S] if unit_first: Sx = [u] + Sx else: Sx = Sx + [u] r = len(Sx) N = prod(S,1) # Initialize T1 to be empty and A to be a matric with 0 rows and r=#Sx columns T1 = [] A = Matrix(GF(2),0,len(Sx)) primes = primes_iter(K,1) p = primes.next() # Repeat the following until A has full rank: take the next prime p # from the iterator, skip if it divides N (=product over S), form the # vector v, and keep p and append v to the bottom of A if it increases # the rank: while A.rank() < r: p = primes.next() while p.divides(N): p = primes.next() if verbose: print("A={} with {} rows and {} cols".format(A,A.nrows(),A.ncols())) v = vector(alphalist(p, Sx)) if verbose: print("v={}".format(v)) A1 = A.stack(v) if A1.rank() > A.rank(): A = A1 T1 = T1 + [p] if verbose: print("new A={} with {} rows and {} cols".format(A,A.nrows(),A.ncols())) print("T1 increases to {}".format(T1)) # the last thing returned is a "decoder" which returns the # discriminant Delta given the splitting beavious at the primes in # T1: B = A.inverse() def decoder(alphalist): e = list(B*vector(alphalist)) return prod([D**ZZ(ei) for D,ei in zip(Sx,e)], 1) return T1, A, decoder
def get_ccz_equivalent_permutation_cartesian(s, v0, v1, verbose=False): """Takes as input two vector spaces v0 and v1 of the set of zeroes in the LAT of s, each being the cartesian product of two spaces, and returns a permutation CCZ equivalent to s obtained using these CCZ spaces. """ N = int(log(len(s), 2)) # building B e1 = extract_basis(v0[0], N) t = len(e1) e2 = extract_basis(v1[0], N) B = Matrix(GF(2), N, N, [tobin(x, N) for x in e1 + e2]) if verbose: print "B= (rank={})\n{}".format(B.rank(), B.str()) # building A e1 = extract_basis(v0[1], N) e2 = extract_basis(v1[1], N) A = Matrix(GF(2), N, N, [tobin(x, N) for x in e1 + e2]) if verbose: print "A= (rank={})\n{}".format(A.rank(), A.str()) # building linear equivalent s_prime s_prime = [ apply_bin_mat(s[apply_bin_mat(x, A.inverse())], B) for x in xrange(0, 2**N) ] # TU decomposition of s' T_inv, U = get_tu_closed(s_prime, t) if verbose: print "T_inv=[" for i in xrange(0, 2**t): print " {} {}".format(T_inv[i], is_permutation(T_inv[i])) print "]\nU=[" for i in xrange(0, 2**t): print " {} {}".format(U[i], is_permutation(U[i])) print "]" # TU-unfolding T = [inverse(row) for row in T_inv] result = [0 for x in xrange(0, 2**N)] for l in xrange(0, 2**t): for r in xrange(0, 2**(N - t)): x = (l << (N - t)) | r y_r = T[r][l] y_l = U[y_r][r] result[x] = (y_l << (t)) | y_r return result
def bound_rosati(alpha_geo): H = Matrix(4, 4) H[0, 2] = H[1, 3] = -1 H[2, 0] = H[3, 1] = 1 return (alpha_geo * H * alpha_geo.transpose() * H.inverse()).trace() / 2