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.
Files changed (113) hide show
  1. pyaegis-0.1.0/LICENSE +21 -0
  2. pyaegis-0.1.0/MANIFEST.in +19 -0
  3. pyaegis-0.1.0/PKG-INFO +264 -0
  4. pyaegis-0.1.0/README.md +224 -0
  5. pyaegis-0.1.0/benchmark.py +246 -0
  6. pyaegis-0.1.0/build_cffi.py +233 -0
  7. pyaegis-0.1.0/c_src/aegis128l/aegis128l.c +261 -0
  8. pyaegis-0.1.0/c_src/aegis128l/aegis128l_aesni.c +74 -0
  9. pyaegis-0.1.0/c_src/aegis128l/aegis128l_aesni.h +9 -0
  10. pyaegis-0.1.0/c_src/aegis128l/aegis128l_altivec.c +71 -0
  11. pyaegis-0.1.0/c_src/aegis128l/aegis128l_altivec.h +9 -0
  12. pyaegis-0.1.0/c_src/aegis128l/aegis128l_common.h +694 -0
  13. pyaegis-0.1.0/c_src/aegis128l/aegis128l_neon_aes.c +78 -0
  14. pyaegis-0.1.0/c_src/aegis128l/aegis128l_neon_aes.h +9 -0
  15. pyaegis-0.1.0/c_src/aegis128l/aegis128l_neon_sha3.c +83 -0
  16. pyaegis-0.1.0/c_src/aegis128l/aegis128l_neon_sha3.h +9 -0
  17. pyaegis-0.1.0/c_src/aegis128l/aegis128l_soft.c +64 -0
  18. pyaegis-0.1.0/c_src/aegis128l/aegis128l_soft.h +9 -0
  19. pyaegis-0.1.0/c_src/aegis128l/implementations.h +39 -0
  20. pyaegis-0.1.0/c_src/aegis128x2/aegis128x2.c +262 -0
  21. pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_aesni.c +109 -0
  22. pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_aesni.h +9 -0
  23. pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_altivec.c +104 -0
  24. pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_altivec.h +9 -0
  25. pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_avx2.c +79 -0
  26. pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_avx2.h +11 -0
  27. pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_common.h +799 -0
  28. pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_neon_aes.c +112 -0
  29. pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_neon_aes.h +9 -0
  30. pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_soft.c +97 -0
  31. pyaegis-0.1.0/c_src/aegis128x2/aegis128x2_soft.h +9 -0
  32. pyaegis-0.1.0/c_src/aegis128x2/implementations.h +39 -0
  33. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4.c +267 -0
  34. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_aesni.c +118 -0
  35. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_aesni.h +9 -0
  36. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_altivec.c +112 -0
  37. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_altivec.h +9 -0
  38. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_avx2.c +112 -0
  39. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_avx2.h +11 -0
  40. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_avx512.c +85 -0
  41. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_avx512.h +11 -0
  42. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_common.h +814 -0
  43. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_neon_aes.c +120 -0
  44. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_neon_aes.h +9 -0
  45. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_soft.c +105 -0
  46. pyaegis-0.1.0/c_src/aegis128x4/aegis128x4_soft.h +9 -0
  47. pyaegis-0.1.0/c_src/aegis128x4/implementations.h +39 -0
  48. pyaegis-0.1.0/c_src/aegis256/aegis256.c +255 -0
  49. pyaegis-0.1.0/c_src/aegis256/aegis256_aesni.c +69 -0
  50. pyaegis-0.1.0/c_src/aegis256/aegis256_aesni.h +9 -0
  51. pyaegis-0.1.0/c_src/aegis256/aegis256_altivec.c +69 -0
  52. pyaegis-0.1.0/c_src/aegis256/aegis256_altivec.h +9 -0
  53. pyaegis-0.1.0/c_src/aegis256/aegis256_common.h +680 -0
  54. pyaegis-0.1.0/c_src/aegis256/aegis256_neon_aes.c +76 -0
  55. pyaegis-0.1.0/c_src/aegis256/aegis256_neon_aes.h +9 -0
  56. pyaegis-0.1.0/c_src/aegis256/aegis256_soft.c +59 -0
  57. pyaegis-0.1.0/c_src/aegis256/aegis256_soft.h +9 -0
  58. pyaegis-0.1.0/c_src/aegis256/implementations.h +39 -0
  59. pyaegis-0.1.0/c_src/aegis256x2/aegis256x2.c +262 -0
  60. pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_aesni.c +104 -0
  61. pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_aesni.h +9 -0
  62. pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_altivec.c +102 -0
  63. pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_altivec.h +9 -0
  64. pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_avx2.c +74 -0
  65. pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_avx2.h +11 -0
  66. pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_common.h +795 -0
  67. pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_neon_aes.c +110 -0
  68. pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_neon_aes.h +9 -0
  69. pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_soft.c +92 -0
  70. pyaegis-0.1.0/c_src/aegis256x2/aegis256x2_soft.h +9 -0
  71. pyaegis-0.1.0/c_src/aegis256x2/implementations.h +40 -0
  72. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4.c +267 -0
  73. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_aesni.c +113 -0
  74. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_aesni.h +9 -0
  75. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_altivec.c +110 -0
  76. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_altivec.h +9 -0
  77. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_avx2.c +107 -0
  78. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_avx2.h +11 -0
  79. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_avx512.c +80 -0
  80. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_avx512.h +11 -0
  81. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_common.h +814 -0
  82. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_neon_aes.c +118 -0
  83. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_neon_aes.h +9 -0
  84. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_soft.c +100 -0
  85. pyaegis-0.1.0/c_src/aegis256x4/aegis256x4_soft.h +9 -0
  86. pyaegis-0.1.0/c_src/aegis256x4/implementations.h +40 -0
  87. pyaegis-0.1.0/c_src/common/common.c +81 -0
  88. pyaegis-0.1.0/c_src/common/common.h +143 -0
  89. pyaegis-0.1.0/c_src/common/cpu.c +379 -0
  90. pyaegis-0.1.0/c_src/common/cpu.h +34 -0
  91. pyaegis-0.1.0/c_src/common/softaes.c +338 -0
  92. pyaegis-0.1.0/c_src/common/softaes.h +65 -0
  93. pyaegis-0.1.0/c_src/include/aegis.h +63 -0
  94. pyaegis-0.1.0/c_src/include/aegis128l.h +332 -0
  95. pyaegis-0.1.0/c_src/include/aegis128x2.h +332 -0
  96. pyaegis-0.1.0/c_src/include/aegis128x4.h +332 -0
  97. pyaegis-0.1.0/c_src/include/aegis256.h +332 -0
  98. pyaegis-0.1.0/c_src/include/aegis256x2.h +332 -0
  99. pyaegis-0.1.0/c_src/include/aegis256x4.h +332 -0
  100. pyaegis-0.1.0/demo.py +267 -0
  101. pyaegis-0.1.0/pyproject.toml +146 -0
  102. pyaegis-0.1.0/setup.cfg +4 -0
  103. pyaegis-0.1.0/setup.py +218 -0
  104. pyaegis-0.1.0/src/pyaegis/__init__.py +52 -0
  105. pyaegis-0.1.0/src/pyaegis/aegis.py +762 -0
  106. pyaegis-0.1.0/src/pyaegis/py.typed +0 -0
  107. pyaegis-0.1.0/src/pyaegis.egg-info/PKG-INFO +264 -0
  108. pyaegis-0.1.0/src/pyaegis.egg-info/SOURCES.txt +111 -0
  109. pyaegis-0.1.0/src/pyaegis.egg-info/dependency_links.txt +1 -0
  110. pyaegis-0.1.0/src/pyaegis.egg-info/not-zip-safe +1 -0
  111. pyaegis-0.1.0/src/pyaegis.egg-info/requires.txt +14 -0
  112. pyaegis-0.1.0/src/pyaegis.egg-info/top_level.txt +1 -0
  113. 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
+ [![CI](https://github.com/aegis-aead/pyaegis/actions/workflows/ci.yml/badge.svg)](https://github.com/aegis-aead/pyaegis/actions/workflows/ci.yml)
44
+ [![PyPI version](https://badge.fury.io/py/pyaegis.svg)](https://badge.fury.io/py/pyaegis)
45
+ [![Python versions](https://img.shields.io/pypi/pyversions/pyaegis.svg)](https://pypi.org/project/pyaegis/)
46
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/aegis-aead/pyaegis/blob/main/LICENSE)
47
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](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.
@@ -0,0 +1,224 @@
1
+ # pyaegis
2
+
3
+ [![CI](https://github.com/aegis-aead/pyaegis/actions/workflows/ci.yml/badge.svg)](https://github.com/aegis-aead/pyaegis/actions/workflows/ci.yml)
4
+ [![PyPI version](https://badge.fury.io/py/pyaegis.svg)](https://badge.fury.io/py/pyaegis)
5
+ [![Python versions](https://img.shields.io/pypi/pyversions/pyaegis.svg)](https://pypi.org/project/pyaegis/)
6
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/aegis-aead/pyaegis/blob/main/LICENSE)
7
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](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.