mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-23 18:03:46 +03:00
4d3ff0e175
This reverts commit 42cc9e61fb
.
tgcrypto was made for Pyrogram, and seeing it used elsewhere
without much credit "hurts" the author. I personally do not endorse
its use, hence the lack of attention or notes in the documentation.
People who still want to benefit from the speed boost should go
out of their way to discover, install and patch Telethon's aes.py
module instead, all while complying with the respective license
(another reason to avoid said code in Telethon, which is under the
much more permissive MIT license).
People using tgcrypto for anything other than Pyrogram will do so
knowing full-well that this was not the library's intended usage.
112 lines
3.1 KiB
Python
112 lines
3.1 KiB
Python
"""
|
|
AES IGE implementation in Python.
|
|
|
|
If available, cryptg will be used instead, otherwise
|
|
if available, libssl will be used instead, otherwise
|
|
the Python implementation will be used.
|
|
"""
|
|
import os
|
|
import pyaes
|
|
import logging
|
|
from . import libssl
|
|
|
|
|
|
__log__ = logging.getLogger(__name__)
|
|
|
|
|
|
try:
|
|
import cryptg
|
|
__log__.info('cryptg detected, it will be used for encryption')
|
|
except ImportError:
|
|
cryptg = None
|
|
if libssl.encrypt_ige and libssl.decrypt_ige:
|
|
__log__.info('libssl detected, it will be used for encryption')
|
|
else:
|
|
__log__.info('cryptg module not installed and libssl not found, '
|
|
'falling back to (slower) Python encryption')
|
|
|
|
|
|
class AES:
|
|
"""
|
|
Class that servers as an interface to encrypt and decrypt
|
|
text through the AES IGE mode.
|
|
"""
|
|
@staticmethod
|
|
def decrypt_ige(cipher_text, key, iv):
|
|
"""
|
|
Decrypts the given text in 16-bytes blocks by using the
|
|
given key and 32-bytes initialization vector.
|
|
"""
|
|
if cryptg:
|
|
return cryptg.decrypt_ige(cipher_text, key, iv)
|
|
if libssl.decrypt_ige:
|
|
return libssl.decrypt_ige(cipher_text, key, iv)
|
|
|
|
iv1 = iv[:len(iv) // 2]
|
|
iv2 = iv[len(iv) // 2:]
|
|
|
|
aes = pyaes.AES(key)
|
|
|
|
plain_text = []
|
|
blocks_count = len(cipher_text) // 16
|
|
|
|
cipher_text_block = [0] * 16
|
|
for block_index in range(blocks_count):
|
|
for i in range(16):
|
|
cipher_text_block[i] = \
|
|
cipher_text[block_index * 16 + i] ^ iv2[i]
|
|
|
|
plain_text_block = aes.decrypt(cipher_text_block)
|
|
|
|
for i in range(16):
|
|
plain_text_block[i] ^= iv1[i]
|
|
|
|
iv1 = cipher_text[block_index * 16:block_index * 16 + 16]
|
|
iv2 = plain_text_block
|
|
|
|
plain_text.extend(plain_text_block)
|
|
|
|
return bytes(plain_text)
|
|
|
|
@staticmethod
|
|
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 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)
|