Ejemplo n.º 1
0
Archivo: codes.py Proyecto: agrrr/pycpc
    def __init__(self, k, r, gen: list = None):
        super().__init__(k, r, name='ADR')

        if gen is None:
            self.F = ffield.FField(r)
        else:
            if not isinstance(gen, list) or len(
                    gen) != r + 1 or gen.count(0) + gen.count(1) != len(gen):
                raise Exception('generator polynom error')
            gen = binlist2int(gen)
            self.F = ffield.FField(r, gen, useLUT=0)  # create GF(2^r)
Ejemplo n.º 2
0
Archivo: codes.py Proyecto: agrrr/pycpc
 def __init__(self, k: int, r: int, gen: list = None):
     super().__init__(k=k, r=r, name='TS')
     s = (k / r - 1) / 2.0
     if int(s) != s:
         raise Exception('TS parameters error: k != (2*s+1)*r')
     self.s = int(s)  # convert double to int.
     if gen is None:
         self.F = ffield.FField(r)
     else:
         if not isinstance(gen, list) or len(
                 gen) != r + 1 or gen.count(0) + gen.count(1) != len(gen):
             raise Exception('generator polynom error')
         gen = binlist2int(gen)
         self.F = ffield.FField(r, gen, useLUT=0)  # create GF(2^r)
Ejemplo n.º 3
0
def reconstruct_secret_cheating(shares_f, shares_g, degree, field_base=8):
    '''
    :param shares: shares. eg. shares = ['52-4cb1787cc758426bc82aebb44050', 'e1-31770e32acb4091ca4e43c000316', 'e2-078f51a8d8e4f2f2b2b00529de62']
    :param degree: the degree of the polynomial
    :param field_base: usually 8
    :return: return the original secret in string or give a cheating notification
    '''
    F = ffield.FField(field_base)
    if len(shares_f) <= degree or len(shares_g) <= degree:
        raise ValueError("The number of shares must be ")
    if len(shares_f) != len(shares_g):
        raise ValueError("Please enter equal number of shares from f and g")
    xy_value_f = get_points(shares_f)
    x_values_f = xy_value_f[0]
    xy_value_g = get_points(shares_g)
    x_values_g = xy_value_g[0]
    secret = ''
    for i in range(1, len(xy_value_f)):
        y_values_f = xy_value_f[i]
        y_values_g = xy_value_g[i]
        s_f, a1_f = lagrange_interpolation_getcoefficients([x_values_f, y_values_f], field_base)
        s_g, a1_g = lagrange_interpolation_getcoefficients([x_values_g, y_values_g], field_base)
        secret += chr(s_f)
    for r in range (2**field_base):
        test1 = F.Add(s_g, F.Multiply(s_f, r))
        test2 = F.Add(a1_g, F.Multiply(a1_f, r))
        if test1 == 0 and test2 == 0:
            print("No cheating detected!")
            return secret
    print ("Cheating detected!")
    return 0
Ejemplo n.º 4
0
 def __init__(self, n, p):
     self.coeff_table = list()
     self.dig_table = list()
     self.cyclomatic_classes = list()
     self.m = int(math.log(n, 2)) + 1
     self.size = 2 ** self.m - 1
     self.p = p
     #self.entropy = (-1) * p * math.log2(p) + (-1) * (1 - p) * math.log2(1 - p)
     self.entropy = (-1) * p * math.log(p, 2) + (-1) * (1.0 - p) * math.log(1.0 - p, 2)
     self.r = int(self.size * self.entropy) + 1
     self.k = self.size - self.r
     self.d = self.calculate_dist()
     self.t = (self.d - 1) // 2
     self.F = ffield.FField(self.m)
     one = 1
     self.dig_table.append(one)
     self.coeff_table.append(list(self.F.ShowCoefficients(one)))
     alpha = 2
     self.coeff_table.append(list(self.F.ShowCoefficients(alpha)))
     self.dig_table.append(alpha)
     beta = alpha
     for i in range(2, self.size + 1):
         beta = self.F.Multiply(alpha, beta)
         self.dig_table.append(beta)
         self.coeff_table.append(list(self.F.ShowCoefficients(beta)))
     self.create_cyclomatic_classes()
     self.gen_poly = self.create_generate_poly(self.t)
     self.verify_poly = self.create_verify_poly()
     return
