Ejemplo n.º 1
0
    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.n, s1.m
        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,
                Bin.concat(Bin(1, 1) + Bin(x, inp) + Bin(s1[x], out)).tuple)
            M2.set_column(
                x,
                Bin.concat(Bin(1, 1) + Bin(x, inp) + Bin(s2[x], out)).tuple)

        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)
Ejemplo n.º 2
0
    def as_matrix(self):
        assert self.is_linear()

        m = matrix(GF(2), self.output_size(), self.input_size())
        for e in range(self.input_size()):
            vec = Bin(self[2**e], self.output_size()).tuple
            m.set_column(self.input_size() - 1 - e, vec)
        return m
Ejemplo n.º 3
0
    def __init__(self, *args):
        self.matrix = matrix(*args)
        assert self.matrix.base_ring() in (ZZ, QQ)
        self.n = self.matrix.nrows()
        self.m = self.matrix.ncols()

        # bounds are relative
        self.set_bounds((1, ) * self.matrix.ncols())
Ejemplo n.º 4
0
 def difference_distribution_table(self, zero_zero=True):
     ddt = matrix(ZZ, 2**self.output_size(), 2**self.input_size())
     for x in self.input_range():
         for dx in self.input_range()[1:]:
             dy = self[x] ^ self[x ^ dx]
             ddt[dx, dy] += 1
     if zero_zero:
         ddt[0, 0] = 0
     return ddt
Ejemplo n.º 5
0
def mat_field_mul_const(field, c):
    assert field.base_ring() == GF(2)
    d = field.degree()
    m = matrix(GF(2), d, d)
    for i, e in enumerate(reversed(range(d))):
        x = 1 << e
        res = field.fetch_int(x) * field.fetch_int(c)
        res = res.integer_representation()
        m.set_column(i, Bin(res, d).tuple)
    return m
Ejemplo n.º 6
0
 def xor_add_ddt(self):
     axddt = matrix(ZZ, self.insize, self.outsize)
     for x in range(self.insize):
         for dx in range(1, self.insize):
             x2 = x ^ dx
             y = self[x]
             y2 = self[x2]
             dy = (y2 - y) % self.outsize
             axddt[dx, dy] += 1
     return axddt
Ejemplo n.º 7
0
 def add_add_ddt(self):
     addt = matrix(ZZ, self.insize, self.outsize)
     for x in range(self.insize):
         for dx in range(1, self.insize):
             x2 = (x + dx) % self.insize
             y = self[x]
             y2 = self[x2]
             dy = (y2 - y) % self.outsize
             addt[dx, dy] += 1
     return addt
Ejemplo n.º 8
0
 def add_xor_ddt(self):
     axddt = matrix(ZZ, self.insize, self.outsize)
     for x in range(self.insize):
         for dx in range(1, self.insize):
             x2 = (x + dx) % self.insize
             y = self[x]
             y2 = self[x2]
             dy = y ^ y2
             axddt[dx, dy] += 1
     return axddt
Ejemplo n.º 9
0
 def linear_approximation_table(self, zero_zero=True):
     lat = matrix(ZZ, 2**self.input_size(), 2**self.output_size(), [
         self.component(mask).to_sage_BF().walsh_hadamard_transform()
         for mask in self.output_range()
     ]).transpose()
     if zero_zero:
         lat[0, 0] = 0
     if abs:
         lat = lat.apply_map(abs)
     return lat
Ejemplo n.º 10
0
 def kddt(self, k=3, zero_zero=False):
     kddt = matrix(ZZ, self.insize, self.outsize)
     for xs in Combinations(range(self.insize), k):
         ys = map(self, xs)
         dx = reduce(lambda a, b: a ^ b, xs)
         dy = reduce(lambda a, b: a ^ b, ys)
         kddt[dx, dy] += 1
     if zero_zero:
         kddt[0, 0] = 0
     return kddt
Ejemplo n.º 11
0
 def as_table(self, height=None, width=None):
     assert (width is None) ^ (height is None)
     if width is not None:
         height = self.input_size() // width
     else:
         width = self.input_size() // height
     assert height * width == self.input_size()
     m = matrix(ZZ, height, width)
     for x, y in self.graph():
         m[divmod(x, width)] = y
     return m
