示例#1
0
def DecryptBlock(k_obj: KalynaObject, c_text: Union[str, int], roundkeys: dict,
                 inv_tables: list, inv_mix_col_t: list, inv_c_mat: np.array):

    l = k_obj.BlockSize
    t = k_obj.NumRounds
    k_t = roundkeys[t]
    k_obj.state = to_bytes(
        hex(c_text)[2:], k_obj.state.shape[1], k_obj.NumStateMatrixRows,
        k_obj.HexKeyLength, True)

    sub_method(k_obj, k_t)

    invMixColumns(k_obj, inv_mix_col_t, inv_c_mat)
    inv_shift = [-((i * l) // 512) for i in range(len(k_obj.state[0]))]
    inv_rot_word(k_obj, inv_shift)
    inv_sub_bytes(k_obj, inv_tables)

    for i in range(t - 1, 0, -1):
        rk = roundkeys[i]

        xor_round_key(k_obj, rk)

        invMixColumns(k_obj, inv_mix_col_t, inv_c_mat)
        inv_rot_word(k_obj, inv_shift)
        inv_sub_bytes(k_obj, inv_tables)

    rk = roundkeys[0]

    sub_method(k_obj, rk)

    return k_obj.state
示例#2
0
def sub_method(k_obj: KalynaObject, byte2: np.array, modulus: int = 2**64):
    """
    Returns the difference of the internal state matrix and byte2 modulo some input.
    Modulus = 2**64 (default).
    :param k_obj: Kalyna object.
    :param byte2: 2nd byte to be subtracted.
    :param modulus: Default value according to the paper.
    :return: (np array) Difference of both bytes modulo "modulus".
    """
    byte1 = k_obj.state
    assert byte1.shape == byte2.shape, "Bytes should be of the same shape."
    length, width = byte1.shape
    slc = 2 * width
    f_block = list()
    b1_w = to_words(np.fliplr(byte1))
    b2_w = to_words(np.fliplr(byte2))
    for i in range(length):
        b1 = int(b1_w[slc * i:slc * (i + 1)], 16)
        b2 = int(b2_w[slc * i:slc * (i + 1)], 16)
        d = (b1 - b2) % modulus
        v = hex(d)[2:]
        # for hex whose starting 0 is stripped off by python
        while len(v) < slc:
            v = '0' + v
        f_block.append(v)
    f_block = ''.join(f_block)
    o_block = np.flipud(
        to_bytes(f_block, width, k_obj.NumStateMatrixRows, k_obj.HexKeyLength,
                 True))
    k_obj.state = o_block
示例#3
0
def EncryptBlock(k_obj: KalynaObject, p_text: Union[str, int], roundkeys: dict,
                 tables: list, mix_col_t: list, c_mat: np.array):

    k_0 = roundkeys[0]
    k_obj.state = to_bytes(
        hex(p_text)[2:], k_obj.state.shape[1], k_obj.NumStateMatrixRows,
        k_obj.HexKeyLength, True)
    add_method(k_obj, k_0)

    for j in range(1, k_obj.NumRounds):
        sub_bytes(k_obj, tables)
        shift = [
            math.floor((i * k_obj.BlockSize) / 512)
            for i in range(len(k_obj.state[0]))
        ]
        rot_word(k_obj, shift)
        mixColumns(k_obj, mix_col_t, c_mat)
        k_v = roundkeys[j]
        xor_round_key(k_obj, k_v)

    sub_bytes(k_obj, tables)
    shift = [(i * k_obj.BlockSize) // 512 for i in range(len(k_obj.state[0]))]
    rot_word(k_obj, shift)
    mixColumns(k_obj, mix_col_t, c_mat)
    k_t = roundkeys[k_obj.NumRounds]
    add_method(k_obj, k_t)

    return k_obj.state
示例#4
0
def KeyExpansionKT(k_obj: KalynaObject, main_key: int, k_alpha: np.array,
                   k_omega: np.array, tables: list, mix_col_t: list,
                   c_mat: np.array, state_0: int):

    l = k_obj.BlockSize

    # Pad state_0 word to appropriate length as keyLengthSize
    init_state = '0' * (k_obj.HexKeyLength -
                        len(hex(state_0)[2:])) + hex(state_0)[2:]

    k_alpha_byte = k_alpha
    k_omega_byte = k_omega

    init_state_byte = to_bytes(init_state, k_obj.state.shape[1],
                               k_obj.NumStateMatrixRows, k_obj.HexKeyLength,
                               True)
    k_obj.state = init_state_byte

    add_method(k_obj, k_alpha_byte)

    shift = [(i * l) // 512 for i in range(len(k_obj.state[0]))]

    EncryptRound(k_obj, tables, mix_col_t, c_mat, shift)

    xor_round_key(k_obj, k_omega_byte)

    EncryptRound(k_obj, tables, mix_col_t, c_mat, shift)

    add_method(k_obj, k_alpha_byte)

    EncryptRound(k_obj, tables, mix_col_t, c_mat, shift)

    K_sigma = k_obj.state
    return K_sigma
示例#5
0
def KalynaDecrypt(parameters: tuple, c_text: Union[str, int], main_key: int,
                  state_0: int):

    l, k, t, c = parameters
    rks = KalynaKeyExpansion(parameters, main_key, state_0)
    k_d = KalynaObject(l, k, t, c)
    return DecryptBlock(k_d, c_text, rks, all_inv_tables, all_inv_mix_cols,
                        inverse_mds_matrix)
示例#6
0
def KalynaEncrypt(parameters: tuple, p_text: Union[str, int], main_key: int,
                  state_0: int):

    l, k, t, c = parameters
    rks = KalynaKeyExpansion(parameters, main_key, state_0)
    k_e = KalynaObject(l, k, t, c)
    return EncryptBlock(k_e, p_text, rks, all_sub_tables, all_mix_cols,
                        mds_matrix)
示例#7
0
def inv_rot_word(k_obj: KalynaObject, inv_shift: list):
    """
    Implements the inverse permutation step.
    :param k_obj: Kalyna object.
    :param inv_shift: Permutation values. -ve for left shift and +ve for right shift.
    :return: Shifted state matrix.
    """
    vals = k_obj.state
    assert len(inv_shift) == vals.shape[
        1], "Length of inv_shift list and state-matrix dim[1] must be same."
    items = vals.transpose()
    for i in range(len(inv_shift)):
        items[i] = np.roll(items[i], inv_shift[i], axis=0)
    k_obj.state = items.transpose()
示例#8
0
def inv_sub_bytes(k_obj: KalynaObject, inv_tables: list):
    """
    Implements the inverse mapping step of the state matrix.
    :param k_obj: Kalyna object.
    :param inv_tables: Forward substitution tables.
    :return: Mapped state matrix.
    """
    num_col, c, h = k_obj.state.shape[
        1], k_obj.NumStateMatrixRows, k_obj.HexKeyLength
    inv_sub_block = to_bytes([
        inv_tables[j % 4][byte[j]] for byte in k_obj.state
        for j in range(len(byte))
    ], num_col, c, h)
    k_obj.state = inv_sub_block
示例#9
0
def KalynaKeyExpansion(parameters: tuple, main_key: int, state_0: int):

    l, k, t, c = parameters

    # Declare KalynaObject for round key generation
    k_c = KalynaObject(l, k, t, c)

    KT = 0
    if k == l:
        k0_b = key_to_bytes(
            hex(main_key)[2:], k_c.state.shape[1], c,
            k_c.PadKeyLength)  # k_alpha
        k1_b = key_to_bytes(
            hex(main_key)[2:], k_c.state.shape[1], c,
            k_c.PadKeyLength)  # k_omega
        KT = KeyExpansionKT(k_c, main_key, k0_b, k1_b, all_sub_tables,
                            all_mix_cols, mds_matrix, state_0)
        k_c.state = KT
    elif k == 2 * l:
        # Number of State Matrix Rows i.e. k_obj.NumStateMatrixRows for key handling is different for k=2*l cases
        # k_alpha
        k0 = LsbReturn(main_key, l, k_c.PadKeyLength)
        k0_b = key_to_bytes(
            hex(k0)[2:], k_c.state.shape[1], c, k_c.HexKeyLength)
        # k_omega
        k1 = MsbReturn(main_key, l, k_c.PadKeyLength)
        k1_b = key_to_bytes(
            hex(k1)[2:], k_c.state.shape[1], c, k_c.HexKeyLength)
        KT = KeyExpansionKT(k_c, main_key, k0_b, k1_b, all_sub_tables,
                            all_mix_cols, mds_matrix, state_0)
        k_c.state = KT

    roundkeys = KeyExpansionEven(k_c, KT, main_key, all_sub_tables,
                                 all_mix_cols, mds_matrix)
    roundkeys = KeyExpansionOdd(k_c, roundkeys)

    return roundkeys
示例#10
0
def xor_round_key(k_obj: KalynaObject, byte2: np.array):
    """
    Returns the XOR result of the internal state matrix of Kalyna object with byte2.
    :param k_obj: Kalyna object.
    :param byte2: 2nd byte.
    :return app_block: (array) XOR result.
    """
    byte_block = k_obj.state
    assert byte_block.shape == byte2.shape, "byte1 and byte2 are not of same shape."
    length, width = byte2.shape[0], byte2.shape[1]
    xor_block = [
        list(map(xor, byte_block[i], byte2[i])) for i in range(length)
    ]
    k_obj.state = to_bytes(xor_block, width, k_obj.NumStateMatrixRows,
                           k_obj.HexKeyLength)
示例#11
0
def mixColumns(k_obj: KalynaObject, tables: list, v: np.array):
    """
    Implements the Galois Field GF(2^8) transformation step.
    :param k_obj: Kalyna object.
    :param tables: Forward transformation tables.
    :param v: MDS vector matrix implemented as 8x8 numpy array
    :return: State matrix.
    """
    r_array = k_obj.state
    g = list()
    for byte in r_array:
        # Looping on mds_matrix
        for row_v in range(len(byte)):
            pr = 0
            for col_v in range(len(byte)):
                y = v[row_v][col_v]
                pr ^= tables[y][byte[col_v]]
            g.append(pr)
    k_obj.state = to_bytes(g, k_obj.state.shape[1], k_obj.NumStateMatrixRows,
                           k_obj.HexKeyLength)
示例#12
0
def invMixColumns(k_obj: KalynaObject, inv_tables: list, c_mat_inv: np.array):
    """
    Implements the inverse Galois Field GF(2^8) transformation step.
    :param k_obj: Kalyna object.
    :param inv_tables: Forward transformation tables.
    :param c_mat_inv: MDS inverse vector matrix implemented as 8x8 numpy array
    :return: State matrix.
    """
    trans = {173: 0, 149: 1, 118: 2, 168: 3, 47: 4, 73: 5, 215: 6, 202: 7}
    r_array = k_obj.state
    g = list()
    for byte in r_array:
        # Looping on mds_matrix
        for row_v in range(len(byte)):
            pr = 0
            for col_v in range(len(byte)):
                y = c_mat_inv[row_v][col_v]
                ind = trans[y]
                pr ^= inv_tables[ind][byte[col_v]]
            g.append(pr)
    k_obj.state = to_bytes(g, k_obj.state.shape[1], k_obj.NumStateMatrixRows,
                           k_obj.HexKeyLength)
示例#13
0
def KeyExpansionEven(k_obj: KalynaObject, k_sigma: np.array, main_key: int,
                     tables: list, mix_col_t: list, c_mat: np.array):

    # Design tmv firstly
    tmv_0 = int("0001" * (k_obj.HexKeyLength // 4), 16)

    roundkeys = dict()
    l = k_obj.BlockSize
    k = k_obj.KeyLength

    for i in range(0, k_obj.NumRounds + 1, 2):
        # print("Round number: {}".format(i))

        # tmv left-shift and length check in case if MSB is added for shift >=8
        tmv = tmv_0 << (i // 2)
        tmv_byte = key_to_bytes(
            hex(tmv)[2:], k_obj.state.shape[1], k_obj.NumStateMatrixRows,
            k_obj.HexKeyLength)

        # right shift the main_key acc to following conditions
        if k == l:
            cipher_key = circular_right_shift(main_key, 32 * i, k)
            ckb = key_to_bytes(
                hex(cipher_key)[2:], k_obj.state.shape[1],
                k_obj.NumStateMatrixRows, k_obj.PadKeyLength)
            cipher_key_byte = np.array(ckb, int)
        elif k == 2 * l:
            # Number of State Matrix Rows i.e. k_obj.NumStateMatrixRows for key handling is different for k=2*l cases
            if i % 4 == 0:
                cipher_key = circular_right_shift(main_key, 16 * i, k)
                ckb = key_to_bytes(
                    hex(cipher_key)[2:], k_obj.state.shape[1],
                    2 * k_obj.NumStateMatrixRows, k_obj.PadKeyLength)
                cipher_key_byte = np.array(ckb[:k_obj.NumStateMatrixRows], int)
            else:
                cipher_key = circular_right_shift(main_key, 64 * (i // 4), k)
                ckb = key_to_bytes(
                    hex(cipher_key)[2:], k_obj.state.shape[1],
                    2 * k_obj.NumStateMatrixRows, k_obj.PadKeyLength)
                cipher_key_byte = np.array(ckb[k_obj.NumStateMatrixRows:], int)
        else:
            cipher_key = main_key
            raise ValueError(
                "Incorrect values of k:KeyLength = {} and l:BlockSize  = {} !".
                format(k, l))

        # Key expansion process
        kt_round = add_method_simple(k_sigma, tmv_byte,
                                     k_obj.NumStateMatrixRows,
                                     k_obj.HexKeyLength)
        k_obj.state = kt_round

        add_method(k_obj, cipher_key_byte)

        shift = [(i * l) // 512 for i in range(len(k_obj.state[0]))]

        EncryptRound(k_obj, tables, mix_col_t, c_mat, shift)

        xor_round_key(k_obj, kt_round)

        EncryptRound(k_obj, tables, mix_col_t, c_mat, shift)

        add_method(k_obj, kt_round)

        roundkeys[i] = k_obj.state

    return roundkeys