Ejemplo n.º 5
0
def lagrange_interpolation_getcoefficients(points, field_base=8):
    '''
    :param points: a list of two lists. the first list element is the list of x values, the second list element is the list of y values
    :param field_base: base of the field. usually 8
    :return: a0, a1, a0 is the constant term of polynomial g(x), while a1 is the coefficient of x in polynomial g(x)
    '''
    x_values, y_values = points
    F = ffield.FField(field_base)
    a1 = 0
    a0 = 0
    for i in range(len(x_values)):
        a1_numerator, denominator = 0, 1
        a0_numerator= 1
        for j in range(len(x_values)):
            if i == j:
                continue
            a1_numerator = F.Add(a0_numerator, F.Multiply(a1_numerator, F.Subtract(0, x_values[j])))
            a0_numerator = F.Multiply(a0_numerator, F.Subtract(0, x_values[j]))
            denominator = F.Multiply(denominator, F.Subtract(x_values[i], x_values[j]))

        lagrange_polynomial_a0 = F.Multiply(a0_numerator, F.Inverse(denominator))
        lagrange_polynomial_a1 = F.Multiply(a1_numerator, F.Inverse(denominator))
        a0 = F.Add(a0, F.Multiply(y_values[i], lagrange_polynomial_a0))
        a1 = F.Add(a1, F.Multiply(y_values[i], lagrange_polynomial_a1))

    return a0, a1
Ejemplo n.º 6
0
 def __init__(self, n=3, u=1, alphabet=alphabet1):
     self.n = 3
     self.Field = ffield.FField(n)  #Galois Field GF(2^n)
     self.array = [[
         alphabet[self.Field.Add(self.Field.Multiply(u, i), 2**n - 1 - j)]
         for j in range(2**n)
     ] for i in range(2**n)]
Ejemplo n.º 7
0
def asyl(A, B, m, c, x1=0, y1=0):
    "tries to find an invertible solution to the equation AX = YB"
    "m is field size, c is subgroup "
    F = ffield.FField(m)
    n = A.shape[0]
    a, null = asylmat(A, B, m, c, x1, y1)
    if a == 0:
        return "no solution"
    f = lambda i: null[i][:n**2]
    g = lambda i: null[i][n**2:]
    for cnt in range(50):
        ran1 = np.zeros((n, n), dtype=int)
        ran2 = np.zeros((n, n), dtype=int)
        for j in range(a):
            c = np.random.randint(0, 2**m)
            for i in range(n):
                for k in range(n):
                    ran1[i][k] = F.Add(ran1[i][k],
                                       F.Multiply(c,
                                                  f(j)[i * n + k]))
                    ran2[i][k] = F.Add(ran2[i][k],
                                       F.Multiply(c,
                                                  g(j)[i * n + k]))
        if invble(ran1, m) and invble(ran2, m):
            return ran1, ran2
    return "no invertible solution"
Ejemplo n.º 8
0
def smul(x, A, m):
    "scalar matrix multiplication"
    F = ffield.FField(m)
    n, m = A.shape
    B = np.zeros((n, m), dtype=int)
    for i in range(n):
        for j in range(m):
            B[i][j] = F.Multiply(A[i][j], x)
    return B
