Пример #1
0
def aesMixColumns(bstr_state):
    """
    TODO: make variable
    """

    # go for columns
    state = makeNDArrayFrom(bstr_state, 4, 4).transpose()
    mds_matrix = np.array(mds_matrix_flat)
    mds_matrix = mds_matrix.reshape(4, 4)
    result = np.zeros(shape=(4, 4), dtype=np.int8)
    # number of columns
    # iterate over columns
    for i in range(len(state)):
        # iterate over bytes
        result_byte = 0
        for bnum in range(len(state[i])):
            result[i][bnum] = mdsLookup(state[i][0], mds_matrix[bnum][0])
            result[i][bnum] ^= mdsLookup(state[i][1], mds_matrix[bnum][1])
            result[i][bnum] ^= mdsLookup(state[i][2], mds_matrix[bnum][2])
            result[i][bnum] ^= mdsLookup(state[i][3], mds_matrix[bnum][3])
    result = bytes(result.transpose().flatten())
    return result

    # gmul variant
    """
Пример #2
0
def aesEncrypt(bstr_msg, bstr_key, num_bits, mode='ecb', bstr_IV=None):
    if len(bstr_key) != 16:
        # no key derivation yet
        print("Unsuitable key length!")
        exit(1)

    # without padding for now
    #bstr_msg = misc.padPKCS7(bstr_msg, 16)
    state_iter = stateGenerator(bstr_msg, 16)
    rounds = {128: 10, 192: 12, 256: 14}
    round_keys = aesKeyExpansion(bstr_key)
    cipher = b''

    preceding_cipher_block = bstr_IV

    for state in state_iter:
        if mode == 'cbc':
            state = xorBytestrings(state, preceding_cipher_block)

        # initial (not actual) round
        state_trans = bytes(makeNDArrayFrom(state, 4, 4).transpose().flatten())
        key_trans = bytes(
            makeNDArrayFrom(bstr_key, 4, 4).transpose().flatten())

        bstr_state = aesAddRoundkey(state_trans, key_trans)

        for r in range(0, rounds[num_bits]):
            if r == rounds[num_bits] - 1:
                # last round no Mix Columns
                bstr_state = aesSubBytes(bstr_state)
                bstr_state = aesShiftRows(bstr_state)
                key_trans = bytes(
                    makeNDArrayFrom(round_keys[r], 4, 4).transpose().flatten())
                bstr_state = aesAddRoundkey(bstr_state, key_trans)
            else:
                bstr_state = aesSubBytes(bstr_state)
                bstr_state = aesShiftRows(bstr_state)
                bstr_state = aesMixColumns(bstr_state)
                key_trans = bytes(
                    makeNDArrayFrom(round_keys[r], 4, 4).transpose().flatten())
                bstr_state = aesAddRoundkey(bstr_state, key_trans)
        state_result = bytes(
            makeNDArrayFrom(bstr_state, 4, 4).transpose().flatten())
        preceding_cipher_block = state_result

        cipher += state_result
    return cipher
Пример #3
0
def aesKeyExpansion(bstr_key):
    """
    Returns the roundkeys a list of byte strings
    TODO: make length parameters variable
    """
    if len(bstr_key) != 16 and len(bstr_key) != 24 and len(bstr_key) != 32:
        print("Invalid key length!")
        exit(1)
    numbits = len(bstr_key) * 8
    rounds = {128: 10, 192: 12, 256: 14}
    round_keys = []

    # transposed since we are operating on the columns
    prevkey = makeNDArrayFrom(bstr_key, 4, 4)

    newkey = b''
    offset = 0
    rcon_round = 1
    while len(round_keys) < rounds[numbits]:
        # on every first 4 byte group of the 16 byte blocks perform rotate,
        # subbytes
        if offset == 0:
            word = bytes(prevkey[3])
            word = aesKeyExpansionCore(word, rcon_round)
            rcon_round += 1
        else:
            word = newkey[offset - 4:offset]
        word_from_prevkey = bytes(prevkey.flatten())[offset:offset + 4]
        word = xorBytestrings(word, word_from_prevkey)
        newkey += word
        offset += 4
        if offset == 16:
            offset = 0
            prevkey = makeNDArrayFrom(newkey, 4, 4)
            # transpose back and convert to byte string before appending to
            # result list
            newkey = bytes(makeNDArrayFrom(newkey, 4, 4).flatten())
            round_keys.append(newkey)
            newkey = b''
    return round_keys
Пример #4
0
def aesInvMixColumns(bstr_state):
    """
    TODO: make variable
    """
    # go for columns
    state = makeNDArrayFrom(bstr_state, 4, 4).transpose()
    inv_mds_matrix = np.array(inv_mds_matrix_flat)
    inv_mds_matrix = inv_mds_matrix.reshape(4, 4)
    result_array = np.zeros(shape=(4, 4), dtype=np.uint8)
    for c in range(len(state)):
        for b in range(len(state[c])):
            result_array[c][b] = gmul(state[c][0], inv_mds_matrix[b][0])
            result_array[c][b] ^= gmul(state[c][1], inv_mds_matrix[b][1])
            result_array[c][b] ^= gmul(state[c][2], inv_mds_matrix[b][2])
            result_array[c][b] ^= gmul(state[c][3], inv_mds_matrix[b][3])

    result = bytes(result_array.transpose().flatten())
    return result
Пример #5
0
def aesDecrypt(bstr_cipher, bstr_key, num_bits, mode='ecb', bstr_IV=None):
    if len(bstr_key) != 16:
        # no key derivation yet
        print("Unsuitable key length!")
        exit(1)

    state_iter = stateGenerator(bstr_cipher, 16)
    rounds = {128: 10, 192: 12, 256: 14}
    round_keys = aesKeyExpansion(bstr_key)
    cipher = b''
    prev_cipherstate = bstr_IV
    for state in state_iter:
        # initial round
        bstr_state = bytes(makeNDArrayFrom(state, 4, 4).transpose().flatten())
        key_trans = bytes(
            makeNDArrayFrom(bstr_key, 4, 4).transpose().flatten())
        for r in reversed(range(0, rounds[num_bits])):
            if r == rounds[num_bits] - 1:
                # first round no inverse MixColumns
                key_trans = bytes(
                    makeNDArrayFrom(round_keys[r], 4, 4).transpose().flatten())
                bstr_state = aesAddRoundkey(bstr_state, key_trans)
                bstr_state = aesInvShiftRows(bstr_state)
                bstr_state = aesInvSubBytes(bstr_state)
            else:
                key_trans = bytes(
                    makeNDArrayFrom(round_keys[r], 4, 4).transpose().flatten())
                bstr_state = aesAddRoundkey(bstr_state, key_trans)
                bstr_state = aesInvMixColumns(bstr_state)
                bstr_state = aesInvShiftRows(bstr_state)
                bstr_state = aesInvSubBytes(bstr_state)
        key_trans = bytes(
            makeNDArrayFrom(bstr_key, 4, 4).transpose().flatten())
        bstr_state = aesAddRoundkey(bstr_state, key_trans)
        bstr_state = bytes(
            makeNDArrayFrom(bstr_state, 4, 4).transpose().flatten())
        if mode == 'cbc':
            bstr_state = xorBytestrings(bstr_state, prev_cipherstate)
            prev_cipherstate = state
        cipher += bstr_state
        #cipher = misc.unpadPKCS7(cipher, 16)
    return cipher
Пример #6
0
def aesInvShiftRows(bstr_state):
    arr = makeNDArrayFrom(bstr_state, 4, 4)
    for i in range(len(arr)):
        arr[i] = rotateList(arr[i], i, 'r')
    return bytes(arr.flatten())