TgCryptos 0.0.11
Fast and Portable Cryptography Extension Library for Pyrofork
Requires Python: >=3.10
Keywords: pyrogram pyrofork telegram

<p align="center">
    📦 <a href="https://pypi.org/project/TgCryptos/" style="text-decoration:none;">Tgcrypto</a>
</p>

<p align="center">
   <a href="https://telegram.me/Space_x_bots"><img src="https://img.shields.io/badge/Sᴘᴀᴄᴇ 𝕩 ʙᴏᴛꜱ-30302f?style=flat&logo=telegram" alt="telegram badge"/></a>
   <a href="https://telegram.me/clinton_abraham"><img src="https://img.shields.io/badge/Cʟɪɴᴛᴏɴ Aʙʀᴀʜᴀᴍ-30302f?style=flat&logo=telegram" alt="telegram badge"/></a>
   <a href="https://telegram.me/sources_codes"><img src="https://img.shields.io/badge/Sᴏᴜʀᴄᴇ ᴄᴏᴅᴇꜱ-30302f?style=flat&logo=telegram" alt="telegram badge"/></a>
</p>

| Fast and Portable Cryptography Extension Library for Pyrofork |
|---------------------------------------------------------------|

TgCrypto is a cryptography library written in C as a python extension. It is designed to be portable, fast,
easy to install and use. TgCrypto is intended for [Pyrofork](https://github.com/Mayuri-Chan/pyrofork) and implements the
cryptographic algorithms telegram requires, namely


<details>
  <summary>....</summary>

- **`AES-256-IGE`** - used in [MTProto v2.0](https://core.telegram.org/mtproto).  
- **`AES-256-CTR`** - used for [CDN encrypted files](https://core.telegram.org/cdn).  
- **`AES-256-CBC`** - used for [encrypted passport credentials](https://core.telegram.org/passport).  

</details>

## REQUIREMENTS

- Python 3.10 or higher.

## INSTALLATION

``` bash
$ pip3 install -U tgcryptos
```

## API

TgCrypto API consists of these six methods:

```python
def ige256_encrypt(data: bytes, key: bytes, iv: bytes) -> bytes: ...
def ige256_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes: ...

def ctr256_encrypt(data: bytes, key: bytes, iv: bytes, state: bytes) -> bytes: ...
def ctr256_decrypt(data: bytes, key: bytes, iv: bytes, state: bytes) -> bytes: ...

def cbc256_encrypt(data: bytes, key: bytes, iv: bytes) -> bytes: ...
def cbc256_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes: ...
```

## USAGE

| IGE MODE |
|---------------------------------------------------------------|

<details>

Note : Data must be padded to match a multiple of the block size (16 bytes).

``` python
import os
import tgcrypto

data = os.urandom(10 * 1024 * 1024 + 7)  # 10 MB of random data + 7 bytes to show padding
key = os.urandom(32)  # Random Key
iv = os.urandom(32)  # Random IV

# Pad with zeroes: -7 % 16 = 9
data += bytes(-len(data) % 16)

ige_encrypted = tgcrypto.ige256_encrypt(data, key, iv)
ige_decrypted = tgcrypto.ige256_decrypt(ige_encrypted, key, iv)

print(data == ige_decrypted)  # True
```

</details>


| CBC MODE |
|---------------------------------------------------------------|

<details>

Note : Data must be padded to match a multiple of the block size (16 bytes).

``` python
import os
import tgcrypto

data = os.urandom(10 * 1024 * 1024 + 7)  # 10 MB of random data + 7 bytes to show padding
key = os.urandom(32)  # Random Key

enc_iv = bytearray(os.urandom(16))  # Random IV
dec_iv = enc_iv.copy()  # Keep a copy for decryption

# Pad with zeroes: -7 % 16 = 9
data += bytes(-len(data) % 16)

cbc_encrypted = tgcrypto.cbc256_encrypt(data, key, enc_iv)
cbc_decrypted = tgcrypto.cbc256_decrypt(cbc_encrypted, key, dec_iv)

print(data == cbc_decrypted)  # True
```

</details>


| CTR MODE (stream) |
|---------------------------------------------------------------|

<details>

``` python
import os
import tgcrypto
from io import BytesIO


data = BytesIO(os.urandom(10 * 1024 * 1024))  # 10 MB of random data

key = os.urandom(32)  # Random Key

enc_iv = bytearray(os.urandom(16))  # Random IV
dec_iv = enc_iv.copy()  # Keep a copy for decryption

enc_state = bytes(1)  # Encryption state, starts from 0
dec_state = bytes(1)  # Decryption state, starts from 0

encrypted_data = BytesIO()  # Encrypted data buffer
decrypted_data = BytesIO()  # Decrypted data buffer

while True:
    chunk = data.read(1024)

    if not chunk:
        break

    # Write 1K encrypted bytes into the encrypted data buffer
    encrypted_data.write(tgcrypto.ctr256_encrypt(chunk, key, enc_iv, enc_state))

# Reset position. We need to read it now
encrypted_data.seek(0)

while True:
    chunk = encrypted_data.read(1024)

    if not chunk:
        break

    # Write 1K decrypted bytes into the decrypted data buffer
    decrypted_data.write(tgcrypto.ctr256_decrypt(chunk, key, dec_iv, dec_state))

print(data.getvalue() == decrypted_data.getvalue())  # True
```
</details>


| CTR MODE (single chunk) |
|---------------------------------------------------------------|

<details>

``` python
import os
import tgcrypto

data = os.urandom(10 * 1024 * 1024)  # 10 MB of random data

key = os.urandom(32)  # Random Key

enc_iv = bytearray(os.urandom(16))  # Random IV
dec_iv = enc_iv.copy()  # Keep a copy for decryption

ctr_encrypted = tgcrypto.ctr256_encrypt(data, key, enc_iv, bytes(1))
ctr_decrypted = tgcrypto.ctr256_decrypt(ctr_encrypted, key, dec_iv, bytes(1))

print(data == ctr_decrypted)  # True
```
</details>


## License

[LGPLv3+](COPYING.lesser) © 2017 - 2024 [Dan](https://github.com/delivrance)  
[LGPLv3+](COPYING.lesser) © 2025 - present [Clinton-Abraham](https://github.com/Clinton-Abraham)