Ejemplo n.º 9
0
def testEvaluations(n: int, l: int, mode: str, R=None, omit_zero=True):
    """
        n: The number of vertices in the complete graph in question
        l: F_2^l is the field we're working with


        Returns and prints the fraction of assignments over F_2^l to the
        edges of the complete graph K_n that yield a nonzero output. 
    """
    m = n**2  #edges
    q = 2**l  #field size
    K = q**m
    F = ffield.FField(l)

    zero_count = 0
    """
        K is an ml bit number. We want to split it up into l bit parts
        To do this, we pick a K, get just the last l bits by taking the AND with 
        q-1 (which is l 1's) and then rightshifting to get the next l bits. 
    """

    #Idea - precompute all the possible relevant monomial values and store them.
    #Idea - do changes to the unvisited set using sortedcontainers

    if mode == "random":
        assert (R is not None)
        for X in randomAssignments(n, l, R, omit_zero):
            evaluation = 0
            for perm in permutations(list(range(1, n))):
                monomial = X[0, perm[0]]
                vtx = 0
                for i in range(n - 1):
                    monomial = F.Multiply(monomial, X[vtx, perm[i]])
                    vtx = perm[i]
                monomial = F.Multiply(monomial, X[perm[n - 2], 0])
                evaluation = F.Add(monomial, evaluation)
            if evaluation == 0:
                zero_count += 1
        print("When n = ", n, "and l = ", l, "the fraction of nonzeros was: ",
              1 - float(zero_count) / R)

    else:
        for X in bruteForceAssignments(n, l):
            evaluation = 0
            for perm in permutations(list(range(1, n))):
                monomial = X[0, perm[0]]
                vtx = 0
                for i in range(n - 1):
                    monomial = F.Multiply(monomial, X[vtx, perm[i]])
                    vtx = perm[i]
                monomial = F.Multiply(monomial, X[perm[n - 2], 0])
                evaluation = F.Add(monomial, evaluation)
            if evaluation == 0:
                zero_count += 1
        print("When n = ", n, "and l = ", l, "the fraction of nonzeros was: ",
              1 - float(zero_count) / K)
Ejemplo n.º 10
0
 def __init__(self, plainTxt, key, printMode=OFF):
     self.plainTxt = plainTxt
     self.key = key
     self.state = FField(plainTxt)
     self.printMode = printMode
     self.currentRound = 10
     self.f = ffield.FField(8, gen=0x11B, useLUT=0)
     print("***********************************************\n" +
           f"Decrypting: {plainTxt}\n" + f"Using Key : {key}\n" +
           "***********************************************")
     self.go()
def calculate_g_shares(x_value, g_coefficients, field_base):
    '''
    This function aims to generate the y value corresponding to the x value in polynomial g(x)
    '''
    #print ("g_coefficients[0]:", g_coefficients[0])
    F = ffield.FField(field_base)
    result = 0
    for i in reversed(range(1, len(g_coefficients) - 1)):
        result = F.Add(F.Multiply(result, x_value), g_coefficients[i])

    result = F.Add(F.Multiply(result, x_value), g_coefficients[0])
    return result
Ejemplo n.º 12
0
def multiply_galois_64(a: int, b: int):
    """
    Multiplies a and b in a Galois Field of 2^64
    :param a:
    :param b:
    :return:
    """
    galois_128 = ffield.FField(
        64, 2**64 + 2**63 + 2**62 + 2**60 + 2**59 + 2**57 + 2**54 + 2**53 +
        2**52 + 2**51 + 2**46 + 2**44 + 2**43 + 2**42 + 2**41 + 2**40 + 2**39 +
        2**38 + 2**34 + 2**31 + 2**0)
    return galois_128.Multiply(a, b)
Ejemplo n.º 13
0
    def __init__(self, key, legacy=False):
        """Met en place un moyen de chiffrement."""

        # Le polynôme "x^5 + x^2 + 1" est celui par défaut
        self._f = ffield.FField(5)

        assert (key.get_size() == 64)

        self._key = key
        self._iterations = 6

        self.encrypt_one_block = self.encrypt_one_block_legacy if legacy else encrypt_one_block_native
