コード例 #1
0
def key_expansion(key):
    expanded_key = [GF28.GF28(0)] * ((WORDS_PER_STATE *
                                      (ROUNDS + 1)) * BYTES_PER_WORD)
    # fill out the first four words with (4 * 8 = 32 bytes) the initial key
    for i in range(len(key)):
        expanded_key[i] = key[i]
    # fill out now according to the rule:
    # if it's a multiple of four, take the previous word, circular shift back once,
    # and then take each byte through the subst. table before XOR'ing with the
    # round constant
    # otherwise, leave it the same
    # then XOR the previous byte with the one NK back
    iterator = 4 * BYTES_PER_WORD
    # this takes place PER WORD (so operating on 4 bytes at a time)
    while (iterator < len(expanded_key)):
        prev_word = expanded_key[iterator - BYTES_PER_WORD:iterator]
        if iterator % (4 * BYTES_PER_WORD) == 0:
            rotate_key_word(prev_word)
            sub_bytes(prev_word)
            some_const = get_round_constant(
                math.floor(iterator / (BYTES_PER_WORD * WORDS_PER_STATE)))
            for idx, byte in enumerate(prev_word):
                prev_word[idx] = prev_word[idx] + some_const[idx]
        word_four_back = expanded_key[iterator -
                                      (4 * BYTES_PER_WORD):iterator -
                                      (3 * BYTES_PER_WORD)]
        new_word = [GF28.GF28(0)] * 4
        for idx in range(iterator, iterator + BYTES_PER_WORD):
            it = idx % 4
            expanded_key[idx] = prev_word[it] + word_four_back[it]
        iterator += BYTES_PER_WORD
    return expanded_key
コード例 #2
0
def inv_mix_cols(state):
    new_state = [GF28.GF28(0)] * 16
    for row in range(0, 4):
        for col in range(0, 4):
            index = 4 * row + col
            # row from mix mtrx,
            # col from state mtrx
            new_state[index] = GF28.dot_prod_in_GF28(
                INV_MIX_MTX[4 * row:4 * (row + 1)], state[col:16:4])
    return new_state
コード例 #3
0
def modify_list_into_GF28(original_list):
    modified_list = []
    if isinstance(original_list, bytes) or isinstance(original_list,
                                                      bytearray):
        for i in range(len(original_list)):
            modified_list.append(GF28.GF28(original_list[i]))
    elif isinstance(original_list, str):
        for i in range(len(original_list)):
            modified_list.append(GF28.GF28(ord(original_list[i])))
    else:
        raise TypeError("input is of an unsupported type")
    return modified_list
コード例 #4
0
def modify_IV_into_GF28(text_IV):
    # we only accept a string for this that is an integer (between 0 and 255)
    # each integer should be delimited by dashes (i.e. -) and there should be 16
    # integers
    result_in_GF28 = []
    if type(text_IV) is bytearray:
        for i in text_IV:
            result_in_GF28.append(GF28.GF28(i))
        return result_in_GF28
    values = text_IV.split('-')
    if (len(values)) != 16:
        raise ValueError("IV is not correct length for AES")
    for let in values:
        result_in_GF28.append(GF28.GF28(int(let)))
    return result_in_GF28
コード例 #5
0
def create_table():
    with open(filename, 'w') as holder:
        subst = {}
        inverse = {}
        for num in range(256):
            num = GF28.GF28(num, bypass_modcheck=True)
            # works with 0 b/c of hack in GF28.py
            byte_stuff = num.inverse()
            res = GF28.GF28()
            for i in range(5):
                res = res + byte_stuff
                byte_stuff.rotate_bit()
            res = res + GF28.GF28(0x63)
            if num.number > 256 or res.number > 256:
                raise ValueError("Num or res out of range")
            subst[num.number] = res.number
            inverse[res.number] = num.number
        holder.write(json.dumps([subst, inverse]))
コード例 #6
0
def sub_bytes(state):
    for idx, byte in enumerate(state):
        state[idx] = GF28.GF28(SUBS_TABLE[str(byte.number)], True)
    return
コード例 #7
0
def PKCS_padd(array_GF28):
    padding = 16 - (len(array_GF28) % 16)
    array_GF28.extend([GF28.GF28(padding)] * padding)
    return array_GF28
コード例 #8
0
def get_round_constant(round_idx):
    if (round_idx < 1):
        raise ValueError("Index should be higher for calling round constant")
    round_res = [GF28.GF28(0)] * 4
    round_res[0] = GF28.GF28(1 << (round_idx - 1))
    return round_res
コード例 #9
0
def unscramble_state(state_arr):
    state_output = [GF28.GF28(0)] * 16
    for idx, GF28_elt in enumerate(state_arr):
        quot_rem = divmod(idx, 4)
        state_output[quot_rem[1] * 4 + quot_rem[0]] = state_arr[idx]
    return state_output
コード例 #10
0
def fill_state_array(text):
    state_arr = [GF28.GF28(0)] * 16
    for idx, elt_GF28 in enumerate(state_arr):
        quot_rem = divmod(idx, 4)
        state_arr[idx] = text[quot_rem[1] * 4 + quot_rem[0]]
    return state_arr
コード例 #11
0
# takes a round index and returns a round constant for key expansion
# that represents a poly of degree
# less than 4 with elements from GF28
def get_round_constant(round_idx):
    if (round_idx < 1):
        raise ValueError("Index should be higher for calling round constant")
    round_res = [GF28.GF28(0)] * 4
    round_res[0] = GF28.GF28(1 << (round_idx - 1))
    return round_res


# fixing this to let the offset determine which row somehthing actually is
MIX_MTX = [2, 3, 1, 1, 1, 2, 3, 1, 1, 1, 2, 3, 3, 1, 1, 2]
for idx, val in enumerate(MIX_MTX):
    MIX_MTX[idx] = GF28.GF28(val)
# TODO write a matrix inverse function
INV_MIX_MTX = [14, 11, 13, 9, 9, 14, 11, 13, 13, 9, 14, 11, 11, 13, 9, 14]
for idx, val in enumerate(INV_MIX_MTX):
    INV_MIX_MTX[idx] = GF28.GF28(val)
SUBS_TABLE = {}
INV_SUBS_TABLE = {}
if not (os.path.exists(filename)):
    create_table()
with open(filename, 'r') as sub_r:
    both_tables = json.loads(sub_r.read())
    SUBS_TABLE = both_tables[0]
    INV_SUBS_TABLE = both_tables[1]


def print_GF28_list(list_t):