def q_key(k: bytes): #part 1 left_part = ByteUtils.getLeftPart(k) sqr_1 = FFunc.f_func(left_part, Key.S_1) right_part = ByteUtils.xor(sqr_1, ByteUtils.getRightPart(k)) #part 2 left_part, right_part = right_part, left_part sqr_2 = FFunc.f_func(left_part, Key.S_2) right_part = ByteUtils.xor(sqr_2, right_part) #part 3 left_part, right_part = right_part, left_part part_3_res = ByteUtils.xor(left_part + right_part, k) #part 4 left_part = ByteUtils.getLeftPart(part_3_res) right_part = ByteUtils.getRightPart(part_3_res) sqr_3 = FFunc.f_func(left_part, Key.S_3) right_part = ByteUtils.xor(sqr_3, right_part) #part 5 left_part, right_part = right_part, left_part sqr_4 = FFunc.f_func(left_part, Key.S_4) right_part = ByteUtils.xor(sqr_4, right_part) return right_part + left_part
def fl_inv(y: bytes, kl: bytes): y_l = ByteUtils.getLeftPart(y) y_r = ByteUtils.getRightPart(y) kl_l = ByteUtils.getLeftPart(kl) kl_R = ByteUtils.getRightPart(kl) sqr_1 = (int.from_bytes(y_r, "little") | int.from_bytes(kl_R, "little")).to_bytes(4, "little") sqr_2 = ByteUtils.xor(sqr_1, y_l) sqr_3 = (int.from_bytes(sqr_2, "little") & int.from_bytes(kl_l, "little")).to_bytes(4, "little") sqr_4 = ByteUtils.rol(sqr_3, 1) sqr_5 = ByteUtils.xor(sqr_4, y_r) return sqr_2 + sqr_5
def decrypt(x: bytes, key: bytes): if (len(x) < 16): raise Exception("text should contain more or equal than 16 bytes") elif (len(key) != 16): raise Exception("text should have 16 bytes") elif (len(x) % 16 != 0): raise Exception("text should have total each block") count = len(x) // 16 blocks = [] for i in range(1, count + 1): blocks.append(x[16 * (i - 1): 16 * i]) cipher_blocks = [] init_block = key for i in range(len(blocks)): cipher_block = ByteUtils.xor(blocks[i], init_block) cipher_blocks.append(cipher_block) init_block = blocks[i] result = bytes() for block in cipher_blocks: result += block if (CBC.is_block_empty(CBC.get_16_bytes_block(result, 1))): return CBC.handle_decrypt_if_last_block_empty(result) else: return result
def encrypt_if_block_not_total(x: bytes, key: bytes): count = len(x) // 16 blocks = [] for i in range(1, count + 1): blocks.append(x[16 * (i - 1): 16 * i]) last_bloc = x[16 * count: len(x)] if(len(last_bloc) == 16): blocks.append(last_bloc) else: empty_bytes = 0 while(len(last_bloc) < 15): empty_bytes += 1 last_bloc += int(0).to_bytes(1, "little") last_bloc += int(empty_bytes).to_bytes(1, "little") blocks.append(last_bloc) blocks.append(int(0).to_bytes(16, "little")) cipher_blocks = [] init_block = key for i in range(len(blocks)): cipher_block = ByteUtils.xor(blocks[i], init_block) cipher_blocks.append(cipher_block) init_block = cipher_block result = bytes() for block in cipher_blocks: result += block return result
def fl_func(x: bytes, kl: bytes): x_l = ByteUtils.getLeftPart(x) x_r = ByteUtils.getRightPart(x) kl_l = ByteUtils.getLeftPart(kl) kl_r = ByteUtils.getRightPart(kl) sqr_1 = int( int.from_bytes(kl_l, "little") & int.from_bytes(x_l, "little")).to_bytes(4, "little") sqr_2 = ByteUtils.rol(sqr_1, 1) sqr_3 = ByteUtils.xor(sqr_2, x_r) sqr_4 = (int.from_bytes(sqr_3, "little") | int.from_bytes(kl_r, "little")).to_bytes(4, "little") sqr_5 = ByteUtils.xor(sqr_4, x_l) return sqr_5 + sqr_3
def encrypt_if_block_total(x: bytes, key: bytes): count = len(x) // 16 blocks = [] for i in range(1, count + 1): blocks.append(x[16 * (i - 1): 16 * i]) cipher_blocks = [] init_block = key for i in range(len(blocks)): cipher_block = ByteUtils.xor(blocks[i], init_block) cipher_blocks.append(cipher_block) init_block = cipher_block result = bytes() for block in cipher_blocks: result += block return result
def encrypt(x: bytes, key: bytes): if (len(x) != 16): raise Exception("entry value should be 16 bytes") elif (len(key) != 16): raise Exception("key should be 16 bytes") Camelia.init_key_k(key) left = ByteUtils.xor(ByteUtils.getLeftPart(x), Camelia.kw_i[0]) right = ByteUtils.xor(ByteUtils.getRightPart(x), Camelia.kw_i[1]) for i in range(6): sqr = FFunc.f_func(left, Camelia.k_i[i]) right = ByteUtils.xor(right, sqr) right, left = left, right left = FLFunction.fl_func(left, Camelia.kl_i[0]) right = FLFunction.fl_inv(right, Camelia.kl_i[1]) for i in range(6, 12): sqr = FFunc.f_func(left, Camelia.k_i[i]) right = ByteUtils.xor(right, sqr) right, left = left, right left = FLFunction.fl_func(left, Camelia.kl_i[2]) right = FLFunction.fl_inv(right, Camelia.kl_i[3]) for i in range(12, 18): sqr = FFunc.f_func(left, Camelia.k_i[i]) right = ByteUtils.xor(right, sqr) right, left = left, right left, right = ByteUtils.xor(right, Camelia.kw_i[2]), ByteUtils.xor( left, Camelia.kw_i[3]) return left + right
def test_xor(self): self.assertEqual(self.res_xor.hex(), ByteUtils.xor(self.bytes_, self.other_xor).hex())