Ejemplo n.º 14
0
Archivo: codes.py Proyecto: agrrr/pycpc
 def __init__(self, k: int, r: int, pv: bitarray = None, gen: list = None):
     """
     pv: Punching vector. len(P)=k, w(P)=r
     gen: generating polynomial in binary vector form.
     """
     super().__init__(k=k, r=r, name='PC')
     if pv is None:
         pv = bitarray([0 for _ in range(k - r)] + [1 for _ in range(r)])
     if pv.count(1) != r or pv.count(0) != k - r:
         raise Exception(
             '{pv} can not be used as punching vector (k={k}, r={r})'.
             format(pv=pv, k=k, r=r))
     self.PV = pv
     if gen is None:
         self.F = ffield.FField(k)
     else:
         if not isinstance(gen, list) or len(
                 gen) != k + 1 or gen.count(0) + gen.count(1) != len(gen):
             raise Exception('generator polynom error')
         gen = binlist2int(gen)
         self.F = ffield.FField(k, gen, useLUT=0)  # create GF(2^k)
Ejemplo n.º 15
0
    def __init__(self):
        self.field = ffield.FField(163)
        self.a = ffield.FElement(self.field, 1)
        self.b = ffield.FElement(
            self.field, 0x000000020A601907B8C953CA1481EB10512F78744A3205FD)

        self.n = 0x000000040000000000000000000292FE77E70C12A4234C33
        self.h = 2

        self.curve_points = self.n * self.h

        self.g = Point(self, False,
                       0x3f0eba16286a2d57ea0991168d4994637e8343e36,
                       0x0d51fbc6c71a0094fa2cdd545b11c5c0c797324f1)
Ejemplo n.º 16
0
def experiment_4_3(n, m):
    F = ffield.FField(m)
    M1 = ran(n, m, "G")
    M2 = ran(n, m, "G")
    M3 = ran(n, m, "G")
    M4 = ran(n, m, "G")
    M5 = ran(n, m, "G")
    M6 = ran(n, m, "G")
    a0 = conj(ran(n, m, "D"), M1, m)
    a1 = conj(ran(n, m, "D"), M2, m)
    a2 = conj(ran(n, m, "D"), M3, m)
    b1 = conj(ran(n, m, "D"), M4, m)
    b2 = conj(ran(n, m, "D"), M5, m)
    b3 = conj(ran(n, m, "D"), M6, m)
    x0 = ran(n, m, "G")
    x1 = conj(ran(n, m, "D"), M4, m)
    x2 = conj(ran(n, m, "D"), M5, m)
    x3 = conj(ran(n, m, "D"), M6, m)
    y0 = conj(ran(n, m, "D"), M1, m)
    y1 = conj(ran(n, m, "D"), M2, m)
    y2 = conj(ran(n, m, "D"), M3, m)
    y3 = ran(n, m, "G")
    p = longmul([inv(y0, m), b1, y1], m)
    cnt = 0
    for n1 in range(1, 2**m):
        for n2 in range(1, 2**m):
            C = np.zeros((n**2, n**2), dtype=int)
            for i in range(n):
                for j in range(n):
                    for k in range(n):
                        C[i * n + j][k] = F.Multiply(
                            mul(M1, inv(M4, m), m)[i][k],
                            mul(M4, inv(M2, m), m)[k][j])
            for j in range(n):
                C[0 * n + j][n + j] = F.Multiply(
                    n1,
                    longmul([M1, p, inv(M2, m)], m)[i][j])
                C[1 * n + j][n + j] = F.Multiply(
                    n2,
                    longmul([M1, p, inv(M2, m)], m)[i][j])
            for i in range(2, n):
                for j in range(n):
                    C[i * n + j][i * n + j] = longmul(
                        [M1, p, inv(M2, m)], m)[i][j]
            d = ns(C, m).shape[0]
            if d > 1:
                return False
            cnt += d
    return cnt
