pyaegis 0.1.0__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.
- pyaegis-0.1.0/LICENSE +21 -0
- pyaegis-0.1.0/MANIFEST.in +19 -0
- pyaegis-0.1.0/PKG-INFO +264 -0
- pyaegis-0.1.0/README.md +224 -0
- pyaegis-0.1.0/benchmark.py +246 -0
- pyaegis-0.1.0/build_cffi.py +233 -0
- pyaegis-0.1.0/c_src/aegis128l/aegis128l.c +261 -0
- pyaegis-0.1.0/c_src/aegis128l/aegis128l_aesni.c +74 -0
- pyaegis-0.1.0/c_src/aegis128l/aegis128l_aesni.h +9 -0
- pyaegis-0.1.0/c_src/aegis128l/aegis128l_altivec.c +71 -0
- pyaegis-0.1.0/c_src/aegis128l/aegis128l_altivec.h +9 -0
- pyaegis-0.1.0/c_src/aegis128l/aegis128l_common.h +694 -0
- pyaegis-0.1.0/c_src/aegis128l/aegis128l_neon_aes.c +78 -0
- pyaegis-0.1.0/c_src/aegis128l/aegis128l_neon_aes.h +9 -0
- pyaegis-0.1.0/c_src/aegis128l/aegis128l_neon_sha3.c +83 -0
- pyaegis-0.1.0/c_src/aegis128l/aegis128l_neon_sha3.h +9 -0
- pyaegis-0.1.0/c_src/aegis128l/aegis128l_soft.c +64 -0
- pyaegis-0.1.0/c_src/aegis128l/aegis128l_soft.h +9 -0
- pyaegis-0.1.0/c_src/aegis128l/implementations.h +39 -0
- pyaegis-0.1.0/c_src/aegis128x2/aegis128x2.c +262 -0
- pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_aesni.c +109 -0
- pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_aesni.h +9 -0
- pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_altivec.c +104 -0
- pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_altivec.h +9 -0
- pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_avx2.c +79 -0
- pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_avx2.h +11 -0
- pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_common.h +799 -0
- pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_neon_aes.c +112 -0
- pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_neon_aes.h +9 -0
- pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_soft.c +97 -0
- pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_soft.h +9 -0
- pyaegis-0.1.0/c_src/aegis128x2/implementations.h +39 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4.c +267 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_aesni.c +118 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_aesni.h +9 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_altivec.c +112 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_altivec.h +9 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_avx2.c +112 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_avx2.h +11 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_avx512.c +85 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_avx512.h +11 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_common.h +814 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_neon_aes.c +120 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_neon_aes.h +9 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_soft.c +105 -0
- pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_soft.h +9 -0
- pyaegis-0.1.0/c_src/aegis128x4/implementations.h +39 -0
- pyaegis-0.1.0/c_src/aegis256/aegis256.c +255 -0
- pyaegis-0.1.0/c_src/aegis256/aegis256_aesni.c +69 -0
- pyaegis-0.1.0/c_src/aegis256/aegis256_aesni.h +9 -0
- pyaegis-0.1.0/c_src/aegis256/aegis256_altivec.c +69 -0
- pyaegis-0.1.0/c_src/aegis256/aegis256_altivec.h +9 -0
- pyaegis-0.1.0/c_src/aegis256/aegis256_common.h +680 -0
- pyaegis-0.1.0/c_src/aegis256/aegis256_neon_aes.c +76 -0
- pyaegis-0.1.0/c_src/aegis256/aegis256_neon_aes.h +9 -0
- pyaegis-0.1.0/c_src/aegis256/aegis256_soft.c +59 -0
- pyaegis-0.1.0/c_src/aegis256/aegis256_soft.h +9 -0
- pyaegis-0.1.0/c_src/aegis256/implementations.h +39 -0
- pyaegis-0.1.0/c_src/aegis256x2/aegis256x2.c +262 -0
- pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_aesni.c +104 -0
- pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_aesni.h +9 -0
- pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_altivec.c +102 -0
- pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_altivec.h +9 -0
- pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_avx2.c +74 -0
- pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_avx2.h +11 -0
- pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_common.h +795 -0
- pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_neon_aes.c +110 -0
- pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_neon_aes.h +9 -0
- pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_soft.c +92 -0
- pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_soft.h +9 -0
- pyaegis-0.1.0/c_src/aegis256x2/implementations.h +40 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4.c +267 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_aesni.c +113 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_aesni.h +9 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_altivec.c +110 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_altivec.h +9 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_avx2.c +107 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_avx2.h +11 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_avx512.c +80 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_avx512.h +11 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_common.h +814 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_neon_aes.c +118 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_neon_aes.h +9 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_soft.c +100 -0
- pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_soft.h +9 -0
- pyaegis-0.1.0/c_src/aegis256x4/implementations.h +40 -0
- pyaegis-0.1.0/c_src/common/common.c +81 -0
- pyaegis-0.1.0/c_src/common/common.h +143 -0
- pyaegis-0.1.0/c_src/common/cpu.c +379 -0
- pyaegis-0.1.0/c_src/common/cpu.h +34 -0
- pyaegis-0.1.0/c_src/common/softaes.c +338 -0
- pyaegis-0.1.0/c_src/common/softaes.h +65 -0
- pyaegis-0.1.0/c_src/include/aegis.h +63 -0
- pyaegis-0.1.0/c_src/include/aegis128l.h +332 -0
- pyaegis-0.1.0/c_src/include/aegis128x2.h +332 -0
- pyaegis-0.1.0/c_src/include/aegis128x4.h +332 -0
- pyaegis-0.1.0/c_src/include/aegis256.h +332 -0
- pyaegis-0.1.0/c_src/include/aegis256x2.h +332 -0
- pyaegis-0.1.0/c_src/include/aegis256x4.h +332 -0
- pyaegis-0.1.0/demo.py +267 -0
- pyaegis-0.1.0/pyproject.toml +146 -0
- pyaegis-0.1.0/setup.cfg +4 -0
- pyaegis-0.1.0/setup.py +218 -0
- pyaegis-0.1.0/src/pyaegis/__init__.py +52 -0
- pyaegis-0.1.0/src/pyaegis/aegis.py +762 -0
- pyaegis-0.1.0/src/pyaegis/py.typed +0 -0
- pyaegis-0.1.0/src/pyaegis.egg-info/PKG-INFO +264 -0
- pyaegis-0.1.0/src/pyaegis.egg-info/SOURCES.txt +111 -0
- pyaegis-0.1.0/src/pyaegis.egg-info/dependency_links.txt +1 -0
- pyaegis-0.1.0/src/pyaegis.egg-info/not-zip-safe +1 -0
- pyaegis-0.1.0/src/pyaegis.egg-info/requires.txt +14 -0
- pyaegis-0.1.0/src/pyaegis.egg-info/top_level.txt +1 -0
- pyaegis-0.1.0/tests/test_aegis.py +813 -0
pyaegis-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Frank Denis
|
|
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.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Include C source files
|
|
2
|
+
recursive-include c_src *.c *.h
|
|
3
|
+
|
|
4
|
+
# Include build script
|
|
5
|
+
include build_cffi.py
|
|
6
|
+
|
|
7
|
+
# Include benchmark and demo scripts
|
|
8
|
+
include benchmark.py
|
|
9
|
+
include demo.py
|
|
10
|
+
|
|
11
|
+
# Include documentation
|
|
12
|
+
include README.md
|
|
13
|
+
|
|
14
|
+
# Exclude unnecessary files
|
|
15
|
+
global-exclude *.pyc
|
|
16
|
+
global-exclude __pycache__
|
|
17
|
+
global-exclude *.so
|
|
18
|
+
global-exclude *.dylib
|
|
19
|
+
global-exclude *.dll
|
pyaegis-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyaegis
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python bindings for libaegis - high-performance AEGIS authenticated encryption
|
|
5
|
+
Author-email: Frank Denis <github@pureftpd.org>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/aegis-aead/pyaegis
|
|
8
|
+
Project-URL: Repository, https://github.com/aegis-aead/pyaegis
|
|
9
|
+
Project-URL: Issues, https://github.com/aegis-aead/pyaegis/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/aegis-aead/pyaegis/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: aegis,encryption,authenticated-encryption,aead,cryptography,cffi,security,crypto
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: C
|
|
20
|
+
Classifier: Topic :: Security :: Cryptography
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.11
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: cffi>=2.0.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=8.4.2; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-cov>=7.0.0; extra == "dev"
|
|
31
|
+
Requires-Dist: build>=1.3.0; extra == "dev"
|
|
32
|
+
Requires-Dist: twine>=6.2.0; extra == "dev"
|
|
33
|
+
Requires-Dist: ruff>=0.14.2; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy>=1.18.2; extra == "dev"
|
|
35
|
+
Requires-Dist: pre-commit>=4.3.0; extra == "dev"
|
|
36
|
+
Provides-Extra: test
|
|
37
|
+
Requires-Dist: pytest>=8.4.2; extra == "test"
|
|
38
|
+
Requires-Dist: pytest-cov>=7.0.0; extra == "test"
|
|
39
|
+
Dynamic: license-file
|
|
40
|
+
|
|
41
|
+
# pyaegis
|
|
42
|
+
|
|
43
|
+
[](https://github.com/aegis-aead/pyaegis/actions/workflows/ci.yml)
|
|
44
|
+
[](https://badge.fury.io/py/pyaegis)
|
|
45
|
+
[](https://pypi.org/project/pyaegis/)
|
|
46
|
+
[](https://github.com/aegis-aead/pyaegis/blob/main/LICENSE)
|
|
47
|
+
[](https://github.com/astral-sh/ruff)
|
|
48
|
+
|
|
49
|
+
Python bindings for libaegis - high-performance AEGIS authenticated encryption.
|
|
50
|
+
|
|
51
|
+
## Overview
|
|
52
|
+
|
|
53
|
+
pyaegis provides Pythonic interfaces to the AEGIS family of authenticated encryption algorithms.
|
|
54
|
+
|
|
55
|
+
AEGIS is a high-performance authenticated cipher that provides both confidentiality and authenticity guarantees.
|
|
56
|
+
|
|
57
|
+
### Supported Variants
|
|
58
|
+
|
|
59
|
+
#### Authenticated Encryption (AEAD)
|
|
60
|
+
|
|
61
|
+
- AEGIS-128L: 16-byte key, 16-byte nonce - optimized for performance
|
|
62
|
+
- AEGIS-256: 32-byte key, 32-byte nonce - higher security margin
|
|
63
|
+
- AEGIS-128X2: Dual-lane variant for higher throughput
|
|
64
|
+
- AEGIS-128X4: Quad-lane variant for maximum throughput on AVX-512
|
|
65
|
+
- AEGIS-256X2: Dual-lane variant with 256-bit security
|
|
66
|
+
- AEGIS-256X4: Quad-lane variant with 256-bit security
|
|
67
|
+
|
|
68
|
+
#### Message Authentication Codes (MAC)
|
|
69
|
+
|
|
70
|
+
All AEAD variants have corresponding MAC variants for authentication without encryption:
|
|
71
|
+
|
|
72
|
+
- AEGIS128L_MAC, AEGIS256_MAC
|
|
73
|
+
- AEGIS128X2_MAC, AEGIS128X4_MAC
|
|
74
|
+
- AEGIS256X2_MAC, AEGIS256X4_MAC
|
|
75
|
+
|
|
76
|
+
## Installation
|
|
77
|
+
|
|
78
|
+
### From PyPI
|
|
79
|
+
|
|
80
|
+
Using [uv](https://docs.astral.sh/uv/):
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
uv pip install pyaegis
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Or using pip:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
pip install pyaegis
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### From Source
|
|
93
|
+
|
|
94
|
+
The package compiles the C library automatically using any installed C compiler:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Clone the repository
|
|
98
|
+
git clone https://github.com/aegis-aead/pyaegis.git
|
|
99
|
+
cd pyaegis
|
|
100
|
+
|
|
101
|
+
# Install with uv (compiles C sources automatically)
|
|
102
|
+
uv pip install .
|
|
103
|
+
|
|
104
|
+
# Or for development
|
|
105
|
+
uv pip install -e .
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Alternatively with pip:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
pip install .
|
|
112
|
+
# Or for development
|
|
113
|
+
pip install -e .
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Building a Distribution
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# With uv
|
|
120
|
+
uv run python -m build
|
|
121
|
+
|
|
122
|
+
# Or with pip
|
|
123
|
+
python -m build
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
This creates both source and wheel distributions in the `dist/` directory. The C sources are bundled in the package and compiled during installation.
|
|
127
|
+
|
|
128
|
+
## Usage
|
|
129
|
+
|
|
130
|
+
### Basic Encryption/Decryption
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from pyaegis import AEGIS128L
|
|
134
|
+
|
|
135
|
+
# Create a cipher instance
|
|
136
|
+
cipher = AEGIS128L()
|
|
137
|
+
|
|
138
|
+
# Generate random key and nonce
|
|
139
|
+
key = cipher.random_key()
|
|
140
|
+
nonce = cipher.random_nonce()
|
|
141
|
+
|
|
142
|
+
# Encrypt a message
|
|
143
|
+
plaintext = b"Hello, World!"
|
|
144
|
+
ciphertext = cipher.encrypt(key, nonce, plaintext)
|
|
145
|
+
|
|
146
|
+
# Decrypt the message
|
|
147
|
+
decrypted = cipher.decrypt(key, nonce, ciphertext)
|
|
148
|
+
assert decrypted == plaintext
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### With Additional Authenticated Data (AAD)
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from pyaegis import AEGIS256
|
|
155
|
+
|
|
156
|
+
cipher = AEGIS256()
|
|
157
|
+
key = cipher.random_key()
|
|
158
|
+
nonce = cipher.random_nonce()
|
|
159
|
+
|
|
160
|
+
# AAD is authenticated but not encrypted
|
|
161
|
+
associated_data = b"metadata"
|
|
162
|
+
|
|
163
|
+
ciphertext = cipher.encrypt(key, nonce, b"secret", associated_data=associated_data)
|
|
164
|
+
plaintext = cipher.decrypt(key, nonce, ciphertext, associated_data=associated_data)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Detached Tag Mode
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from pyaegis import AEGIS128L
|
|
171
|
+
|
|
172
|
+
cipher = AEGIS128L()
|
|
173
|
+
key = cipher.random_key()
|
|
174
|
+
nonce = cipher.random_nonce()
|
|
175
|
+
|
|
176
|
+
# Encrypt with detached tag
|
|
177
|
+
ciphertext, tag = cipher.encrypt_detached(key, nonce, b"secret")
|
|
178
|
+
|
|
179
|
+
# Decrypt with detached tag
|
|
180
|
+
plaintext = cipher.decrypt_detached(key, nonce, ciphertext, tag)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Tag Size
|
|
184
|
+
|
|
185
|
+
By default, a 32-byte (256-bit) tag is used for maximum security. You can also use a 16-byte (128-bit) tag:
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
cipher = AEGIS128L(tag_size=16)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Stream Generation
|
|
192
|
+
|
|
193
|
+
Generate a deterministic pseudo-random byte sequence (AEGIS-128L and AEGIS-256 only):
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from pyaegis import AEGIS128L
|
|
197
|
+
|
|
198
|
+
key = AEGIS128L.random_key()
|
|
199
|
+
nonce = AEGIS128L.random_nonce()
|
|
200
|
+
|
|
201
|
+
# Generate 1024 pseudo-random bytes
|
|
202
|
+
random_bytes = AEGIS128L.stream(key, nonce, 1024)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Message Authentication Code (MAC)
|
|
206
|
+
|
|
207
|
+
Generate and verify authentication tags without encryption:
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
from pyaegis import AEGIS128L_MAC, DecryptionError
|
|
211
|
+
|
|
212
|
+
key = AEGIS128L_MAC.random_key()
|
|
213
|
+
nonce = AEGIS128L_MAC.random_nonce()
|
|
214
|
+
|
|
215
|
+
# Generate MAC tag
|
|
216
|
+
mac = AEGIS128L_MAC(key, nonce)
|
|
217
|
+
mac.update(b"message part 1")
|
|
218
|
+
mac.update(b"message part 2")
|
|
219
|
+
tag = mac.final()
|
|
220
|
+
|
|
221
|
+
# Verify MAC tag
|
|
222
|
+
mac_verify = AEGIS128L_MAC(key, nonce)
|
|
223
|
+
mac_verify.update(b"message part 1message part 2")
|
|
224
|
+
try:
|
|
225
|
+
mac_verify.verify(tag)
|
|
226
|
+
print("Authentication successful!")
|
|
227
|
+
except DecryptionError:
|
|
228
|
+
print("Authentication failed!")
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Important: The same key must NOT be used for both MAC and encryption operations.
|
|
232
|
+
|
|
233
|
+
## Error Handling
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
from pyaegis import AEGIS128L, DecryptionError
|
|
237
|
+
|
|
238
|
+
cipher = AEGIS128L()
|
|
239
|
+
key = cipher.random_key()
|
|
240
|
+
nonce = cipher.random_nonce()
|
|
241
|
+
|
|
242
|
+
try:
|
|
243
|
+
# This will raise DecryptionError if authentication fails
|
|
244
|
+
plaintext = cipher.decrypt(key, nonce, tampered_ciphertext)
|
|
245
|
+
except DecryptionError:
|
|
246
|
+
print("Authentication failed - ciphertext was tampered with!")
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Performance
|
|
250
|
+
|
|
251
|
+
The library automatically detects CPU features at runtime and uses the most optimized implementation available:
|
|
252
|
+
|
|
253
|
+
- AES-NI on Intel/AMD processors
|
|
254
|
+
- ARM Crypto Extensions on ARM processors
|
|
255
|
+
- AVX2 and AVX-512 for multi-lane variants
|
|
256
|
+
- Software fallback for other platforms
|
|
257
|
+
|
|
258
|
+
Multi-lane variants (X2, X4) provide higher throughput on systems with appropriate SIMD support.
|
|
259
|
+
|
|
260
|
+
## Security Considerations
|
|
261
|
+
|
|
262
|
+
- Nonce Uniqueness: Never reuse a nonce with the same key. If you can't maintain a counter, use `random_nonce()` for each message.
|
|
263
|
+
- Key Management: Use `random_key()` to generate cryptographically secure keys. Keep keys secret.
|
|
264
|
+
- AAD: Additional authenticated data is not encrypted but is protected against tampering.
|
pyaegis-0.1.0/README.md
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# pyaegis
|
|
2
|
+
|
|
3
|
+
[](https://github.com/aegis-aead/pyaegis/actions/workflows/ci.yml)
|
|
4
|
+
[](https://badge.fury.io/py/pyaegis)
|
|
5
|
+
[](https://pypi.org/project/pyaegis/)
|
|
6
|
+
[](https://github.com/aegis-aead/pyaegis/blob/main/LICENSE)
|
|
7
|
+
[](https://github.com/astral-sh/ruff)
|
|
8
|
+
|
|
9
|
+
Python bindings for libaegis - high-performance AEGIS authenticated encryption.
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
pyaegis provides Pythonic interfaces to the AEGIS family of authenticated encryption algorithms.
|
|
14
|
+
|
|
15
|
+
AEGIS is a high-performance authenticated cipher that provides both confidentiality and authenticity guarantees.
|
|
16
|
+
|
|
17
|
+
### Supported Variants
|
|
18
|
+
|
|
19
|
+
#### Authenticated Encryption (AEAD)
|
|
20
|
+
|
|
21
|
+
- AEGIS-128L: 16-byte key, 16-byte nonce - optimized for performance
|
|
22
|
+
- AEGIS-256: 32-byte key, 32-byte nonce - higher security margin
|
|
23
|
+
- AEGIS-128X2: Dual-lane variant for higher throughput
|
|
24
|
+
- AEGIS-128X4: Quad-lane variant for maximum throughput on AVX-512
|
|
25
|
+
- AEGIS-256X2: Dual-lane variant with 256-bit security
|
|
26
|
+
- AEGIS-256X4: Quad-lane variant with 256-bit security
|
|
27
|
+
|
|
28
|
+
#### Message Authentication Codes (MAC)
|
|
29
|
+
|
|
30
|
+
All AEAD variants have corresponding MAC variants for authentication without encryption:
|
|
31
|
+
|
|
32
|
+
- AEGIS128L_MAC, AEGIS256_MAC
|
|
33
|
+
- AEGIS128X2_MAC, AEGIS128X4_MAC
|
|
34
|
+
- AEGIS256X2_MAC, AEGIS256X4_MAC
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
### From PyPI
|
|
39
|
+
|
|
40
|
+
Using [uv](https://docs.astral.sh/uv/):
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
uv pip install pyaegis
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or using pip:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install pyaegis
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### From Source
|
|
53
|
+
|
|
54
|
+
The package compiles the C library automatically using any installed C compiler:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Clone the repository
|
|
58
|
+
git clone https://github.com/aegis-aead/pyaegis.git
|
|
59
|
+
cd pyaegis
|
|
60
|
+
|
|
61
|
+
# Install with uv (compiles C sources automatically)
|
|
62
|
+
uv pip install .
|
|
63
|
+
|
|
64
|
+
# Or for development
|
|
65
|
+
uv pip install -e .
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Alternatively with pip:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install .
|
|
72
|
+
# Or for development
|
|
73
|
+
pip install -e .
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Building a Distribution
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# With uv
|
|
80
|
+
uv run python -m build
|
|
81
|
+
|
|
82
|
+
# Or with pip
|
|
83
|
+
python -m build
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This creates both source and wheel distributions in the `dist/` directory. The C sources are bundled in the package and compiled during installation.
|
|
87
|
+
|
|
88
|
+
## Usage
|
|
89
|
+
|
|
90
|
+
### Basic Encryption/Decryption
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from pyaegis import AEGIS128L
|
|
94
|
+
|
|
95
|
+
# Create a cipher instance
|
|
96
|
+
cipher = AEGIS128L()
|
|
97
|
+
|
|
98
|
+
# Generate random key and nonce
|
|
99
|
+
key = cipher.random_key()
|
|
100
|
+
nonce = cipher.random_nonce()
|
|
101
|
+
|
|
102
|
+
# Encrypt a message
|
|
103
|
+
plaintext = b"Hello, World!"
|
|
104
|
+
ciphertext = cipher.encrypt(key, nonce, plaintext)
|
|
105
|
+
|
|
106
|
+
# Decrypt the message
|
|
107
|
+
decrypted = cipher.decrypt(key, nonce, ciphertext)
|
|
108
|
+
assert decrypted == plaintext
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### With Additional Authenticated Data (AAD)
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from pyaegis import AEGIS256
|
|
115
|
+
|
|
116
|
+
cipher = AEGIS256()
|
|
117
|
+
key = cipher.random_key()
|
|
118
|
+
nonce = cipher.random_nonce()
|
|
119
|
+
|
|
120
|
+
# AAD is authenticated but not encrypted
|
|
121
|
+
associated_data = b"metadata"
|
|
122
|
+
|
|
123
|
+
ciphertext = cipher.encrypt(key, nonce, b"secret", associated_data=associated_data)
|
|
124
|
+
plaintext = cipher.decrypt(key, nonce, ciphertext, associated_data=associated_data)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Detached Tag Mode
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from pyaegis import AEGIS128L
|
|
131
|
+
|
|
132
|
+
cipher = AEGIS128L()
|
|
133
|
+
key = cipher.random_key()
|
|
134
|
+
nonce = cipher.random_nonce()
|
|
135
|
+
|
|
136
|
+
# Encrypt with detached tag
|
|
137
|
+
ciphertext, tag = cipher.encrypt_detached(key, nonce, b"secret")
|
|
138
|
+
|
|
139
|
+
# Decrypt with detached tag
|
|
140
|
+
plaintext = cipher.decrypt_detached(key, nonce, ciphertext, tag)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Tag Size
|
|
144
|
+
|
|
145
|
+
By default, a 32-byte (256-bit) tag is used for maximum security. You can also use a 16-byte (128-bit) tag:
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
cipher = AEGIS128L(tag_size=16)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Stream Generation
|
|
152
|
+
|
|
153
|
+
Generate a deterministic pseudo-random byte sequence (AEGIS-128L and AEGIS-256 only):
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from pyaegis import AEGIS128L
|
|
157
|
+
|
|
158
|
+
key = AEGIS128L.random_key()
|
|
159
|
+
nonce = AEGIS128L.random_nonce()
|
|
160
|
+
|
|
161
|
+
# Generate 1024 pseudo-random bytes
|
|
162
|
+
random_bytes = AEGIS128L.stream(key, nonce, 1024)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Message Authentication Code (MAC)
|
|
166
|
+
|
|
167
|
+
Generate and verify authentication tags without encryption:
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from pyaegis import AEGIS128L_MAC, DecryptionError
|
|
171
|
+
|
|
172
|
+
key = AEGIS128L_MAC.random_key()
|
|
173
|
+
nonce = AEGIS128L_MAC.random_nonce()
|
|
174
|
+
|
|
175
|
+
# Generate MAC tag
|
|
176
|
+
mac = AEGIS128L_MAC(key, nonce)
|
|
177
|
+
mac.update(b"message part 1")
|
|
178
|
+
mac.update(b"message part 2")
|
|
179
|
+
tag = mac.final()
|
|
180
|
+
|
|
181
|
+
# Verify MAC tag
|
|
182
|
+
mac_verify = AEGIS128L_MAC(key, nonce)
|
|
183
|
+
mac_verify.update(b"message part 1message part 2")
|
|
184
|
+
try:
|
|
185
|
+
mac_verify.verify(tag)
|
|
186
|
+
print("Authentication successful!")
|
|
187
|
+
except DecryptionError:
|
|
188
|
+
print("Authentication failed!")
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Important: The same key must NOT be used for both MAC and encryption operations.
|
|
192
|
+
|
|
193
|
+
## Error Handling
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from pyaegis import AEGIS128L, DecryptionError
|
|
197
|
+
|
|
198
|
+
cipher = AEGIS128L()
|
|
199
|
+
key = cipher.random_key()
|
|
200
|
+
nonce = cipher.random_nonce()
|
|
201
|
+
|
|
202
|
+
try:
|
|
203
|
+
# This will raise DecryptionError if authentication fails
|
|
204
|
+
plaintext = cipher.decrypt(key, nonce, tampered_ciphertext)
|
|
205
|
+
except DecryptionError:
|
|
206
|
+
print("Authentication failed - ciphertext was tampered with!")
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Performance
|
|
210
|
+
|
|
211
|
+
The library automatically detects CPU features at runtime and uses the most optimized implementation available:
|
|
212
|
+
|
|
213
|
+
- AES-NI on Intel/AMD processors
|
|
214
|
+
- ARM Crypto Extensions on ARM processors
|
|
215
|
+
- AVX2 and AVX-512 for multi-lane variants
|
|
216
|
+
- Software fallback for other platforms
|
|
217
|
+
|
|
218
|
+
Multi-lane variants (X2, X4) provide higher throughput on systems with appropriate SIMD support.
|
|
219
|
+
|
|
220
|
+
## Security Considerations
|
|
221
|
+
|
|
222
|
+
- Nonce Uniqueness: Never reuse a nonce with the same key. If you can't maintain a counter, use `random_nonce()` for each message.
|
|
223
|
+
- Key Management: Use `random_key()` to generate cryptographically secure keys. Keep keys secret.
|
|
224
|
+
- AAD: Additional authenticated data is not encrypted but is protected against tampering.
|