コード例 #1
0
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
コード例 #2
0
def NonCubicSet(K,S, verbose=False):
    u = -1 if K==QQ else  K(K.unit_group().torsion_generator())
    from KSp import IdealGenerator
    Sx = [u] + [IdealGenerator(P) for P in S]
    r = len(Sx)
    d123 = r + binomial(r,2) + binomial(r,3)
    vecP = vec123(K,Sx)
    A = Matrix(GF(2),0,d123)
    N = prod(S,1)

    primes = primes_iter(K,None)
    T = []
    while A.rank() < d123:
        p = primes.next()
        while p.divides(N):
            p = primes.next()
        v = vecP(p)
        if verbose:
            print("v={}".format(v))
        A1 = A.stack(vector(v))
        if A1.rank() > A.rank():
            A = A1
            T.append(p)
            if verbose:
                print("new A={} with {} rows and {} cols".format(A,A.nrows(),A.ncols()))
                print("T increases to {}".format(T))
    return T
コード例 #3
0
ファイル: ccz.py プロジェクト: adelapie/sboxU
def delta_rank(f):
    """Returns the Gamma-rank of the function with LUT f.

    The Gamma-rank is the rank of the 2^{2n} \times 2^{2n} binary
    matrix M defined by

    M[x][y] = 1 if and only if x + y \in \Delta,

    where \Delta is defined as

    \Delta = \{ (a, b), DDT_f[a][b] == 2  \} ~.

    """
    n = int(log(len(f), 2))
    dim = 2**(2 * n)
    d = ddt(f)
    gamma = [(a << n) | b
             for a, b in itertools.product(xrange(1, 2**n), xrange(0, 2**n))
             if d[a][b] == 2]
    mat_content = []
    for x in xrange(0, dim):
        row = [0 for j in xrange(0, dim)]
        for y in gamma:
            row[oplus(x, y)] = 1
        mat_content.append(row)
    mat_gf2 = Matrix(GF(2), dim, dim, mat_content)
    return mat_gf2.rank()
コード例 #4
0
ファイル: T0T1T2.py プロジェクト: JohnCremona/CremonaPacetti
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
コード例 #5
0
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
コード例 #6
0
def get_ccz_equivalent_permutation(l, v0, v1, verbose=False):
    N = int(log(len(l), 2))
    mask = sum(int(1 << i) for i in xrange(0, N))
    L = v0 + v1
    L = Matrix(GF(2), 2 * N, 2 * N, [tobin(x, 2 * N) for x in L]).transpose()
    if verbose:
        print "\n\nrank={}\n{}".format(L.rank(), L.str())
    new_l = [[0 for b in xrange(0, 2**N)] for a in xrange(0, 2**N)]
    for a, b in itertools.product(xrange(0, 2**N), xrange(0, 2**N)):
        v = apply_bin_mat((a << N) | b, L)
        a_prime, b_prime = v >> N, v & mask
        new_l[a][b] = l[a_prime][b_prime]
    return invert_lat(new_l)
コード例 #7
0
def rand_linear_permutation(n, density=0.5):
    """Returns the matrix representation of a linear permutation of
    {0,1}^n.

    This is done by generating random n x n binary matrices until one
    with full rank is found. As a random binary matrix has full rank
    with probability more than 1/2, this method is fine.

    """
    while True:
        result = [[0 for j in xrange(0, n)] for i in xrange(0, n)]
        for i, j in itertools.product(xrange(0, n), repeat=2):
            if random.random() < density:
                result[i][j] = 1
        result = Matrix(GF(2), n, n, result)
        if result.rank() == n:
            return result
コード例 #8
0
ファイル: ccz.py プロジェクト: adelapie/sboxU
def gamma_rank(f):
    """Returns the Gamma-rank of the function with LUT f.

    The Gamma-rank is the rank of the 2^{2n} \times 2^{2n} binary
    matrix M defined by

    M[x][y] = 1 if and only if x + y \in \Gamma,

    where \Gamma is the codebook of f, i.e.

    \Gamma = \{ (x, f(x)), x \in \F_2^n  \} ~.

    """
    n = int(log(len(f), 2))
    dim = 2**(2 * n)
    gamma = [(x << n) | f[x] for x in xrange(0, 2**n)]
    mat_content = []
    for x in xrange(0, dim):
        row = [0 for j in xrange(0, dim)]
        for y in gamma:
            row[oplus(x, y)] = 1
        mat_content.append(row)
    mat_gf2 = Matrix(GF(2), dim, dim, mat_content)
    return mat_gf2.rank()
