def encrypt_cdata(correct: bool, step: int, mistakes: int, userId: int) -> bytes: data = (correct.to_bytes(1, "little") + step.to_bytes(1, "little") + mistakes.to_bytes(1, "little") + userId.to_bytes(4, "little") + os.urandom(57)) iv = bytes(32) return tgcrypto.ige256_encrypt(data, key, iv)
def encrypt(self, message, mode): if mode == "org": mode = 0 else: mode = 8 message_len = f"{len(message):b}" length = f"{(32 - len(message_len)) * '0'}" + f"{message_len}" padded_message = Oracle.pad(length.encode() + message) msg_key_large = hashlib.sha256(self.secret_key[88 + mode:120] + padded_message).digest() self.msg_key = msg_key_large[8:24] kdf = KDF(self.secret_key, self.msg_key, mode) aes_key, aes_iv = kdf.KD() ige_encrypted = tgcrypto.ige256_encrypt(padded_message, aes_key, aes_iv) ige_encrypted_header_set = self.msg_key + ige_encrypted return ige_encrypted_header_set
def encrypt_ige(plain_text, key, iv): """ Encrypts the given text in 16-bytes blocks by using the given key and 32-bytes initialization vector. """ padding = len(plain_text) % 16 if padding: plain_text += os.urandom(16 - padding) if tgcrypto: return tgcrypto.ige256_encrypt(plain_text, key, iv) if cryptg: return cryptg.encrypt_ige(plain_text, key, iv) if libssl.encrypt_ige: return libssl.encrypt_ige(plain_text, key, iv) iv1 = iv[:len(iv) // 2] iv2 = iv[len(iv) // 2:] aes = pyaes.AES(key) cipher_text = [] blocks_count = len(plain_text) // 16 for block_index in range(blocks_count): plain_text_block = list(plain_text[block_index * 16:block_index * 16 + 16]) for i in range(16): plain_text_block[i] ^= iv1[i] cipher_text_block = aes.encrypt(plain_text_block) for i in range(16): cipher_text_block[i] ^= iv2[i] iv1 = cipher_text_block iv2 = plain_text[block_index * 16:block_index * 16 + 16] cipher_text.extend(cipher_text_block) return bytes(cipher_text)
def ige256_encrypt(cls, data: bytes, key: bytes, iv: bytes) -> bytes: return tgcrypto.ige256_encrypt(data, key, iv)
def test_ige256_encrypt_invalid_iv_size(self): with self.assertRaisesRegex(ValueError, r"IV size must be exactly 32 bytes"): tgcrypto.ige256_encrypt(os.urandom(16), os.urandom(32), os.urandom(31))
def test_ige256_encrypt_empty_data(self): with self.assertRaisesRegex(ValueError, r"Data must not be empty"): tgcrypto.ige256_encrypt(b"", os.urandom(32), os.urandom(32))
def test_ige256_encrypt_invalid_args_type(self): with self.assertRaisesRegex(TypeError, self.TYPE_ERROR_PATTERN): tgcrypto.ige256_encrypt(1, 2, 3)
def test_ige256_encrypt_invalid_args_count(self): with self.assertRaisesRegex( TypeError, r"function takes exactly \d arguments \(\d given\)"): tgcrypto.ige256_encrypt(os.urandom(16), os.urandom(32))