Ejemplo n.º 17
0
def mul(A, B, m):
    "finite-field multiplication"
    F = ffield.FField(m)
    n1, m1 = A.shape
    n2, m2 = B.shape
    if m1 != n2:
        return "incompatible dimensions"
    C = np.zeros((n1, m2), dtype=int)
    for i in range(n1):
        for j in range(m2):
            cnt = 0
            for k in range(m1):
                cnt = F.Add(cnt, F.Multiply(A[i][k], B[k][j]))
            C[i][j] = cnt
    return C
Ejemplo n.º 18
0
 def create_finite_field(self):
     self.coeff_table = list()
     self.dig_table = list()
     self.F = ffield.FField(self.m)
     one = 1
     self.dig_table.append(one)
     self.coeff_table.append(list(self.F.ShowCoefficients(one)))
     alpha = 2
     self.coeff_table.append(list(self.F.ShowCoefficients(alpha)))
     self.dig_table.append(alpha)
     beta = alpha
     for i in range(2, self.size + 1):
         beta = self.F.Multiply(alpha, beta)
         self.dig_table.append(beta)
         self.coeff_table.append(list(self.F.ShowCoefficients(beta)))
     return
Ejemplo n.º 19
0
def reshape_as_matrix(input_state):
    # define GF(2^8) (i.e., GF(256)) field
    F = ffield.FField(8)

    # define a matrix in GF(256)
    output_matrix = genericmatrix.GenericMatrix(size=(4, 4),
                                                add=F.Add,
                                                sub=F.Subtract,
                                                mul=F.Multiply,
                                                div=F.Divide)

    # add the corresponding elements from the input_state to the matrix
    for i in range(4):
        output_matrix.SetRow(i, input_state[i * 4:(i * 4) + 4])

    return output_matrix
Ejemplo n.º 20
0
def calculate_shares(x_value, coefficients, secret, field_base=8):
    """
    :param x_value: the x value
    :param coefficients: coefficients of the polynomial, coefficient[i] is the coefficient of x^(i+1)
    :param field_base: field base
    :param secret: the character secret
    :return: return the y value correspond to the x value
    """
    F = ffield.FField(field_base)
    s0 = ord(secret)
    result = 0
    for i in reversed(range(len(coefficients))):
        result = F.Add(F.Multiply(result, x_value), coefficients[i])

    result = F.Add(F.Multiply(result, x_value), s0)
    return result
