Various improvements (#24)

This commit is contained in:
Dan 2021-10-11 18:18:46 +02:00 committed by GitHub
parent a3164a03c8
commit 4102d3b116
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 111 additions and 70 deletions

View File

@ -2,24 +2,15 @@
<img src="https://i.imgur.com/JyxrStE.png" width="160" align="right"> <img src="https://i.imgur.com/JyxrStE.png" width="160" align="right">
> Fast and Portable Telegram Crypto Library for Python > Fast and Portable Cryptography Extension Library for Pyrogram
**TgCrypto** is a Telegram Crypto Library written in C89 as a Python extension. It is designed to be portable, fast, easy **TgCrypto** is a Cryptography Library written in C as a Python extension. It is designed to be portable, fast,
to install and use. TgCrypto is intended for [Pyrogram](https://github.com/pyrogram/pyrogram) and implements the crypto easy to install and use. TgCrypto is intended for [Pyrogram](https://github.com/pyrogram/pyrogram) and implements the
algorithms Telegram requires, namely: cryptographic algorithms Telegram requires, namely:
- **`AES256-IGE`** - used in [MTProto v2.0](https://core.telegram.org/mtproto). - **`AES-256-IGE`** - used in [MTProto v2.0](https://core.telegram.org/mtproto).
- **`AES256-CTR`** - used for [CDN encrypted files](https://core.telegram.org/cdn). - **`AES-256-CTR`** - used for [CDN encrypted files](https://core.telegram.org/cdn).
- **`AES256-CBC`** - used for [encrypted passport credentials](https://core.telegram.org/passport). - **`AES-256-CBC`** - used for [encrypted passport credentials](https://core.telegram.org/passport).
Python [wheels are available](https://pypi.org/project/TgCrypto/#files) for hassle-free installations; they are
automatically built and tested using Travis CI for Linux (i686, x86_64, AArch64), Windows (32-bit, 64-bit) and macOS
(x86_64).
Even though TgCrypto is primarily intended for use with Pyrogram, you are free and welcome to use it for any other
Python project too, as it's shipped as standalone package.
More info: https://docs.pyrogram.org/topics/tgcrypto
## Requirements ## Requirements
@ -163,7 +154,8 @@ print(data == cbc_decrypted) # True
1. Clone this repository: `git clone https://github.com/pyrogram/tgcrypto`. 1. Clone this repository: `git clone https://github.com/pyrogram/tgcrypto`.
2. Enter the directory: `cd tgcrypto`. 2. Enter the directory: `cd tgcrypto`.
3. Run tests: `python3 setup.py test`. 3. Install `tox`: `pip3 install tox`
4. Run tests: `tox`.
## License ## License

3
pyproject.toml Normal file
View File

@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

View File

@ -24,7 +24,7 @@ with open("README.md", encoding="utf-8") as f:
setup( setup(
name="TgCrypto", name="TgCrypto",
version="1.2.2", version="1.2.2",
description="Fast Telegram Crypto Library for Python", description="Fast and Portable Cryptography Extension Library for Pyrogram",
long_description=readme, long_description=readme,
long_description_content_type="text/markdown", long_description_content_type="text/markdown",
url="https://github.com/pyrogram", url="https://github.com/pyrogram",
@ -40,12 +40,11 @@ setup(
"Programming Language :: C", "Programming Language :: C",
"Programming Language :: Python", "Programming Language :: Python",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: Implementation", "Programming Language :: Python :: Implementation",
"Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: Implementation :: PyPy",
@ -57,7 +56,7 @@ setup(
"Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries",
"Topic :: Software Development :: Libraries :: Python Modules" "Topic :: Software Development :: Libraries :: Python Modules"
], ],
keywords="fast pyrogram telegram crypto mtproto api client library python", keywords="pyrogram telegram crypto cryptography encryption mtproto extension library aes",
project_urls={ project_urls={
"Tracker": "https://github.com/pyrogram/tgcrypto/issues", "Tracker": "https://github.com/pyrogram/tgcrypto/issues",
"Community": "https://t.me/pyrogram", "Community": "https://t.me/pyrogram",

View File

@ -306,25 +306,6 @@ static const uint32_t Td3[256] = {
0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0 0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0
}; };
static const uint8_t Td4[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
static const uint8_t SBOX[16][16] = { static const uint8_t SBOX[16][16] = {
{0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76}, {0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76},
{0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0}, {0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0},
@ -344,6 +325,25 @@ static const uint8_t SBOX[16][16] = {
{0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16} {0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}
}; };
static const uint8_t SBOX1[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
static const uint32_t RCON[10] = { static const uint32_t RCON[10] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000 0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000
@ -591,40 +591,40 @@ void aes256_decrypt(const uint8_t in[16], uint8_t out[16], const uint32_t key[60
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ key[55]; t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ key[55];
s0 = ( s0 = (
((uint32_t) Td4[(t0 >> 24)] << 24) ((uint32_t) SBOX1[(t0 >> 24)] << 24)
^ ((uint32_t) Td4[(t3 >> 16) & 0xff] << 16) ^ ((uint32_t) SBOX1[(t3 >> 16) & 0xff] << 16)
^ ((uint32_t) Td4[(t2 >> 8) & 0xff] << 8) ^ ((uint32_t) SBOX1[(t2 >> 8) & 0xff] << 8)
^ ((uint32_t) Td4[(t1) & 0xff]) ^ ((uint32_t) SBOX1[(t1) & 0xff])
^ key[56] ^ key[56]
); );
PUT(out, s0); PUT(out, s0);
s1 = ( s1 = (
((uint32_t) Td4[(t1 >> 24)] << 24) ((uint32_t) SBOX1[(t1 >> 24)] << 24)
^ ((uint32_t) Td4[(t0 >> 16) & 0xff] << 16) ^ ((uint32_t) SBOX1[(t0 >> 16) & 0xff] << 16)
^ ((uint32_t) Td4[(t3 >> 8) & 0xff] << 8) ^ ((uint32_t) SBOX1[(t3 >> 8) & 0xff] << 8)
^ ((uint32_t) Td4[(t2) & 0xff]) ^ ((uint32_t) SBOX1[(t2) & 0xff])
^ key[57] ^ key[57]
); );
PUT(out + 4, s1); PUT(out + 4, s1);
s2 = ( s2 = (
((uint32_t) Td4[(t2 >> 24)] << 24) ((uint32_t) SBOX1[(t2 >> 24)] << 24)
^ ((uint32_t) Td4[(t1 >> 16) & 0xff] << 16) ^ ((uint32_t) SBOX1[(t1 >> 16) & 0xff] << 16)
^ ((uint32_t) Td4[(t0 >> 8) & 0xff] << 8) ^ ((uint32_t) SBOX1[(t0 >> 8) & 0xff] << 8)
^ ((uint32_t) Td4[(t3) & 0xff]) ^ ((uint32_t) SBOX1[(t3) & 0xff])
^ key[58] ^ key[58]
); );
PUT(out + 8, s2); PUT(out + 8, s2);
s3 = ( s3 = (
((uint32_t) Td4[(t3 >> 24)] << 24) ((uint32_t) SBOX1[(t3 >> 24)] << 24)
^ ((uint32_t) Td4[(t2 >> 16) & 0xff] << 16) ^ ((uint32_t) SBOX1[(t2 >> 16) & 0xff] << 16)
^ ((uint32_t) Td4[(t1 >> 8) & 0xff] << 8) ^ ((uint32_t) SBOX1[(t1 >> 8) & 0xff] << 8)
^ ((uint32_t) Td4[(t0) & 0xff]) ^ ((uint32_t) SBOX1[(t0) & 0xff])
^ key[59] ^ key[59]
); );

View File

@ -19,6 +19,7 @@
*/ */
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include "aes256.h" #include "aes256.h"
@ -26,6 +27,10 @@
#include "ctr256.h" #include "ctr256.h"
#include "cbc256.h" #include "cbc256.h"
#define DESCRIPTION "Fast and Portable Cryptography Extension Library for Pyrogram\n" \
"TgCrypto is part of Pyrogram, a Telegram MTProto library for Python\n" \
"You can learn more about Pyrogram here: https://pyrogram.org\n"
static PyObject *ige(PyObject *args, uint8_t encrypt) { static PyObject *ige(PyObject *args, uint8_t encrypt) {
Py_buffer data, key, iv; Py_buffer data, key, iv;
uint8_t *buf; uint8_t *buf;
@ -55,7 +60,7 @@ static PyObject *ige(PyObject *args, uint8_t encrypt) {
} }
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
buf = ige256(data.buf, data.len, key.buf, iv.buf, encrypt); buf = ige256(data.buf, data.len, key.buf, iv.buf, encrypt);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
PyBuffer_Release(&data); PyBuffer_Release(&data);
@ -110,7 +115,7 @@ static PyObject *ctr256_encrypt(PyObject *self, PyObject *args) {
} }
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
buf = ctr256(data.buf, data.len, key.buf, iv.buf, state.buf); buf = ctr256(data.buf, data.len, key.buf, iv.buf, state.buf);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
PyBuffer_Release(&data); PyBuffer_Release(&data);
@ -152,7 +157,7 @@ static PyObject *cbc(PyObject *args, uint8_t encrypt) {
} }
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
buf = cbc256(data.buf, data.len, key.buf, iv.buf, encrypt); buf = cbc256(data.buf, data.len, key.buf, iv.buf, encrypt);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
PyBuffer_Release(&data); PyBuffer_Release(&data);
@ -173,20 +178,62 @@ static PyObject *cbc256_decrypt(PyObject *self, PyObject *args) {
return cbc(args, 0); return cbc(args, 0);
} }
PyDoc_STRVAR(
ige256_encrypt_docs,
"ige256_encrypt(data, key, iv)\n"
"--\n\n"
"AES-256-IGE Encryption"
);
PyDoc_STRVAR(
ige256_decrypt_docs,
"ige256_decrypt(data, key, iv)\n"
"--\n\n"
"AES-256-IGE Decryption"
);
PyDoc_STRVAR(
ctr256_encrypt_docs,
"ctr256_encrypt(data, key, iv, state)\n"
"--\n\n"
"AES-256-CTR Encryption"
);
PyDoc_STRVAR(
ctr256_decrypt_docs,
"ctr256_decrypt(data, key, iv, state)\n"
"--\n\n"
"AES-256-CTR Decryption"
);
PyDoc_STRVAR(
cbc256_encrypt_docs,
"cbc256_encrypt(data, key, iv)\n"
"--\n\n"
"AES-256-CBC Encryption"
);
PyDoc_STRVAR(
cbc256_decrypt_docs,
"cbc256_decrypt(data, key, iv)\n"
"--\n\n"
"AES-256-CBC Encryption"
);
static PyMethodDef methods[] = { static PyMethodDef methods[] = {
{"ige256_encrypt", (PyCFunction) ige256_encrypt, METH_VARARGS, "AES256-IGE Encryption"}, {"ige256_encrypt", (PyCFunction) ige256_encrypt, METH_VARARGS, ige256_encrypt_docs},
{"ige256_decrypt", (PyCFunction) ige256_decrypt, METH_VARARGS, "AES256-IGE Decryption"}, {"ige256_decrypt", (PyCFunction) ige256_decrypt, METH_VARARGS, ige256_decrypt_docs},
{"ctr256_encrypt", (PyCFunction) ctr256_encrypt, METH_VARARGS, "AES256-CTR Encryption"}, {"ctr256_encrypt", (PyCFunction) ctr256_encrypt, METH_VARARGS, ctr256_encrypt_docs},
{"ctr256_decrypt", (PyCFunction) ctr256_encrypt, METH_VARARGS, "AES256-CTR Decryption"}, {"ctr256_decrypt", (PyCFunction) ctr256_encrypt, METH_VARARGS, ctr256_decrypt_docs},
{"cbc256_encrypt", (PyCFunction) cbc256_encrypt, METH_VARARGS, "AES256-CBC Encryption"}, {"cbc256_encrypt", (PyCFunction) cbc256_encrypt, METH_VARARGS, cbc256_encrypt_docs},
{"cbc256_decrypt", (PyCFunction) cbc256_decrypt, METH_VARARGS, "AES256-CBC Decryption"}, {"cbc256_decrypt", (PyCFunction) cbc256_decrypt, METH_VARARGS, cbc256_decrypt_docs},
{NULL, NULL, 0, NULL} {NULL}
}; };
static struct PyModuleDef module = { static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT, PyModuleDef_HEAD_INIT,
"tgcrypto", "TgCrypto",
"Telegram Crypto for Pyrogram", DESCRIPTION,
-1, -1,
methods methods
}; };

View File

@ -1,3 +1,3 @@
[testenv] [testenv]
deps = pytest deps = pytest
commands = pytest {posargs} commands = pytest {posargs}