# TgCrypto
> Cryptography Extension Library for Pyrogram
**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 [Pyrogram](https://github.com/pyrogram/pyrogram) and implements the
cryptographic algorithms Telegram requires, namely:
- **`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).
## Requirements
- Python 3.9 or higher.
## Installation
``` bash
$ pip3 install -U cryptgram
```
## 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
**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
```
### CTR Mode (single chunk)
``` 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
```
### CTR Mode (stream)
``` python
import os
from io import BytesIO
import tgcrypto
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
```
### CBC Mode
**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
```
## License
[LGPLv3+](COPYING.lesser) © 2017-present [Dan](https://github.com/delivrance)
Raw data
{
"_id": null,
"home_page": "https://github.com/pyrogram",
"name": "CrypTGram",
"maintainer": null,
"docs_url": null,
"requires_python": "~=3.9",
"maintainer_email": null,
"keywords": "pyrogram telegram crypto cryptography encryption mtproto extension library aes",
"author": "Dan",
"author_email": "dan@pyrogram.org",
"download_url": "https://github.com/hazy-kun/tgcrypto/releases/latest",
"platform": null,
"description": "# TgCrypto\r\n\r\n> Cryptography Extension Library for Pyrogram\r\n\r\n**TgCrypto** is a Cryptography Library written in C as a Python extension. It is designed to be portable, fast,\r\neasy to install and use. TgCrypto is intended for [Pyrogram](https://github.com/pyrogram/pyrogram) and implements the\r\ncryptographic algorithms Telegram requires, namely:\r\n\r\n- **`AES-256-IGE`** - used in [MTProto v2.0](https://core.telegram.org/mtproto).\r\n- **`AES-256-CTR`** - used for [CDN encrypted files](https://core.telegram.org/cdn).\r\n- **`AES-256-CBC`** - used for [encrypted passport credentials](https://core.telegram.org/passport).\r\n\r\n## Requirements\r\n\r\n- Python 3.9 or higher.\r\n\r\n## Installation\r\n\r\n``` bash\r\n$ pip3 install -U cryptgram\r\n```\r\n\r\n## API\r\n\r\nTgCrypto API consists of these six methods:\r\n\r\n```python\r\ndef ige256_encrypt(data: bytes, key: bytes, iv: bytes) -> bytes: ...\r\ndef ige256_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes: ...\r\n\r\ndef ctr256_encrypt(data: bytes, key: bytes, iv: bytes, state: bytes) -> bytes: ...\r\ndef ctr256_decrypt(data: bytes, key: bytes, iv: bytes, state: bytes) -> bytes: ...\r\n\r\ndef cbc256_encrypt(data: bytes, key: bytes, iv: bytes) -> bytes: ...\r\ndef cbc256_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes: ...\r\n```\r\n\r\n## Usage\r\n\r\n### IGE Mode\r\n\r\n**Note**: Data must be padded to match a multiple of the block size (16 bytes).\r\n\r\n``` python\r\nimport os\r\n\r\nimport tgcrypto\r\n\r\ndata = os.urandom(10 * 1024 * 1024 + 7) # 10 MB of random data + 7 bytes to show padding\r\nkey = os.urandom(32) # Random Key\r\niv = os.urandom(32) # Random IV\r\n\r\n# Pad with zeroes: -7 % 16 = 9\r\ndata += bytes(-len(data) % 16)\r\n\r\nige_encrypted = tgcrypto.ige256_encrypt(data, key, iv)\r\nige_decrypted = tgcrypto.ige256_decrypt(ige_encrypted, key, iv)\r\n\r\nprint(data == ige_decrypted) # True\r\n```\r\n \r\n### CTR Mode (single chunk)\r\n\r\n``` python\r\nimport os\r\n\r\nimport tgcrypto\r\n\r\ndata = os.urandom(10 * 1024 * 1024) # 10 MB of random data\r\n\r\nkey = os.urandom(32) # Random Key\r\n\r\nenc_iv = bytearray(os.urandom(16)) # Random IV\r\ndec_iv = enc_iv.copy() # Keep a copy for decryption\r\n\r\nctr_encrypted = tgcrypto.ctr256_encrypt(data, key, enc_iv, bytes(1))\r\nctr_decrypted = tgcrypto.ctr256_decrypt(ctr_encrypted, key, dec_iv, bytes(1))\r\n\r\nprint(data == ctr_decrypted) # True\r\n```\r\n\r\n### CTR Mode (stream)\r\n\r\n``` python\r\nimport os\r\nfrom io import BytesIO\r\n\r\nimport tgcrypto\r\n\r\ndata = BytesIO(os.urandom(10 * 1024 * 1024)) # 10 MB of random data\r\n\r\nkey = os.urandom(32) # Random Key\r\n\r\nenc_iv = bytearray(os.urandom(16)) # Random IV\r\ndec_iv = enc_iv.copy() # Keep a copy for decryption\r\n\r\nenc_state = bytes(1) # Encryption state, starts from 0\r\ndec_state = bytes(1) # Decryption state, starts from 0\r\n\r\nencrypted_data = BytesIO() # Encrypted data buffer\r\ndecrypted_data = BytesIO() # Decrypted data buffer\r\n\r\nwhile True:\r\n chunk = data.read(1024)\r\n\r\n if not chunk:\r\n break\r\n\r\n # Write 1K encrypted bytes into the encrypted data buffer\r\n encrypted_data.write(tgcrypto.ctr256_encrypt(chunk, key, enc_iv, enc_state))\r\n\r\n# Reset position. We need to read it now\r\nencrypted_data.seek(0)\r\n\r\nwhile True:\r\n chunk = encrypted_data.read(1024)\r\n\r\n if not chunk:\r\n break\r\n\r\n # Write 1K decrypted bytes into the decrypted data buffer\r\n decrypted_data.write(tgcrypto.ctr256_decrypt(chunk, key, dec_iv, dec_state))\r\n\r\nprint(data.getvalue() == decrypted_data.getvalue()) # True\r\n```\r\n\r\n### CBC Mode\r\n\r\n**Note**: Data must be padded to match a multiple of the block size (16 bytes).\r\n\r\n``` python\r\nimport os\r\n\r\nimport tgcrypto\r\n\r\ndata = os.urandom(10 * 1024 * 1024 + 7) # 10 MB of random data + 7 bytes to show padding\r\nkey = os.urandom(32) # Random Key\r\n\r\nenc_iv = bytearray(os.urandom(16)) # Random IV\r\ndec_iv = enc_iv.copy() # Keep a copy for decryption\r\n\r\n# Pad with zeroes: -7 % 16 = 9\r\ndata += bytes(-len(data) % 16)\r\n\r\ncbc_encrypted = tgcrypto.cbc256_encrypt(data, key, enc_iv)\r\ncbc_decrypted = tgcrypto.cbc256_decrypt(cbc_encrypted, key, dec_iv)\r\n\r\nprint(data == cbc_decrypted) # True\r\n```\r\n\r\n## License\r\n\r\n[LGPLv3+](COPYING.lesser) \u00a9 2017-present [Dan](https://github.com/delivrance)\r\n",
"bugtrack_url": null,
"license": "LGPLv3+",
"summary": "Fast and Portable Cryptography Extension Library for Pyrogram",
"version": "1.2.6",
"project_urls": {
"Community": "https://t.me/pyrogram",
"Documentation": "https://docs.pyrogram.org",
"Download": "https://github.com/hazy-kun/tgcrypto/releases/latest",
"Homepage": "https://github.com/pyrogram",
"Source": "https://github.com/pyrogram/tgcrypto",
"Tracker": "https://github.com/pyrogram/tgcrypto/issues"
},
"split_keywords": [
"pyrogram",
"telegram",
"crypto",
"cryptography",
"encryption",
"mtproto",
"extension",
"library",
"aes"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "a71276a1f9ec5ca5e60df5428967f7a8d1eb6b84218f96d129f1ff3359e3ce35",
"md5": "55c1920dc4d659455112bdc49a151d9b",
"sha256": "627935df61471bf1f23667e098f7c9b1fad9f021f0dd331a4598c93be2441090"
},
"downloads": -1,
"filename": "CrypTGram-1.2.6-cp311-cp311-win_amd64.whl",
"has_sig": false,
"md5_digest": "55c1920dc4d659455112bdc49a151d9b",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": "~=3.9",
"size": 32418,
"upload_time": "2024-05-04T22:52:28",
"upload_time_iso_8601": "2024-05-04T22:52:28.598706Z",
"url": "https://files.pythonhosted.org/packages/a7/12/76a1f9ec5ca5e60df5428967f7a8d1eb6b84218f96d129f1ff3359e3ce35/CrypTGram-1.2.6-cp311-cp311-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "1a6980039912efb8276b8f6e89644caf95768be24ac5b97c14a734a699af7839",
"md5": "62fcbadcf270251d64d971c78aff2752",
"sha256": "1d3ac424d02e39e5ec4ecf10e0b1b8e3d6e5df2bb66b8f202b84df090d25ea92"
},
"downloads": -1,
"filename": "CrypTGram-1.2.6-cp312-cp312-win_amd64.whl",
"has_sig": false,
"md5_digest": "62fcbadcf270251d64d971c78aff2752",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": "~=3.9",
"size": 32419,
"upload_time": "2024-05-04T22:52:30",
"upload_time_iso_8601": "2024-05-04T22:52:30.866207Z",
"url": "https://files.pythonhosted.org/packages/1a/69/80039912efb8276b8f6e89644caf95768be24ac5b97c14a734a699af7839/CrypTGram-1.2.6-cp312-cp312-win_amd64.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-05-04 22:52:28",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "hazy-kun",
"github_project": "tgcrypto",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "cryptgram"
}