Ejemplo n.º 21
0
    def __init__(self, bit_length: int = 16, fn_poly: str = 'polynomial.txt'):
        self.irr_polys_8 = [
            2**8 + 2**4 + 2**3 + 2**2 + 2**0, 2**8 + 2**5 + 2**3 + 2**1 + 2**0,
            2**8 + 2**6 + 2**4 + 2**3 + 2**2 + 2**1 + 2**0,
            2**8 + 2**6 + 2**5 + 2**1 + 2**0, 2**8 + 2**6 + 2**5 + 2**2 + 2**0,
            2**8 + 2**6 + 2**5 + 2**3 + 2**0, 2**8 + 2**7 + 2**6 + 2**1 + 2**0,
            2**8 + 2**7 + 2**6 + 2**5 + 2**2 + 2**1 + 2**0
        ]

        self.irr_polys_16 = [
            2**16 + 2**9 + 2**8 + 2**7 + 2**6 + 2**4 + 2**3 + 2**2 + 2**0,
            2**16 + 2**12 + 2**3 + 2**1 + 2**0,
            2**16 + 2**12 + 2**7 + 2**2 + 2**0,
            2**16 + 2**13 + 2**12 + 2**10 + 2**9 + 2**7 + 2**6 + 2**1 + 2**0,
            2**16 + 2**13 + 2**12 + 2**11 + 2**7 + 2**6 + 2**3 + 2**1 + 2**0,
            2**16 + 2**13 + 2**12 + 2**11 + 2**10 + 2**6 + 2**2 + 2**1 + 2**0,
            2**16 + 2**14 + 2**10 + 2**8 + 2**3 + 2**1 + 2**0,
            2**16 + 2**14 + 2**13 + 2**12 + 2**6 + 2**5 + 2**3 + 2**2 + 2**0,
            2**16 + 2**14 + 2**13 + 2**12 + 2**10 + 2**7 + 2**0,
            2**16 + 2**15 + 2**10 + 2**6 + 2**5 + 2**3 + 2**2 + 2**1 + 2**0,
            2**16 + 2**15 + 2**11 + 2**9 + 2**8 + 2**7 + 2**5 + 2**4 + 2**2 +
            2**1 + 2**0, 2**16 + 2**15 + 2**11 + 2**10 + 2**7 + 2**6 + 2**5 +
            2**3 + 2**2 + 2**1 + 2**0, 2**16 + 2**15 + 2**11 + 2**10 + 2**9 +
            2**6 + 2**2 + 2**1 + 2**0, 2**16 + 2**15 + 2**11 + 2**10 + 2**9 +
            2**8 + 2**6 + 2**4 + 2**2 + 2**1 + 2**0
        ]
        self.polynomial = 0
        self.generator = 0
        self.bit_length = bit_length
        self.path_poly = path.join(
            path.join(path.abspath(path.dirname(__file__)), '../../data/'),
            fn_poly)
        self.galois_field = None

        if path.exists(self.path_poly):
            # Open previously written polynomial setting
            with open(self.path_poly, 'r') as file_poly:
                line_elems = file_poly.readline().split(' ')
                if int(line_elems[0]) == self.bit_length:
                    self.polynomial = int(line_elems[1])
                    self.generator = int(line_elems[2])
                    self.galois_field = ffield.FField(self.bit_length,
                                                      self.polynomial)

        if self.polynomial == 0:
            self.__generate_polynomial()
Ejemplo n.º 22
0
    def __generate_polynomial(self):
        """ Generates a generator element in the polynomial """

        power = 0
        res = 1

        # Select a random generator possibility
        # primes_field, _ = _prime_factorize(2 ** self.bit_length - 1)
        # possibilities = _products(primes_field)
        possibilities = [i for i in range(2, 2**self.bit_length - 1)]

        # Select a random irreducible polynomial according to the degree
        if self.bit_length == 16:
            self.polynomial = self.irr_polys_16[random.randint(
                0,
                len(self.irr_polys_16) - 1)]
        elif self.bit_length == 8:
            self.polynomial = self.irr_polys_8[random.randint(
                0,
                len(self.irr_polys_8) - 1)]
        else:
            # TODO select an irreducible polynomial for degrees other than 16 (not required for now)
            print('Oups')

        self.galois_field = ffield.FField(self.bit_length, self.polynomial)
        while True:
            # Select one random polynomial to check if it is a generator
            elem = possibilities[random.randint(0, len(possibilities) - 1)]
            possibilities.remove(
                elem)  # Remove it from remaining possibilities

            for power in range(2**self.bit_length):
                res = self.galois_field.Multiply(res, elem)

                if res == 1:
                    break

            if power == (2**self.bit_length) - 2:  # Generator !!!
                break

        self.generator = elem

        with open(self.path_poly, 'w+') as file_poly:
            file_poly.write(
                str(self.bit_length) + ' ' + str(self.polynomial) + ' ' +
                str(self.generator))
Ejemplo n.º 23
0
def ffunction(x):
    x4 = []
    for i in range(4):
        x4.append((x >> (4 * (3 - i))) & 0xffff)

    F = ffield.FField(16)
    x4d = []
    for i in range(4):
        for k in range(4):
            sum = 0
            sum += F.Multiply(M[i][k], x4[k])
        x4d.append(sum)

    new_x = 0
    for i in range(4):
        new_x = new_x | (x4d[i] << (4 * (3 - i)))

    return new_x
