def aes128_ctr_cipher(string, nonce, key): """ ------------------ | nonce + counter| ------------------ | ----------- | encrypt | ----------- ------------------------ | | plain or cipher text | ---------> |XOR| ------------------------ | ------------------------ | plain or cipher text | ------------------------ """ cipher_string = b'' # Divide input string in blocks of 16 bytes cipher_text_blocks = [string[i:i + 16] for i in range(0, len(string), 16)] for i in range(len(cipher_text_blocks)): # Calculate incremental nonce block for each input string block nonce_block = nonce + i.to_bytes(8, byteorder='little') nonce_matrix = string_to_matrix_states(nonce_block)[0] # Cipher nonce block with key nonce_matrix_cipher = aes128_RoundBlock(nonce_matrix, key) d = xor_states(nonce_matrix_cipher, string_to_matrix_states(cipher_text_blocks[i])[0]) cipher_string += matrix_to_bytes(d) return cipher_string
def mt19937_cipher(input_string, seed): """ ----------------------- | Generated keystream | ----------------------- ------------------------ | | plain or cipher text | ---------> |XOR| ------------------------ | ------------------------ | plain or cipher text | ------------------------ """ output_string = b'' # Initialize rng using key as a seed. rng = MT19937(seed) # Divide input string in blocks of 16 bytes input_text_blocks = [ input_string[i:i + 16] for i in range(0, len(input_string), 16) ] for i in range(len(input_text_blocks)): # Calculate keystream block for each input string block rng_block = generate_keytream_block(rng) rng_matrix = string_to_matrix_states(rng_block)[0] # Xor matrix d = xor_states(rng_matrix, string_to_matrix_states(input_text_blocks[i])[0]) output_string += matrix_to_bytes(d) return output_string
def aes128_cbc_decrypt(cipher_text, iv, key): # assuming iv is a 16 bytes string, so a single state is created iv_matrix = string_to_matrix_states(iv)[0] states = string_to_matrix_states(cipher_text) plain_text = b'' for index, state in enumerate(states): if index == 0: d = xor_states(aes128_InvRoundBlock(state, key), iv_matrix) else: d = xor_states(aes128_InvRoundBlock(state, key), states[index - 1]) plain_text += matrix_to_bytes(d) return plain_text
def aes128_cbc_encrypt(plain_text, iv, key): # assuming iv is a 16 bytes string, so a single state is created iv_matrix = string_to_matrix_states(iv)[0] states = string_to_matrix_states(plain_text) cipher_text = b'' pre_ciphertext_state = [[], [], [], []] for index, state in enumerate(states): if index == 0: e = aes128_RoundBlock(xor_states(state, iv_matrix), key) else: e = aes128_RoundBlock(xor_states(state, pre_ciphertext_state), key) pre_ciphertext_state = e cipher_text += matrix_to_bytes(e) return cipher_text
def aes128_ecb_encrypt(plain_text, key): states = string_to_matrix_states(plain_text) cipher_text = b'' for state in states: d = matrix_to_bytes(aes128_RoundBlock(state, key)) cipher_text += d return cipher_text
def aes128_ecb_decrypt(cipher_text, key): states = string_to_matrix_states(cipher_text) plain_text = b'' for state in states: d = matrix_to_bytes(aes128_InvRoundBlock(state, key)) plain_text += d return plain_text