Ejemplo n.º 12
0
 def hdim(self, right_to_left=False):
     """
     hdim[i,j] = i-th output bit contains monomial x1...xn/xj
     """
     res = matrix(GF(2), self.in_bits, self.out_bits)
     anf = mobius(tuple(self))
     for j in range(self.in_bits):
         mask = (1 << self.in_bits) - 1
         mask ^= 1 << (self.in_bits - 1 - j)
         res.set_column(j, Bin(anf[mask], self.out_bits).tuple)
     if right_to_left:
         res = res[::-1, ::-1]
     return res
Ejemplo n.º 13
0
 def cmul_xor_ddt(self, F=None):
     if F is None:
         F = GF(self.insize, name='a')
     cxddt = matrix(ZZ, self.insize, self.outsize)
     for x in range(1, self.insize):
         for dx in range(2, self.insize):
             x2 = (F.fetch_int(x) *
                   F.fetch_int(dx)).integer_representation()
             y = self[x]
             y2 = self[x2]
             dy = y2 ^ y
             cxddt[dx, dy] += 1
     return cxddt
Ejemplo n.º 14
0
 def minilat(self, abs=False):
     """LAT taken on a basis points"""
     res = matrix(ZZ, self.m, self.n)
     for eu in range(self.m):
         for ev in range(self.n):
             u = Integer(2**eu)
             v = Integer(2**ev)
             for x in range(2**self.m):
                 res[eu, ev] += ((u & x).popcount()
                                 & 1 == (v & self[x]).popcount() & 1)
     if abs:
         res = res.apply_map(_abs)
     return res
Ejemplo n.º 15
0
 def xor_cmul_ddt(self, F=None):
     if F is None:
         F = GF(self.insize, name='a')
     xcddt = matrix(ZZ, self.insize, self.outsize)
     for x in range(self.insize):
         for dx in range(1, self.insize):
             x2 = x ^ dx
             y = self[x]
             y2 = self[x2]
             dy = (F.fetch_int(y2) * F.fetch_int(y)
                   **(self.outsize - 2)).integer_representation()
             xcddt[dx, dy] += 1
     return xcddt
Ejemplo n.º 16
0
def matrix_is_mds(mat):
    """@mat is considered as operator M*x"""
    n = mat.ncols()
    m = mat.nrows()

    mat2 = matrix(mat.base_ring(), m * 2, n)
    mat2[:m, :n] = identity_matrix(mat.base_ring(), m, n)
    mat2[m:, :n] = mat

    # linear code: x -> (x || M*x)
    C = LinearCode(mat2.transpose())
    D = C.minimum_distance()
    K = n
    N = 2 * m

    # Singleton bound
    # MDS on equality
    assert D <= N - K + 1
    return D == N - K + 1
Ejemplo n.º 17
0
    def __init__(self, oracle, n_in, field=F2, ntests=10):
        self.oracle = oracle
        self.field = field
        self.n_in = int(n_in)

        self.zero = vector(field, oracle([0] * n_in))
        self.n_out = len(self.zero)
        cols = []
        for i in range(n_in):
            x = [0] * n_in
            x[i] = 1
            y = vector(field, oracle(x)) - self.zero
            cols.append(y)

        self.matrix = matrix(field, cols).transpose()
        self._kernel = None

        self.rank = self.matrix.rank()
        self.kernel_dimension = self.matrix.ncols() - self.rank

        self.test_oracle(ntests)
Ejemplo n.º 18
0
def mat_from_linear_func(m, n, func):
    mat = matrix(GF(2), n, m)
    for i, e in enumerate(reversed(range(m))):
        x = 1 << e
        mat.set_column(i, Bin(func(x), n).tuple)
    return mat
Ejemplo n.º 19
0
def random_permutation_matrix(field, n):
    rows = list(identity_matrix(n))
    shuffle(rows)
    return matrix(field, rows)
Ejemplo n.º 20
0
Archivo: perm.py Proyecto: hellman/cry
 def to_matrix(self, field=F2):
     m = matrix(Permutation([v + 1 for v in self.p]))
     m = m.transpose().change_ring(field)
     return m