Ejemplo n.º 24
0
 def old_init(self, size, m):
     self.coeff_table = list()
     self.dig_table = list()
     self.cyclomatic_classes = list()
     self.size = size
     self.m = m
     self.F = ffield.FField(self.m)
     one = 1
     self.dig_table.append(one)
     self.coeff_table.append(list(self.F.ShowCoefficients(one)))
     alpha = 2
     self.coeff_table.append(list(self.F.ShowCoefficients(alpha)))
     self.dig_table.append(alpha)
     beta = alpha
     for i in range(2, self.size + 1):
         beta = self.F.Multiply(alpha, beta)
         self.dig_table.append(beta)
         self.coeff_table.append(list(self.F.ShowCoefficients(beta)))
     self.create_cyclomatic_classes()
     return
Ejemplo n.º 25
0
def inv(Y, m):
    "finds inverse of a square matrix A over the finite field F(2^m)"
    A = copy.copy(Y)
    if ns(A, m).shape[0] != 0:  # nontrivial nullspace - not invertible!
        return "not invertible"
    F = ffield.FField(m)
    n = A.shape[0]
    X = np.zeros((n, n), dtype=int)
    for i in range(n):
        X[i][i] = 1
    for j in range(n):
        zeros = True
        for i in range(j, n):
            if zeros == True and A[i][j] != 0:
                B = copy.copy(A[i])
                B1 = copy.copy(X[i])
                C = copy.copy(A[j])
                C1 = copy.copy(X[j])
                A[i] = C
                A[j] = B
                X[i] = C1
                X[j] = B1
                zeros = False
        if A[j][j] != 0:
            B = copy.copy(A[j])
            B1 = copy.copy(X[j])
            for i in range(n):
                B[i] = F.Multiply(A[j][i], F.Inverse(A[j][j]))
                B1[i] = F.Multiply(X[j][i], F.Inverse(A[j][j]))
            A[j] = B
            X[j] = B1
            for i in range(n):
                if i != j:
                    B = copy.copy(A[i])
                    B1 = copy.copy(X[i])
                    for l in range(n):
                        B[l] = F.Add(A[i][l], F.Multiply(A[j][l], A[i][j]))
                        B1[l] = F.Add(X[i][l], F.Multiply(X[j][l], A[i][j]))
                    A[i] = B
                    X[i] = B1
    return X
Ejemplo n.º 26
0
def syl(A, B, m, c, x1=0, y1=0):
    "tries to find an invertible solution to the sylvester equation AX = XB"
    "m is field size, c is subgroup"
    F = ffield.FField(m)
    n = A.shape[0]
    a, null = sylmat(A, B, m, c, x1, y1)
    if a == 0:
        return "no solution"
    f = lambda i: null[i].reshape((n, n))
    for cnt in range(20):
        ran = np.zeros((n, n), dtype=int)
        for j in range(a):
            c = np.random.randint(0, 2**m)
            for i1 in range(n):
                for i2 in range(n):
                    ran[i1][i2] = F.Add(ran[i1][i2],
                                        F.Multiply(c,
                                                   f(j)[i1][i2]))
        if invble(ran, m):
            return ran
    return "no invertible solution"
Ejemplo n.º 27
0
def invert_matrix():
    field = ffield.FField(7, gen=0x83)
    matrix = genericmatrix.GenericMatrix(size=(8, 8),
                                         zeroElement=0,
                                         identityElement=1,
                                         add=field.Add,
                                         mul=field.Multiply,
                                         sub=field.Subtract,
                                         div=field.Divide)
    matrix.SetRow(0, [get_int_from_BV(i) for i in A_matrix[0]])
    matrix.SetRow(1, [get_int_from_BV(i) for i in A_matrix[1]])
    matrix.SetRow(2, [get_int_from_BV(i) for i in A_matrix[2]])
    matrix.SetRow(3, [get_int_from_BV(i) for i in A_matrix[3]])
    matrix.SetRow(4, [get_int_from_BV(i) for i in A_matrix[4]])
    matrix.SetRow(5, [get_int_from_BV(i) for i in A_matrix[5]])
    matrix.SetRow(6, [get_int_from_BV(i) for i in A_matrix[6]])
    matrix.SetRow(7, [get_int_from_BV(i) for i in A_matrix[7]])
    inverse = matrix.Inverse()
    for rownum in range(8):
        row = [bv(i) for i in inverse.GetRow(rownum)]
        A_Inverse.append(row)
