Following upstream libaegis 0.10.5 (874f884): the absorbing-mode
unauthenticated pair is deprecated in favor of the pure keystream XOR.
- stream_xor(key, nonce, data, into=None): same function encrypts and
decrypts; output equals data XOR stream(key, nonce); supports in-place
use via into (same buffer semantics as elsewhere).
- encrypt_unauthenticated/decrypt_unauthenticated kept for the old
format but now emit DeprecationWarning; removed from README (stream_xor
documented under Keystream generation instead).
Each cipher module's random() now returns a thread-local Random that is
created on first use and reused thereafter. Each thread gets its own
OS-seeded generator (own key+nonce), so no locking and no cross-thread
nonce collisions. random_key() and random_nonce() draw from this CSPRNG
instead of secrets.token_bytes, making them as fast as the stream.
Changes made in the aegis256x4.py template and regenerated.
StreamStorage wraps any seek-based file-like object using the same
lock + seek/read/write pattern as FileStorage's fallback for platforms
without pread/pwrite. create()/open() auto-wrap io.BytesIO, so in-memory
use no longer requires the explicit BytesIOStorage wrapper. The caller
keeps ownership of the stream (Raf does not close it).
mmap-backed buffer locked against swapping (mlock/VirtualLock) and
excluded from core dumps (MADV_DONTDUMP) where available, wiped on
close. Not used for return values; intended as an 'into' target (and
key input) to keep sensitive material out of the regular heap.
Adapted from quantumpipe's securebuf module.
- requires-python >= 3.12; abi3 limited API tag cp310 -> cp312
- util.Buffer now imported directly from collections.abc (no fallback)
- release.py: ABI3 wheel covers 3.12-3.15; PyPy wheels dropped (PyPy
has no 3.12 support yet)
Running generate.py standalone previously rewrote _ciphers.py with
formatting that differed from the committed (ruff-formatted) style,
creating spurious diffs. release.py already ran ruff after generation;
now generate.py does too, so both entry points leave the tree in the
same state.
Implement Python bindings for the libaegis 0.10.6 RAF API:
- Thin per-variant wrappers (raf_create/open/read/write/truncate/size/
sync/close, merkle_rebuild/verify/commitment) generated from a template
in tools/generate.py, with errno-mapped exceptions.
- aeg.raf: high-level file-like API (Raf, create/open/probe,
derive_master_key) with pluggable Storage backends (FileStorage,
BytesIOStorage) and Merkle tree integrity via a MerkleHasher protocol
(SHA256MerkleHasher default), adapted from pyaegis (MIT).
- aeg.random: CSPRNG facility. Random produces AEGIS keystream seeded
once from the OS, exposed per cipher module as cipher.random() and
usable as the RAF RNG (as_raf_rng) or standalone RandomSource.
- Tests: roundtrip/random-access/seek/truncate/Merkle coverage for all
six variants, pyaegis-style API checks, and a Merkle fuzz test.