コード例 #9
0
ファイル: T0T1T2.py プロジェクト: JohnCremona/CremonaPacetti
def algo64(K, S, BB, T2=None, unit_first = True, verbose=False):
   r = 1+len(S)
   if T2 is None:
      T2 = get_T2(QQ,S, unit_first)
      if verbose:
         print("T2 = {}".format(T2))
   assert len(T2)==r*(r+1)//2

   from KSp import IdealGenerator
   Sx = [IdealGenerator(P) for P in S]
   u = -1 if K==QQ else  K(K.unit_group().torsion_generator())
   Sx = [u] + Sx if unit_first else Sx+[u]
   if verbose:
      print("Basis for K(S,2): {}".format(Sx))

   #BBdict = dict((k,BB(T2[k])) for k in T2)
   ap = BB_trace(BB)
   apdict = dict((k,ap(T2[k])) for k in T2)
   t4 = BB_t4(BB)
   t4dict = dict((k,t4(T2[k])) for k in T2)
   if verbose:
      print("apdict = {}".format(apdict))
      print("t4dict = {}".format(t4dict))

   v = vector(GF(2),[t4dict[Set([i])] for i in range(r)])
   if verbose:
      print("v = {}".format(v))

   def w(i,j):
      if i==j:
         return 0
      else:
         return (t4dict[Set([i,j])] + t4dict[Set([i])] + t4dict[Set([j])])

   # Note that W ignores the first coordinate
   Wd = Matrix(GF(2),[[w(i,j) for j in range(1,r)] for i in range(1,r)])
   vd = vector(v.list()[1:])
   rkWd = Wd.rank()
   if verbose:
      print("W' = \n{} with rank {}".format(Wd,rkWd))
   # Case 1: rank(W)=2
   if rkWd==2:
      # x' and y' are any two distinct nonzero rows of W
      Wrows = [wr for wr in Wd.rows() if wr]
      xd = Wrows[0]
      yd = next(wr for wr in Wrows if wr!=xd)
      zd = xd+yd
      ud = vd - vector(xi*yi for xi,yi in zip(list(xd),list(yd)))
      if verbose:
         print("x' = {}".format(xd))
         print("y' = {}".format(yd))
         print("z' = {}".format(zd))
         print("u' = {}".format(ud))
         print("v' = {}".format(vd))

      u = vector([1]+ud.list())
      v = vector([0]+vd.list())

      if t4dict[Set([0])]==1:
         x = vector([1]+xd.list())
         y = vector([1]+yd.list())
         z = vector([1]+zd.list())
         if verbose:
            print("x = {}".format(x))
            print("y = {}".format(y))
            print("z = {}".format(z))
            print("u = {}".format(u))
            print("v = {}".format(v))
      else:
         raise NotImplementedError("t_4(p_1) case not yet implemented in algo64")

      return [vec_to_disc(Sx,vec) for vec in [u,x,y,z]]

   # W==0
   raise NotImplementedError("rank(W)=0 case not yet implemented in algo64")
コード例 #10
0
ファイル: T0T1T2.py プロジェクト: JohnCremona/CremonaPacetti
def algo63(K, S, BB, T2=None, unit_first = True, verbose=False):
   r = 1+len(S)
   if T2 is None:
      T2 = get_T2(QQ,S, unit_first)
      if verbose:
         print("T2 = {}".format(T2))
   assert len(T2)==r*(r+1)//2

   from KSp import IdealGenerator
   Sx = [IdealGenerator(P) for P in S]
   u = -1 if K==QQ else  K(K.unit_group().torsion_generator())
   Sx = [u] + Sx if unit_first else Sx+[u]
   if verbose:
      print("Basis for K(S,2): {}".format(Sx))

   BBdict = dict((k,BB(T2[k])) for k in T2)
   ap = BB_trace(BB)
   apdict = dict((k,ap(T2[k])) for k in T2)
   t2 = BB_t2(BB)
   t2dict = dict((k,t2(T2[k])) for k in T2)
   if verbose:
      print("apdict = {}".format(apdict))
      print("t2dict = {}".format(t2dict))

   v = vector(GF(2),[t2dict[Set([i])] for i in range(r)])
   if verbose:
      print("v = {}".format(v))

   def w(i,j):
      if i==j:
         return 0
      else:
         return (t2dict[Set([i,j])] + t2dict[Set([i])] + t2dict[Set([j])])

   W = Matrix(GF(2),[[w(i,j) for j in range(r)] for i in range(r)])
   rkW = W.rank()
   if verbose:
      print("W = \n{} with rank {}".format(W,rkW))
   # Case 1: rank(W)=2
   if rkW==2:
      # x and y are any two distinct nonzero rows of W
      Wrows = [wr for wr in W.rows() if wr]
      x = Wrows[0]
      y = next(wr for wr in Wrows if wr!=x)
      z = x+y
      u = v - vector(xi*yi for xi,yi in zip(list(x),list(y)))
      if verbose:
         print("x = {}".format(x))
         print("y = {}".format(y))
         print("z = {}".format(z))
         print("u = {}".format(u))
   else: # W==0
      # y=0, x=z
      u = v
      y = u-u # zero vector
      if verbose:
         print("u = {}".format(u))
         print("y = {}".format(y))
      t3dict = {}
      for k in T2:
         t = 1 if t2dict[k]==0 else -1
         t3dict[k] = (BBdict[k](t)//8)%2
      s = solve_vectors(r,t3dict)
      if not s:
         z = x = y # = 0
         if verbose:
            print("x and  y are both zero, so class has >4 vertices")
      else:
         x, _ = s
         z = x
         if verbose:
            print("x = {}".format(x))
            print("y = {}".format(y))
            print("z = {}".format(z))

   return [vec_to_disc(Sx,vec) for vec in [u,x,y,z]]