ttcrypto 0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ttcrypto-0.1/.gitignore +97 -0
- ttcrypto-0.1/.gitlab-ci.yml +23 -0
- ttcrypto-0.1/CHANGELOG +7 -0
- ttcrypto-0.1/LICENSE.md +21 -0
- ttcrypto-0.1/Makefile +9 -0
- ttcrypto-0.1/PKG-INFO +152 -0
- ttcrypto-0.1/README.md +119 -0
- ttcrypto-0.1/pyproject.toml +130 -0
- ttcrypto-0.1/setup.cfg +4 -0
- ttcrypto-0.1/tests/cfg.env +0 -0
- ttcrypto-0.1/tests/test_aes.py +58 -0
- ttcrypto-0.1/tests/test_cmd.py +305 -0
- ttcrypto-0.1/tox.toml +13 -0
- ttcrypto-0.1/ttcrypto/__init__.py +9 -0
- ttcrypto-0.1/ttcrypto/aes.py +181 -0
- ttcrypto-0.1/ttcrypto/cmd.py +112 -0
- ttcrypto-0.1/ttcrypto.egg-info/PKG-INFO +152 -0
- ttcrypto-0.1/ttcrypto.egg-info/SOURCES.txt +20 -0
- ttcrypto-0.1/ttcrypto.egg-info/dependency_links.txt +1 -0
- ttcrypto-0.1/ttcrypto.egg-info/entry_points.txt +2 -0
- ttcrypto-0.1/ttcrypto.egg-info/requires.txt +10 -0
- ttcrypto-0.1/ttcrypto.egg-info/top_level.txt +7 -0
ttcrypto-0.1/.gitignore
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# IDE STUFF
|
|
2
|
+
.settings
|
|
3
|
+
.pydevproject
|
|
4
|
+
.project
|
|
5
|
+
*.DS_Store
|
|
6
|
+
**/project.xcworkspace
|
|
7
|
+
*.ipa
|
|
8
|
+
.idea
|
|
9
|
+
|
|
10
|
+
# JS stuff
|
|
11
|
+
node_modules/
|
|
12
|
+
bower_components/
|
|
13
|
+
.fetch.json
|
|
14
|
+
coverage/
|
|
15
|
+
react-built
|
|
16
|
+
static/components/
|
|
17
|
+
static/files/
|
|
18
|
+
static/js-min
|
|
19
|
+
static/css-min
|
|
20
|
+
static/js/
|
|
21
|
+
static/css/
|
|
22
|
+
#!static/js/jsx/*
|
|
23
|
+
index.html
|
|
24
|
+
login.html
|
|
25
|
+
login-two-step.html
|
|
26
|
+
static/google/analytics.js
|
|
27
|
+
|
|
28
|
+
# Python stuff
|
|
29
|
+
MANIFEST
|
|
30
|
+
|
|
31
|
+
# Byte-compiled / optimized / DLL files
|
|
32
|
+
__pycache__/
|
|
33
|
+
*.py[cod]
|
|
34
|
+
|
|
35
|
+
# C extensions
|
|
36
|
+
*.so
|
|
37
|
+
|
|
38
|
+
# Distribution / packaging
|
|
39
|
+
.Python
|
|
40
|
+
env/
|
|
41
|
+
build/
|
|
42
|
+
develop-eggs/
|
|
43
|
+
dist/
|
|
44
|
+
downloads/
|
|
45
|
+
eggs/
|
|
46
|
+
lib/
|
|
47
|
+
lib64/
|
|
48
|
+
parts/
|
|
49
|
+
sdist/
|
|
50
|
+
var/
|
|
51
|
+
*.egg-info/
|
|
52
|
+
.installed.cfg
|
|
53
|
+
*.egg
|
|
54
|
+
|
|
55
|
+
# PyInstaller
|
|
56
|
+
# Usually these files are written by a python script from a template
|
|
57
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
58
|
+
*.manifest
|
|
59
|
+
*.spec
|
|
60
|
+
|
|
61
|
+
# Installer logs
|
|
62
|
+
pip-log.txt
|
|
63
|
+
pip-delete-this-directory.txt
|
|
64
|
+
|
|
65
|
+
# Unit test / coverage reports
|
|
66
|
+
htmlcov/
|
|
67
|
+
.tox/
|
|
68
|
+
.coverage
|
|
69
|
+
.cache
|
|
70
|
+
nosetests.xml
|
|
71
|
+
coverage.xml
|
|
72
|
+
|
|
73
|
+
# Translations
|
|
74
|
+
*.mo
|
|
75
|
+
*.pot
|
|
76
|
+
|
|
77
|
+
# Django stuff:
|
|
78
|
+
*.log
|
|
79
|
+
|
|
80
|
+
# Sphinx documentation
|
|
81
|
+
docs/_build/
|
|
82
|
+
|
|
83
|
+
# PyBuilder
|
|
84
|
+
target/
|
|
85
|
+
|
|
86
|
+
config/kromxr.yaml
|
|
87
|
+
|
|
88
|
+
desktop/app/static
|
|
89
|
+
desktop/TMP/
|
|
90
|
+
desktop/nwjs_download_cache/
|
|
91
|
+
.ropeproject/
|
|
92
|
+
|
|
93
|
+
*.swp
|
|
94
|
+
|
|
95
|
+
*.eggs/
|
|
96
|
+
*.mypy_cache/
|
|
97
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
stages:
|
|
2
|
+
- check
|
|
3
|
+
- test
|
|
4
|
+
|
|
5
|
+
include:
|
|
6
|
+
- component: gitlab.pararamx.ru/pub/cicd/gitleaks@master
|
|
7
|
+
inputs:
|
|
8
|
+
optional: false
|
|
9
|
+
- component: gitlab.pararamx.ru/pub/cicd/words@master
|
|
10
|
+
inputs:
|
|
11
|
+
path: ttcrypto tests
|
|
12
|
+
- component: gitlab.pararamx.ru/pub/cicd/uv_base@master
|
|
13
|
+
- component: gitlab.pararamx.ru/pub/cicd/uv_check@master
|
|
14
|
+
inputs:
|
|
15
|
+
python: python3.11
|
|
16
|
+
isort-args: "--check ttcrypto tests"
|
|
17
|
+
mypy-optional: false
|
|
18
|
+
mypy-args: 'ttcrypto'
|
|
19
|
+
mypy-uvx-args: '--with-requirements pyproject.toml'
|
|
20
|
+
- component: gitlab.pararamx.ru/pub/cicd/uv_test@master
|
|
21
|
+
inputs:
|
|
22
|
+
python: python3.11
|
|
23
|
+
with_db: false
|
ttcrypto-0.1/CHANGELOG
ADDED
ttcrypto-0.1/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Dmitry Vlasov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
ttcrypto-0.1/Makefile
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
clean:
|
|
2
|
+
rm -fr dist/ *.eggs .eggs build/ .coverage htmlcov/ .mypy_cache/ .pytest_cache/ *.log *.egg-info
|
|
3
|
+
find . -name '__pycache__' | xargs rm -rf
|
|
4
|
+
find . -name '*.pyc' | xargs rm -rf
|
|
5
|
+
|
|
6
|
+
release: clean
|
|
7
|
+
pip install twine build
|
|
8
|
+
python -m build --sdist --wheel .
|
|
9
|
+
python -m twine upload dist/*
|
ttcrypto-0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ttcrypto
|
|
3
|
+
Version: 0.1
|
|
4
|
+
Summary: Tools for encryption/decryption
|
|
5
|
+
Author-email: Dmitriy Vlasov <support@tamtamteam.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: cryptography,utils
|
|
8
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
9
|
+
Classifier: Environment :: Plugins
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE.md
|
|
23
|
+
Requires-Dist: cryptography
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: ttutils; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest-runner; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
[![Version][version-image]][pypi-url]
|
|
35
|
+
[![Supported Python Version][py-versions-image]][pypi-url]
|
|
36
|
+
[![Downloads][downloads-image]][pypi-url]
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
# ttCrypto
|
|
41
|
+
|
|
42
|
+
Утилита для шифрования и расшифровки данных в буфере, поточно или в файле.
|
|
43
|
+
|
|
44
|
+
Библиотека содержит функции и консольную утилиту для работы с файлами.
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## Установка
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
pip install ttcrypto
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
## Использование в коде
|
|
55
|
+
|
|
56
|
+
Простое шифрование/расшифровка (AES-256-GCM)
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from ttcrypto import aes
|
|
60
|
+
|
|
61
|
+
encrypted_bytes = aes.encrypt_gcm_plain(text_bytes, passphrase)
|
|
62
|
+
decrypted_bytes = aes.decrypt_gcm_plain(encrypted_bytes, passphrase)
|
|
63
|
+
|
|
64
|
+
assert to_string(decrypted_bytes) == text
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Проточное шифрования по AES-256-GCM
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from ttcrypto import encrypt_gcm_generator
|
|
71
|
+
|
|
72
|
+
enc = encrypt_gcm_generator(passphrase) # инициализируем генератор
|
|
73
|
+
encrypted_bytes = enc.send(None) # генерируем salt + nonce для сессии
|
|
74
|
+
encrypted_bytes += enc.send(b'123') # отправляем порцию данных (в цикле)
|
|
75
|
+
encrypted_bytes += enc.send(b'') # отправляем пустую строку для финализации
|
|
76
|
+
encrypted_bytes = next(enc) + encrypted_bytes # next вычисляет tag, ставим его в начало
|
|
77
|
+
# encrypted_bytes = tag(16) + salt(16) + nonce(16) + ciphertext
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Проточная расшифровка по AES-256-GCM
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from ttcrypto import decrypt_gcm_generator
|
|
84
|
+
|
|
85
|
+
dec = decrypt_gcm_generator(passphrase) # инициализируем генератор
|
|
86
|
+
dec.send(None) # инициализируем ввод (всегда отвечает b'')
|
|
87
|
+
data = dec.send(encrypted_bytes) # отправляем порцию данных (в цикле) - не менее 45 байт
|
|
88
|
+
data += dec.send(b'') # отправляем b'' для финализации
|
|
89
|
+
# data - оригинальные расшифрованные данные
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## Консольная утилита
|
|
94
|
+
|
|
95
|
+
Шифрование/расшифровка файла (интерактивный ввод секрета)
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
$ ttcrypto -e source.txt target.enc
|
|
99
|
+
$ ttcrypto -d source.enc target.txt
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Шифрование с перезаписью целевого файла и передаченй секрета в команде
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
$ export TTCRYPTO_PASSPHRASE=123
|
|
106
|
+
$ ttcrypto -efp `echo $TTCRYPTO_PASSPHRASE` source.txt target.enc
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Шифрование/расшифровке всех файлов в директории
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
$ ttcrypto -e source_dir encrypted_files_dir
|
|
113
|
+
$ ttcrypto -d encrypted_files_dir origin_files_dir
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Шифрование файлов в директории, подходящих по имени
|
|
117
|
+
|
|
118
|
+
```sh
|
|
119
|
+
$ ttcrypto -e -n '*.txt' source_dir encrypted_files_dir
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
## Модуль криптографии AES-256-GCM (PBKDF2HMAC)
|
|
124
|
+
|
|
125
|
+
Cодержит:
|
|
126
|
+
- функции шифрования/расшифровки байтов (с полной буферизацией),
|
|
127
|
+
- функции-генераторы для поточного шифрования/расшифровки (без полной буферизации)
|
|
128
|
+
- функции для работы с BufferedIOBase объектами (с интерфейсов файлов)
|
|
129
|
+
|
|
130
|
+
Сложность реализации поточной обработки при использовании GCM алгоритма заключается в том,
|
|
131
|
+
что подпись (tag) вычисляется после обратки всех данных и как правило дописывается в конец файла.
|
|
132
|
+
Но при расшифровке подпись нужна до обратки данных - а чтение файла с конца не всегда возвожно.
|
|
133
|
+
Поэтому решено записывать тег в начало контейнера, вместе с другими метаданными:
|
|
134
|
+
|
|
135
|
+
` tag(16) + salt(16) + nonce(12) + ciphertext`
|
|
136
|
+
|
|
137
|
+
При работе с файловыми объектами в начало записывается 16 нулевых байт - чтоб
|
|
138
|
+
зарезервировать место для подписи (tag). В конце шифрования, когда будет вычислен tag -
|
|
139
|
+
курсор переставляется в начало файла и 16 нулевых байт перезаписываются подписью.
|
|
140
|
+
Для системы которая один раз пишет - много читает, возможность сразу направить поток
|
|
141
|
+
расшифрованных данных потребителю критически важна.
|
|
142
|
+
|
|
143
|
+
- Файл 3,5Гб: шифрование ~ 4 сек, расшифровка ~ 3.8 сек (1 CPU ~ 70%, RAM ~ 50Мб)
|
|
144
|
+
- Файл 9,4Мб: шифрование ~ 17.7 мс, расшифровка ~ 16.8 мс
|
|
145
|
+
- Файл 68Кб: шифрование ~ 11 мс, расшифровка ~ 9.5 мс
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
<!-- Badges -->
|
|
149
|
+
[pypi-url]: https://pypi.org/project/ttcrypto
|
|
150
|
+
[version-image]: https://img.shields.io/pypi/v/ttcrypto.svg
|
|
151
|
+
[py-versions-image]: https://img.shields.io/pypi/pyversions/ttcrypto.svg
|
|
152
|
+
[downloads-image]: https://img.shields.io/pypi/dm/ttcrypto.svg
|
ttcrypto-0.1/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
[![Version][version-image]][pypi-url]
|
|
2
|
+
[![Supported Python Version][py-versions-image]][pypi-url]
|
|
3
|
+
[![Downloads][downloads-image]][pypi-url]
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ttCrypto
|
|
8
|
+
|
|
9
|
+
Утилита для шифрования и расшифровки данных в буфере, поточно или в файле.
|
|
10
|
+
|
|
11
|
+
Библиотека содержит функции и консольную утилиту для работы с файлами.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## Установка
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
pip install ttcrypto
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## Использование в коде
|
|
22
|
+
|
|
23
|
+
Простое шифрование/расшифровка (AES-256-GCM)
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from ttcrypto import aes
|
|
27
|
+
|
|
28
|
+
encrypted_bytes = aes.encrypt_gcm_plain(text_bytes, passphrase)
|
|
29
|
+
decrypted_bytes = aes.decrypt_gcm_plain(encrypted_bytes, passphrase)
|
|
30
|
+
|
|
31
|
+
assert to_string(decrypted_bytes) == text
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Проточное шифрования по AES-256-GCM
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from ttcrypto import encrypt_gcm_generator
|
|
38
|
+
|
|
39
|
+
enc = encrypt_gcm_generator(passphrase) # инициализируем генератор
|
|
40
|
+
encrypted_bytes = enc.send(None) # генерируем salt + nonce для сессии
|
|
41
|
+
encrypted_bytes += enc.send(b'123') # отправляем порцию данных (в цикле)
|
|
42
|
+
encrypted_bytes += enc.send(b'') # отправляем пустую строку для финализации
|
|
43
|
+
encrypted_bytes = next(enc) + encrypted_bytes # next вычисляет tag, ставим его в начало
|
|
44
|
+
# encrypted_bytes = tag(16) + salt(16) + nonce(16) + ciphertext
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Проточная расшифровка по AES-256-GCM
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from ttcrypto import decrypt_gcm_generator
|
|
51
|
+
|
|
52
|
+
dec = decrypt_gcm_generator(passphrase) # инициализируем генератор
|
|
53
|
+
dec.send(None) # инициализируем ввод (всегда отвечает b'')
|
|
54
|
+
data = dec.send(encrypted_bytes) # отправляем порцию данных (в цикле) - не менее 45 байт
|
|
55
|
+
data += dec.send(b'') # отправляем b'' для финализации
|
|
56
|
+
# data - оригинальные расшифрованные данные
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## Консольная утилита
|
|
61
|
+
|
|
62
|
+
Шифрование/расшифровка файла (интерактивный ввод секрета)
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
$ ttcrypto -e source.txt target.enc
|
|
66
|
+
$ ttcrypto -d source.enc target.txt
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Шифрование с перезаписью целевого файла и передаченй секрета в команде
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
$ export TTCRYPTO_PASSPHRASE=123
|
|
73
|
+
$ ttcrypto -efp `echo $TTCRYPTO_PASSPHRASE` source.txt target.enc
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Шифрование/расшифровке всех файлов в директории
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
$ ttcrypto -e source_dir encrypted_files_dir
|
|
80
|
+
$ ttcrypto -d encrypted_files_dir origin_files_dir
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Шифрование файлов в директории, подходящих по имени
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
$ ttcrypto -e -n '*.txt' source_dir encrypted_files_dir
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
## Модуль криптографии AES-256-GCM (PBKDF2HMAC)
|
|
91
|
+
|
|
92
|
+
Cодержит:
|
|
93
|
+
- функции шифрования/расшифровки байтов (с полной буферизацией),
|
|
94
|
+
- функции-генераторы для поточного шифрования/расшифровки (без полной буферизации)
|
|
95
|
+
- функции для работы с BufferedIOBase объектами (с интерфейсов файлов)
|
|
96
|
+
|
|
97
|
+
Сложность реализации поточной обработки при использовании GCM алгоритма заключается в том,
|
|
98
|
+
что подпись (tag) вычисляется после обратки всех данных и как правило дописывается в конец файла.
|
|
99
|
+
Но при расшифровке подпись нужна до обратки данных - а чтение файла с конца не всегда возвожно.
|
|
100
|
+
Поэтому решено записывать тег в начало контейнера, вместе с другими метаданными:
|
|
101
|
+
|
|
102
|
+
` tag(16) + salt(16) + nonce(12) + ciphertext`
|
|
103
|
+
|
|
104
|
+
При работе с файловыми объектами в начало записывается 16 нулевых байт - чтоб
|
|
105
|
+
зарезервировать место для подписи (tag). В конце шифрования, когда будет вычислен tag -
|
|
106
|
+
курсор переставляется в начало файла и 16 нулевых байт перезаписываются подписью.
|
|
107
|
+
Для системы которая один раз пишет - много читает, возможность сразу направить поток
|
|
108
|
+
расшифрованных данных потребителю критически важна.
|
|
109
|
+
|
|
110
|
+
- Файл 3,5Гб: шифрование ~ 4 сек, расшифровка ~ 3.8 сек (1 CPU ~ 70%, RAM ~ 50Мб)
|
|
111
|
+
- Файл 9,4Мб: шифрование ~ 17.7 мс, расшифровка ~ 16.8 мс
|
|
112
|
+
- Файл 68Кб: шифрование ~ 11 мс, расшифровка ~ 9.5 мс
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
<!-- Badges -->
|
|
116
|
+
[pypi-url]: https://pypi.org/project/ttcrypto
|
|
117
|
+
[version-image]: https://img.shields.io/pypi/v/ttcrypto.svg
|
|
118
|
+
[py-versions-image]: https://img.shields.io/pypi/pyversions/ttcrypto.svg
|
|
119
|
+
[downloads-image]: https://img.shields.io/pypi/dm/ttcrypto.svg
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ['setuptools', 'setuptools-scm']
|
|
3
|
+
build-backend = 'setuptools.build_meta'
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = 'ttcrypto'
|
|
7
|
+
authors = [
|
|
8
|
+
{name = 'Dmitriy Vlasov', email = 'support@tamtamteam.com'},
|
|
9
|
+
]
|
|
10
|
+
description = 'Tools for encryption/decryption'
|
|
11
|
+
readme = 'README.md'
|
|
12
|
+
requires-python = '>=3.10'
|
|
13
|
+
classifiers = [
|
|
14
|
+
'Development Status :: 5 - Production/Stable',
|
|
15
|
+
'Environment :: Plugins',
|
|
16
|
+
'Intended Audience :: Developers',
|
|
17
|
+
'License :: OSI Approved :: Apache Software License',
|
|
18
|
+
'Programming Language :: Python',
|
|
19
|
+
'Programming Language :: Python :: 3',
|
|
20
|
+
'Programming Language :: Python :: 3.10',
|
|
21
|
+
'Programming Language :: Python :: 3.11',
|
|
22
|
+
'Programming Language :: Python :: 3.12',
|
|
23
|
+
'Programming Language :: Python :: 3.13',
|
|
24
|
+
'Programming Language :: Python :: 3.14',
|
|
25
|
+
'Topic :: Software Development :: Libraries :: Python Modules',
|
|
26
|
+
]
|
|
27
|
+
dependencies = [
|
|
28
|
+
'cryptography',
|
|
29
|
+
]
|
|
30
|
+
keywords = [
|
|
31
|
+
'cryptography',
|
|
32
|
+
'utils'
|
|
33
|
+
]
|
|
34
|
+
license = {text = 'MIT'}
|
|
35
|
+
dynamic = ['version']
|
|
36
|
+
|
|
37
|
+
[project.optional-dependencies]
|
|
38
|
+
dev = [
|
|
39
|
+
'ttutils',
|
|
40
|
+
'pytest-runner',
|
|
41
|
+
'pytest',
|
|
42
|
+
'pytest-cov',
|
|
43
|
+
'pytest-asyncio',
|
|
44
|
+
'ruff',
|
|
45
|
+
'mypy',
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[project.entry-points.'console_scripts']
|
|
49
|
+
ttcrypto = 'ttcrypto.cmd:run'
|
|
50
|
+
|
|
51
|
+
[tool.setuptools.dynamic]
|
|
52
|
+
version = {attr = 'ttcrypto.__version__'}
|
|
53
|
+
|
|
54
|
+
[tool.setuptools.packages.find]
|
|
55
|
+
exclude=['tests.*', 'tests']
|
|
56
|
+
|
|
57
|
+
[tool.setuptools.package-data]
|
|
58
|
+
'ttcrypto' = ['py.typed']
|
|
59
|
+
|
|
60
|
+
[tool.pytest.ini_options]
|
|
61
|
+
addopts = '--verbose --cov=ttcrypto --cov-report=html --asyncio-mode=auto'
|
|
62
|
+
testpaths = [
|
|
63
|
+
'tests',
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
[tool.coverage.run]
|
|
67
|
+
branch = true
|
|
68
|
+
omit = ['tests/*']
|
|
69
|
+
|
|
70
|
+
[tool.ruff]
|
|
71
|
+
line-length = 100
|
|
72
|
+
target-version = 'py310'
|
|
73
|
+
preview = true
|
|
74
|
+
|
|
75
|
+
[tool.ruff.lint]
|
|
76
|
+
preview = true
|
|
77
|
+
select = [
|
|
78
|
+
'E', 'W', 'PL', 'C90', 'N', 'UP',
|
|
79
|
+
# pep8-errors, pep8-warn, pylint, mccabe, pep8-naming, pyupgrade, isort
|
|
80
|
+
'F', 'B', 'A', 'T20', 'BLE', 'RET',
|
|
81
|
+
# flake8, flake8-bugbear, flake8-builtins, flake8-print, flake8-blind-except, flake8-return
|
|
82
|
+
'ANN', 'ASYNC', 'DTZ', 'ISC', 'Q',
|
|
83
|
+
# flake8-annotations, flake8-async, flake8-datetimez, flake8-implicit-str-concat, flake8-quotes
|
|
84
|
+
]
|
|
85
|
+
ignore = [
|
|
86
|
+
'PLR6301', # no-self-use
|
|
87
|
+
'ANN401', # Dynamically typed expressions (typing.Any) are disallowed
|
|
88
|
+
]
|
|
89
|
+
|
|
90
|
+
[tool.ruff.lint.per-file-ignores]
|
|
91
|
+
'tests/test_cmd.py' = ['PLR0913', 'PLR0917']
|
|
92
|
+
'tests/*' = [
|
|
93
|
+
'PLR2004', # Checks for the use of unnamed numerical constants ('magic') values in comparisons
|
|
94
|
+
'PLC1901', # Checks for comparisons to empty strings
|
|
95
|
+
'ANN', # flake8-annotations
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
[tool.ruff.lint.mccabe]
|
|
99
|
+
max-complexity = 10
|
|
100
|
+
|
|
101
|
+
[tool.ruff.lint.pep8-naming]
|
|
102
|
+
extend-ignore-names = ['test_*']
|
|
103
|
+
|
|
104
|
+
[tool.ruff.lint.flake8-annotations]
|
|
105
|
+
allow-star-arg-any = true
|
|
106
|
+
|
|
107
|
+
[tool.ruff.lint.flake8-quotes]
|
|
108
|
+
inline-quotes = 'single'
|
|
109
|
+
docstring-quotes = 'single'
|
|
110
|
+
multiline-quotes = 'single'
|
|
111
|
+
avoid-escape = false
|
|
112
|
+
|
|
113
|
+
[tool.ruff.lint.isort]
|
|
114
|
+
case-sensitive = true
|
|
115
|
+
combine-as-imports = true
|
|
116
|
+
lines-after-imports = 2
|
|
117
|
+
lines-between-types = 1
|
|
118
|
+
split-on-trailing-comma = false
|
|
119
|
+
|
|
120
|
+
[tool.mypy]
|
|
121
|
+
show_error_codes = true
|
|
122
|
+
warn_redundant_casts = true
|
|
123
|
+
follow_imports = 'normal'
|
|
124
|
+
strict_optional = true
|
|
125
|
+
warn_unused_ignores = true
|
|
126
|
+
warn_unreachable = true
|
|
127
|
+
warn_no_return = true
|
|
128
|
+
disallow_untyped_defs = true
|
|
129
|
+
disallow_incomplete_defs = true
|
|
130
|
+
ignore_missing_imports = true
|
ttcrypto-0.1/setup.cfg
ADDED
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
|
|
3
|
+
from ttutils import to_bytes, to_string
|
|
4
|
+
|
|
5
|
+
from ttcrypto import aes
|
|
6
|
+
|
|
7
|
+
passphrase = b'asdqwe123zxc'
|
|
8
|
+
text = 'абвгд%asd^123'
|
|
9
|
+
text_bytes = to_bytes(text, 'utf8')
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_encrypt_decrypt_gcm_plain_ok() -> None:
|
|
13
|
+
encrypted_bytes = aes.encrypt_gcm_plain(text_bytes, passphrase)
|
|
14
|
+
decrypted_bytes = aes.decrypt_gcm_plain(encrypted_bytes, passphrase)
|
|
15
|
+
assert to_string(decrypted_bytes) == text
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_encrypt_gcm_generator_ok() -> None:
|
|
19
|
+
enc = aes.encrypt_gcm_generator(passphrase)
|
|
20
|
+
encrypted_bytes = enc.send(None)
|
|
21
|
+
encrypted_bytes += enc.send(text_bytes)
|
|
22
|
+
encrypted_bytes += enc.send(b'')
|
|
23
|
+
encrypted_bytes = next(enc) + encrypted_bytes
|
|
24
|
+
|
|
25
|
+
decrypted_bytes = aes.decrypt_gcm_plain(encrypted_bytes, passphrase)
|
|
26
|
+
assert to_string(decrypted_bytes) == text
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_decrypt_gcm_generator_ok() -> None:
|
|
30
|
+
encrypted_bytes = aes.encrypt_gcm_plain(text_bytes, passphrase)
|
|
31
|
+
|
|
32
|
+
dec = aes.decrypt_gcm_generator(passphrase)
|
|
33
|
+
dec.send(None)
|
|
34
|
+
decrypted_bytes = dec.send(encrypted_bytes)
|
|
35
|
+
decrypted_bytes += dec.send(b'')
|
|
36
|
+
|
|
37
|
+
assert to_string(decrypted_bytes) == text
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_encrypt_gcm_io_ok() -> None:
|
|
41
|
+
input_io = BytesIO(text_bytes)
|
|
42
|
+
output_io = BytesIO(b'')
|
|
43
|
+
|
|
44
|
+
aes.encrypt_gcm_io(passphrase, input_io, output_io)
|
|
45
|
+
|
|
46
|
+
decrypted_bytes = aes.decrypt_gcm_plain(output_io.read(), passphrase)
|
|
47
|
+
assert to_string(decrypted_bytes) == text
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_decrypt_gcm_io_ok() -> None:
|
|
51
|
+
encrypted_bytes = aes.encrypt_gcm_plain(text_bytes, passphrase)
|
|
52
|
+
|
|
53
|
+
input_io = BytesIO(encrypted_bytes)
|
|
54
|
+
output_io = BytesIO(b'')
|
|
55
|
+
|
|
56
|
+
aes.decrypt_gcm_io(passphrase, input_io, output_io)
|
|
57
|
+
|
|
58
|
+
assert to_string(output_io.read()) == text
|