Ejemplo n.º 28
0
def mix_column(input_state, mode):

    # define GF(2^8) (i.e., GF(256)) field
    F = ffield.FField(8)

    # depending on the mode of operation get the right mix_column matrix
    if mode == 'E':
        column_matrix = genericmatrix.GenericMatrix(size=(4, 4),
                                                    add=F.Add,
                                                    sub=F.Subtract,
                                                    mul=F.Multiply,
                                                    div=F.Divide)
        row = [2, 3, 1, 1]
        for i in range(4):
            column_matrix.SetRow(i, row)
            row = rotate(row, -1)

    elif mode == 'D':
        column_matrix = genericmatrix.GenericMatrix(size=(4, 4),
                                                    add=F.Add,
                                                    sub=F.Subtract,
                                                    mul=F.Multiply,
                                                    div=F.Divide)
        row = [14, 11, 13, 9]
        for i in range(4):
            column_matrix.SetRow(i, row)
            row = rotate(row, -1)
    else:
        raise ValueError('invalid mode of operation, mode = {0}'.format(mode))

    # convert input_state to input_matrix
    input_matrix = reshape_as_matrix(input_state)

    # perform matrix multiplication using * operator
    output_matrix = input_matrix * column_matrix

    # convert output_matrix to output_state
    output_state = reshape_as_state(output_matrix)

    return output_state
def lagrange_interpolation(points, field_base=8, x0=0):
    '''
    :param points: a list of two lists. the first list element is the list of x values, the second list element is the list of y values
    :param field_base: base of the field. usually 8
    :param x0: f(x0) is the secret. We set x0 to be 0
    :return: s0, which is also the constant term of the polynomial
    '''
    x_values, y_values = points
    F = ffield.FField(field_base)
    f_x = 0
    for i in range(len(x_values)):
        numerator, denominator = 1, 1
        for j in range(len(x_values)):
            if i == j:
                continue
            numerator = F.Multiply(numerator, F.Subtract(x0, x_values[j]))
            denominator = F.Multiply(denominator, F.Subtract(x_values[i], x_values[j]))

        lagrange_polynomial = F.Multiply(numerator, F.Inverse(denominator))
        f_x = F.Add(f_x, F.Multiply(y_values[i], lagrange_polynomial))
    print(f_x)
    return chr(f_x)
def generate_g_polynomial(degree, field_base, f_coefficients, secret):
    '''
    To detect cheating, we generate another polynomial g(x) = a0 + a1x + ... + ak-1x^(k-1), which 
    satisfies a0 + s0*r = 0, a1 + s1*r = 0, r belongs to GF(2^8). 
    Here we denote f(x) = s0 + s1x + ... + sk-1*x^(k-1)
    This function returns [a0, a1, ... , ak-1]
    
    '''
    F = ffield.FField(field_base)
    if degree < 0:
        raise ValueError("Degree cannot be a negative number.")
    g_coefficients = []
    upper_bound = 2**field_base - 1
    random_r = randint(0, upper_bound)
    s0 = ord(secret)
    a0 = F.Subtract(0, F.Multiply(random_r, s0))
    g_coefficients.append(a0)
    a1 = F.Subtract(0, F.Multiply(random_r, f_coefficients[0]))
    g_coefficients.append(a1)
    for i in range(1, degree):
        random_coeff = randint(0, upper_bound)
        g_coefficients.append(random_coeff)
    return g_coefficients