Make key, nonce the first arguments (in this order), require kwargs past the initial few positional arguments. Add ALIGNMENT constant to each module. Add a script to generate all other modules from aegis256x4.py.
This commit is contained in:
+47
-38
@@ -18,6 +18,7 @@ NPUBBYTES = _lib.aegis128l_npubbytes()
|
|||||||
ABYTES_MIN = _lib.aegis128l_abytes_min()
|
ABYTES_MIN = _lib.aegis128l_abytes_min()
|
||||||
ABYTES_MAX = _lib.aegis128l_abytes_max()
|
ABYTES_MAX = _lib.aegis128l_abytes_max()
|
||||||
TAILBYTES_MAX = _lib.aegis128l_tailbytes_max()
|
TAILBYTES_MAX = _lib.aegis128l_tailbytes_max()
|
||||||
|
ALIGNMENT = 32
|
||||||
|
|
||||||
|
|
||||||
def _ptr(buf):
|
def _ptr(buf):
|
||||||
@@ -33,10 +34,11 @@ def _ptr(buf):
|
|||||||
|
|
||||||
|
|
||||||
def encrypt_detached(
|
def encrypt_detached(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
message: Buffer,
|
message: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
ct_into: Buffer | None = None,
|
ct_into: Buffer | None = None,
|
||||||
mac_into: Buffer | None = None,
|
mac_into: Buffer | None = None,
|
||||||
@@ -44,8 +46,8 @@ def encrypt_detached(
|
|||||||
"""Encrypt message with associated data, returning ciphertext and MAC separately.
|
"""Encrypt message with associated data, returning ciphertext and MAC separately.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
message: The plaintext message to encrypt.
|
message: The plaintext message to encrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -99,18 +101,19 @@ def encrypt_detached(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt_detached(
|
def decrypt_detached(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
ct: Buffer,
|
ct: Buffer,
|
||||||
mac: Buffer,
|
mac: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext with detached MAC and associated data.
|
"""Decrypt ciphertext with detached MAC and associated data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ct: The ciphertext to decrypt.
|
ct: The ciphertext to decrypt.
|
||||||
mac: The MAC to verify.
|
mac: The MAC to verify.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
@@ -158,18 +161,19 @@ def decrypt_detached(
|
|||||||
|
|
||||||
|
|
||||||
def encrypt(
|
def encrypt(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
message: Buffer,
|
message: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Encrypt message with associated data, returning ciphertext with appended MAC.
|
"""Encrypt message with associated data, returning ciphertext with appended MAC.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
message: The plaintext message to encrypt.
|
message: The plaintext message to encrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -216,18 +220,19 @@ def encrypt(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt(
|
def decrypt(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
ct: Buffer,
|
ct: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext with appended MAC and associated data.
|
"""Decrypt ciphertext with appended MAC and associated data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ct: The ciphertext with MAC to decrypt.
|
ct: The ciphertext with MAC to decrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -274,16 +279,17 @@ def decrypt(
|
|||||||
|
|
||||||
|
|
||||||
def stream(
|
def stream(
|
||||||
nonce: Buffer | None,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer | None,
|
||||||
length: int | None = None,
|
length: int | None = None,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Generate a stream of pseudorandom bytes.
|
"""Generate a stream of pseudorandom bytes.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes, uses zeroes for nonce if None).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes, uses zeroes for nonce if None).
|
||||||
length: Number of bytes to generate (required if into is None).
|
length: Number of bytes to generate (required if into is None).
|
||||||
into: Buffer to write stream into (default: bytearray created).
|
into: Buffer to write stream into (default: bytearray created).
|
||||||
|
|
||||||
@@ -314,17 +320,18 @@ def stream(
|
|||||||
|
|
||||||
|
|
||||||
def encrypt_unauthenticated(
|
def encrypt_unauthenticated(
|
||||||
message: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
message: Buffer,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Encrypt message without authentication (for testing/debugging).
|
"""Encrypt message without authentication (for testing/debugging).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message: The plaintext message to encrypt.
|
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
message: The plaintext message to encrypt.
|
||||||
into: Buffer to write ciphertext into (default: bytearray created).
|
into: Buffer to write ciphertext into (default: bytearray created).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -356,17 +363,18 @@ def encrypt_unauthenticated(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt_unauthenticated(
|
def decrypt_unauthenticated(
|
||||||
ct: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
ct: Buffer,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext without authentication (for testing/debugging).
|
"""Decrypt ciphertext without authentication (for testing/debugging).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
ct: The ciphertext to decrypt.
|
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
ct: The ciphertext to decrypt.
|
||||||
into: Buffer to write plaintext into (default: bytearray created).
|
into: Buffer to write plaintext into (default: bytearray created).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -399,56 +407,56 @@ def decrypt_unauthenticated(
|
|||||||
|
|
||||||
# This is missing from C API but convenient to have here
|
# This is missing from C API but convenient to have here
|
||||||
def mac(
|
def mac(
|
||||||
data: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
data: Buffer,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Compute a MAC for the given data in one shot.
|
"""Compute a MAC for the given data in one shot.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
data: Data to MAC
|
|
||||||
nonce: Nonce (32 bytes)
|
|
||||||
key: Key (32 bytes)
|
key: Key (32 bytes)
|
||||||
|
nonce: Nonce (32 bytes)
|
||||||
|
data: Data to MAC
|
||||||
maclen: MAC length (16 or 32, default 16)
|
maclen: MAC length (16 or 32, default 16)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
MAC bytes
|
MAC bytes
|
||||||
"""
|
"""
|
||||||
mac_state = Mac(nonce, key)
|
mac_state = Mac(key, nonce)
|
||||||
mac_state.update(data)
|
mac_state.update(data)
|
||||||
return mac_state.final(maclen)
|
return mac_state.final(maclen)
|
||||||
|
|
||||||
|
|
||||||
class Mac:
|
class Mac:
|
||||||
"""AEGIS-256X4 MAC state wrapper.
|
"""AEGIS-128L MAC state wrapper.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
mac = Mac(nonce, key)
|
mac = Mac(key, nonce)
|
||||||
mac.update(data)
|
mac.update(data)
|
||||||
tag = mac.final() # defaults to 16-byte MAC
|
tag = mac.final() # defaults to 16-byte MAC
|
||||||
# or verify:
|
# or verify:
|
||||||
mac2 = Mac(nonce, key); mac2.update(data); mac2.verify(tag)
|
mac2 = Mac(key, nonce); mac2.update(data); mac2.verify(tag)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ("_st", "_nonce", "_key")
|
__slots__ = ("_st", "_nonce", "_key")
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
_other=None,
|
_other=None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize a MAC state with a nonce and key.
|
"""Initialize a MAC state with a nonce and key.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
TypeError: If key or nonce lengths are invalid.
|
TypeError: If key or nonce lengths are invalid.
|
||||||
"""
|
"""
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128l_mac_state"), 32)
|
raw = alloc_aligned(ffi.sizeof("aegis128l_mac_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis128l_mac_state *", raw)
|
st = ffi.cast("aegis128l_mac_state *", raw)
|
||||||
self._st = ffi.gc(st, libc.free)
|
self._st = ffi.gc(st, libc.free)
|
||||||
if _other is not None:
|
if _other is not None:
|
||||||
@@ -553,12 +561,12 @@ class Encryptor:
|
|||||||
|
|
||||||
__slots__ = ("_st",)
|
__slots__ = ("_st",)
|
||||||
|
|
||||||
def __init__(self, nonce: Buffer, key: Buffer, ad: Buffer | None = None):
|
def __init__(self, key: Buffer, nonce: Buffer, ad: Buffer | None = None):
|
||||||
"""Create an incremental encryptor.
|
"""Create an incremental encryptor.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ad: Associated data to bind to the encryption (optional).
|
ad: Associated data to bind to the encryption (optional).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@@ -570,7 +578,7 @@ class Encryptor:
|
|||||||
raise TypeError(f"key length must be {KEYBYTES}")
|
raise TypeError(f"key length must be {KEYBYTES}")
|
||||||
if nonce.nbytes != NPUBBYTES:
|
if nonce.nbytes != NPUBBYTES:
|
||||||
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128l_state"), 32)
|
raw = alloc_aligned(ffi.sizeof("aegis128l_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis128l_state *", raw)
|
st = ffi.cast("aegis128l_state *", raw)
|
||||||
st = ffi.gc(st, libc.free)
|
st = ffi.gc(st, libc.free)
|
||||||
_lib.aegis128l_state_init(
|
_lib.aegis128l_state_init(
|
||||||
@@ -704,12 +712,12 @@ class Decryptor:
|
|||||||
|
|
||||||
__slots__ = ("_st",)
|
__slots__ = ("_st",)
|
||||||
|
|
||||||
def __init__(self, nonce: Buffer, key: Buffer, ad: Buffer | None = None):
|
def __init__(self, key: Buffer, nonce: Buffer, ad: Buffer | None = None):
|
||||||
"""Create an incremental decryptor for detached tags.
|
"""Create an incremental decryptor for detached tags.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ad: Associated data used during encryption (optional).
|
ad: Associated data used during encryption (optional).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@@ -721,7 +729,7 @@ class Decryptor:
|
|||||||
raise TypeError(f"key length must be {KEYBYTES}")
|
raise TypeError(f"key length must be {KEYBYTES}")
|
||||||
if nonce.nbytes != NPUBBYTES:
|
if nonce.nbytes != NPUBBYTES:
|
||||||
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128l_state"), 32)
|
raw = alloc_aligned(ffi.sizeof("aegis128l_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis128l_state *", raw)
|
st = ffi.cast("aegis128l_state *", raw)
|
||||||
st = ffi.gc(st, libc.free)
|
st = ffi.gc(st, libc.free)
|
||||||
_lib.aegis128l_state_init(
|
_lib.aegis128l_state_init(
|
||||||
@@ -812,15 +820,15 @@ def new_state():
|
|||||||
|
|
||||||
The returned object is an ffi cdata pointer with automatic finalizer.
|
The returned object is an ffi cdata pointer with automatic finalizer.
|
||||||
"""
|
"""
|
||||||
# Allocate with 64-byte alignment using libc.posix_memalign
|
# Allocate with required alignment using libc.posix_memalign
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128l_state"), 32)
|
raw = alloc_aligned(ffi.sizeof("aegis128l_state"), ALIGNMENT)
|
||||||
ptr = ffi.cast("aegis128l_state *", raw)
|
ptr = ffi.cast("aegis128l_state *", raw)
|
||||||
return ffi.gc(ptr, libc.free)
|
return ffi.gc(ptr, libc.free)
|
||||||
|
|
||||||
|
|
||||||
def new_mac_state():
|
def new_mac_state():
|
||||||
"""Allocate and return a new aegis128l_mac_state* with proper alignment."""
|
"""Allocate and return a new aegis128l_mac_state* with proper alignment."""
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128l_mac_state"), 32)
|
raw = alloc_aligned(ffi.sizeof("aegis128l_mac_state"), ALIGNMENT)
|
||||||
ptr = ffi.cast("aegis128l_mac_state *", raw)
|
ptr = ffi.cast("aegis128l_mac_state *", raw)
|
||||||
return ffi.gc(ptr, libc.free)
|
return ffi.gc(ptr, libc.free)
|
||||||
|
|
||||||
@@ -832,6 +840,7 @@ __all__ = [
|
|||||||
"ABYTES_MIN",
|
"ABYTES_MIN",
|
||||||
"ABYTES_MAX",
|
"ABYTES_MAX",
|
||||||
"TAILBYTES_MAX",
|
"TAILBYTES_MAX",
|
||||||
|
"ALIGNMENT",
|
||||||
# one-shot functions
|
# one-shot functions
|
||||||
"encrypt_detached",
|
"encrypt_detached",
|
||||||
"decrypt_detached",
|
"decrypt_detached",
|
||||||
|
|||||||
+47
-38
@@ -18,6 +18,7 @@ NPUBBYTES = _lib.aegis128x2_npubbytes()
|
|||||||
ABYTES_MIN = _lib.aegis128x2_abytes_min()
|
ABYTES_MIN = _lib.aegis128x2_abytes_min()
|
||||||
ABYTES_MAX = _lib.aegis128x2_abytes_max()
|
ABYTES_MAX = _lib.aegis128x2_abytes_max()
|
||||||
TAILBYTES_MAX = _lib.aegis128x2_tailbytes_max()
|
TAILBYTES_MAX = _lib.aegis128x2_tailbytes_max()
|
||||||
|
ALIGNMENT = 64
|
||||||
|
|
||||||
|
|
||||||
def _ptr(buf):
|
def _ptr(buf):
|
||||||
@@ -33,10 +34,11 @@ def _ptr(buf):
|
|||||||
|
|
||||||
|
|
||||||
def encrypt_detached(
|
def encrypt_detached(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
message: Buffer,
|
message: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
ct_into: Buffer | None = None,
|
ct_into: Buffer | None = None,
|
||||||
mac_into: Buffer | None = None,
|
mac_into: Buffer | None = None,
|
||||||
@@ -44,8 +46,8 @@ def encrypt_detached(
|
|||||||
"""Encrypt message with associated data, returning ciphertext and MAC separately.
|
"""Encrypt message with associated data, returning ciphertext and MAC separately.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
message: The plaintext message to encrypt.
|
message: The plaintext message to encrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -99,18 +101,19 @@ def encrypt_detached(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt_detached(
|
def decrypt_detached(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
ct: Buffer,
|
ct: Buffer,
|
||||||
mac: Buffer,
|
mac: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext with detached MAC and associated data.
|
"""Decrypt ciphertext with detached MAC and associated data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ct: The ciphertext to decrypt.
|
ct: The ciphertext to decrypt.
|
||||||
mac: The MAC to verify.
|
mac: The MAC to verify.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
@@ -158,18 +161,19 @@ def decrypt_detached(
|
|||||||
|
|
||||||
|
|
||||||
def encrypt(
|
def encrypt(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
message: Buffer,
|
message: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Encrypt message with associated data, returning ciphertext with appended MAC.
|
"""Encrypt message with associated data, returning ciphertext with appended MAC.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
message: The plaintext message to encrypt.
|
message: The plaintext message to encrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -216,18 +220,19 @@ def encrypt(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt(
|
def decrypt(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
ct: Buffer,
|
ct: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext with appended MAC and associated data.
|
"""Decrypt ciphertext with appended MAC and associated data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ct: The ciphertext with MAC to decrypt.
|
ct: The ciphertext with MAC to decrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -274,16 +279,17 @@ def decrypt(
|
|||||||
|
|
||||||
|
|
||||||
def stream(
|
def stream(
|
||||||
nonce: Buffer | None,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer | None,
|
||||||
length: int | None = None,
|
length: int | None = None,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Generate a stream of pseudorandom bytes.
|
"""Generate a stream of pseudorandom bytes.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes, uses zeroes for nonce if None).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes, uses zeroes for nonce if None).
|
||||||
length: Number of bytes to generate (required if into is None).
|
length: Number of bytes to generate (required if into is None).
|
||||||
into: Buffer to write stream into (default: bytearray created).
|
into: Buffer to write stream into (default: bytearray created).
|
||||||
|
|
||||||
@@ -314,17 +320,18 @@ def stream(
|
|||||||
|
|
||||||
|
|
||||||
def encrypt_unauthenticated(
|
def encrypt_unauthenticated(
|
||||||
message: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
message: Buffer,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Encrypt message without authentication (for testing/debugging).
|
"""Encrypt message without authentication (for testing/debugging).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message: The plaintext message to encrypt.
|
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
message: The plaintext message to encrypt.
|
||||||
into: Buffer to write ciphertext into (default: bytearray created).
|
into: Buffer to write ciphertext into (default: bytearray created).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -356,17 +363,18 @@ def encrypt_unauthenticated(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt_unauthenticated(
|
def decrypt_unauthenticated(
|
||||||
ct: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
ct: Buffer,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext without authentication (for testing/debugging).
|
"""Decrypt ciphertext without authentication (for testing/debugging).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
ct: The ciphertext to decrypt.
|
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
ct: The ciphertext to decrypt.
|
||||||
into: Buffer to write plaintext into (default: bytearray created).
|
into: Buffer to write plaintext into (default: bytearray created).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -399,56 +407,56 @@ def decrypt_unauthenticated(
|
|||||||
|
|
||||||
# This is missing from C API but convenient to have here
|
# This is missing from C API but convenient to have here
|
||||||
def mac(
|
def mac(
|
||||||
data: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
data: Buffer,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Compute a MAC for the given data in one shot.
|
"""Compute a MAC for the given data in one shot.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
data: Data to MAC
|
|
||||||
nonce: Nonce (32 bytes)
|
|
||||||
key: Key (32 bytes)
|
key: Key (32 bytes)
|
||||||
|
nonce: Nonce (32 bytes)
|
||||||
|
data: Data to MAC
|
||||||
maclen: MAC length (16 or 32, default 16)
|
maclen: MAC length (16 or 32, default 16)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
MAC bytes
|
MAC bytes
|
||||||
"""
|
"""
|
||||||
mac_state = Mac(nonce, key)
|
mac_state = Mac(key, nonce)
|
||||||
mac_state.update(data)
|
mac_state.update(data)
|
||||||
return mac_state.final(maclen)
|
return mac_state.final(maclen)
|
||||||
|
|
||||||
|
|
||||||
class Mac:
|
class Mac:
|
||||||
"""AEGIS-256X4 MAC state wrapper.
|
"""AEGIS-128X2 MAC state wrapper.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
mac = Mac(nonce, key)
|
mac = Mac(key, nonce)
|
||||||
mac.update(data)
|
mac.update(data)
|
||||||
tag = mac.final() # defaults to 16-byte MAC
|
tag = mac.final() # defaults to 16-byte MAC
|
||||||
# or verify:
|
# or verify:
|
||||||
mac2 = Mac(nonce, key); mac2.update(data); mac2.verify(tag)
|
mac2 = Mac(key, nonce); mac2.update(data); mac2.verify(tag)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ("_st", "_nonce", "_key")
|
__slots__ = ("_st", "_nonce", "_key")
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
_other=None,
|
_other=None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize a MAC state with a nonce and key.
|
"""Initialize a MAC state with a nonce and key.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
TypeError: If key or nonce lengths are invalid.
|
TypeError: If key or nonce lengths are invalid.
|
||||||
"""
|
"""
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128x2_mac_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis128x2_mac_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis128x2_mac_state *", raw)
|
st = ffi.cast("aegis128x2_mac_state *", raw)
|
||||||
self._st = ffi.gc(st, libc.free)
|
self._st = ffi.gc(st, libc.free)
|
||||||
if _other is not None:
|
if _other is not None:
|
||||||
@@ -553,12 +561,12 @@ class Encryptor:
|
|||||||
|
|
||||||
__slots__ = ("_st",)
|
__slots__ = ("_st",)
|
||||||
|
|
||||||
def __init__(self, nonce: Buffer, key: Buffer, ad: Buffer | None = None):
|
def __init__(self, key: Buffer, nonce: Buffer, ad: Buffer | None = None):
|
||||||
"""Create an incremental encryptor.
|
"""Create an incremental encryptor.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ad: Associated data to bind to the encryption (optional).
|
ad: Associated data to bind to the encryption (optional).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@@ -570,7 +578,7 @@ class Encryptor:
|
|||||||
raise TypeError(f"key length must be {KEYBYTES}")
|
raise TypeError(f"key length must be {KEYBYTES}")
|
||||||
if nonce.nbytes != NPUBBYTES:
|
if nonce.nbytes != NPUBBYTES:
|
||||||
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128x2_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis128x2_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis128x2_state *", raw)
|
st = ffi.cast("aegis128x2_state *", raw)
|
||||||
st = ffi.gc(st, libc.free)
|
st = ffi.gc(st, libc.free)
|
||||||
_lib.aegis128x2_state_init(
|
_lib.aegis128x2_state_init(
|
||||||
@@ -704,12 +712,12 @@ class Decryptor:
|
|||||||
|
|
||||||
__slots__ = ("_st",)
|
__slots__ = ("_st",)
|
||||||
|
|
||||||
def __init__(self, nonce: Buffer, key: Buffer, ad: Buffer | None = None):
|
def __init__(self, key: Buffer, nonce: Buffer, ad: Buffer | None = None):
|
||||||
"""Create an incremental decryptor for detached tags.
|
"""Create an incremental decryptor for detached tags.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ad: Associated data used during encryption (optional).
|
ad: Associated data used during encryption (optional).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@@ -721,7 +729,7 @@ class Decryptor:
|
|||||||
raise TypeError(f"key length must be {KEYBYTES}")
|
raise TypeError(f"key length must be {KEYBYTES}")
|
||||||
if nonce.nbytes != NPUBBYTES:
|
if nonce.nbytes != NPUBBYTES:
|
||||||
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128x2_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis128x2_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis128x2_state *", raw)
|
st = ffi.cast("aegis128x2_state *", raw)
|
||||||
st = ffi.gc(st, libc.free)
|
st = ffi.gc(st, libc.free)
|
||||||
_lib.aegis128x2_state_init(
|
_lib.aegis128x2_state_init(
|
||||||
@@ -812,15 +820,15 @@ def new_state():
|
|||||||
|
|
||||||
The returned object is an ffi cdata pointer with automatic finalizer.
|
The returned object is an ffi cdata pointer with automatic finalizer.
|
||||||
"""
|
"""
|
||||||
# Allocate with 64-byte alignment using libc.posix_memalign
|
# Allocate with required alignment using libc.posix_memalign
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128x2_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis128x2_state"), ALIGNMENT)
|
||||||
ptr = ffi.cast("aegis128x2_state *", raw)
|
ptr = ffi.cast("aegis128x2_state *", raw)
|
||||||
return ffi.gc(ptr, libc.free)
|
return ffi.gc(ptr, libc.free)
|
||||||
|
|
||||||
|
|
||||||
def new_mac_state():
|
def new_mac_state():
|
||||||
"""Allocate and return a new aegis128x2_mac_state* with proper alignment."""
|
"""Allocate and return a new aegis128x2_mac_state* with proper alignment."""
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128x2_mac_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis128x2_mac_state"), ALIGNMENT)
|
||||||
ptr = ffi.cast("aegis128x2_mac_state *", raw)
|
ptr = ffi.cast("aegis128x2_mac_state *", raw)
|
||||||
return ffi.gc(ptr, libc.free)
|
return ffi.gc(ptr, libc.free)
|
||||||
|
|
||||||
@@ -832,6 +840,7 @@ __all__ = [
|
|||||||
"ABYTES_MIN",
|
"ABYTES_MIN",
|
||||||
"ABYTES_MAX",
|
"ABYTES_MAX",
|
||||||
"TAILBYTES_MAX",
|
"TAILBYTES_MAX",
|
||||||
|
"ALIGNMENT",
|
||||||
# one-shot functions
|
# one-shot functions
|
||||||
"encrypt_detached",
|
"encrypt_detached",
|
||||||
"decrypt_detached",
|
"decrypt_detached",
|
||||||
|
|||||||
+47
-38
@@ -18,6 +18,7 @@ NPUBBYTES = _lib.aegis128x4_npubbytes()
|
|||||||
ABYTES_MIN = _lib.aegis128x4_abytes_min()
|
ABYTES_MIN = _lib.aegis128x4_abytes_min()
|
||||||
ABYTES_MAX = _lib.aegis128x4_abytes_max()
|
ABYTES_MAX = _lib.aegis128x4_abytes_max()
|
||||||
TAILBYTES_MAX = _lib.aegis128x4_tailbytes_max()
|
TAILBYTES_MAX = _lib.aegis128x4_tailbytes_max()
|
||||||
|
ALIGNMENT = 64
|
||||||
|
|
||||||
|
|
||||||
def _ptr(buf):
|
def _ptr(buf):
|
||||||
@@ -33,10 +34,11 @@ def _ptr(buf):
|
|||||||
|
|
||||||
|
|
||||||
def encrypt_detached(
|
def encrypt_detached(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
message: Buffer,
|
message: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
ct_into: Buffer | None = None,
|
ct_into: Buffer | None = None,
|
||||||
mac_into: Buffer | None = None,
|
mac_into: Buffer | None = None,
|
||||||
@@ -44,8 +46,8 @@ def encrypt_detached(
|
|||||||
"""Encrypt message with associated data, returning ciphertext and MAC separately.
|
"""Encrypt message with associated data, returning ciphertext and MAC separately.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
message: The plaintext message to encrypt.
|
message: The plaintext message to encrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -99,18 +101,19 @@ def encrypt_detached(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt_detached(
|
def decrypt_detached(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
ct: Buffer,
|
ct: Buffer,
|
||||||
mac: Buffer,
|
mac: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext with detached MAC and associated data.
|
"""Decrypt ciphertext with detached MAC and associated data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ct: The ciphertext to decrypt.
|
ct: The ciphertext to decrypt.
|
||||||
mac: The MAC to verify.
|
mac: The MAC to verify.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
@@ -158,18 +161,19 @@ def decrypt_detached(
|
|||||||
|
|
||||||
|
|
||||||
def encrypt(
|
def encrypt(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
message: Buffer,
|
message: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Encrypt message with associated data, returning ciphertext with appended MAC.
|
"""Encrypt message with associated data, returning ciphertext with appended MAC.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
message: The plaintext message to encrypt.
|
message: The plaintext message to encrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -216,18 +220,19 @@ def encrypt(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt(
|
def decrypt(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
ct: Buffer,
|
ct: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext with appended MAC and associated data.
|
"""Decrypt ciphertext with appended MAC and associated data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ct: The ciphertext with MAC to decrypt.
|
ct: The ciphertext with MAC to decrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -274,16 +279,17 @@ def decrypt(
|
|||||||
|
|
||||||
|
|
||||||
def stream(
|
def stream(
|
||||||
nonce: Buffer | None,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer | None,
|
||||||
length: int | None = None,
|
length: int | None = None,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Generate a stream of pseudorandom bytes.
|
"""Generate a stream of pseudorandom bytes.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes, uses zeroes for nonce if None).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes, uses zeroes for nonce if None).
|
||||||
length: Number of bytes to generate (required if into is None).
|
length: Number of bytes to generate (required if into is None).
|
||||||
into: Buffer to write stream into (default: bytearray created).
|
into: Buffer to write stream into (default: bytearray created).
|
||||||
|
|
||||||
@@ -314,17 +320,18 @@ def stream(
|
|||||||
|
|
||||||
|
|
||||||
def encrypt_unauthenticated(
|
def encrypt_unauthenticated(
|
||||||
message: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
message: Buffer,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Encrypt message without authentication (for testing/debugging).
|
"""Encrypt message without authentication (for testing/debugging).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message: The plaintext message to encrypt.
|
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
message: The plaintext message to encrypt.
|
||||||
into: Buffer to write ciphertext into (default: bytearray created).
|
into: Buffer to write ciphertext into (default: bytearray created).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -356,17 +363,18 @@ def encrypt_unauthenticated(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt_unauthenticated(
|
def decrypt_unauthenticated(
|
||||||
ct: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
ct: Buffer,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext without authentication (for testing/debugging).
|
"""Decrypt ciphertext without authentication (for testing/debugging).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
ct: The ciphertext to decrypt.
|
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
ct: The ciphertext to decrypt.
|
||||||
into: Buffer to write plaintext into (default: bytearray created).
|
into: Buffer to write plaintext into (default: bytearray created).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -399,56 +407,56 @@ def decrypt_unauthenticated(
|
|||||||
|
|
||||||
# This is missing from C API but convenient to have here
|
# This is missing from C API but convenient to have here
|
||||||
def mac(
|
def mac(
|
||||||
data: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
data: Buffer,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Compute a MAC for the given data in one shot.
|
"""Compute a MAC for the given data in one shot.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
data: Data to MAC
|
|
||||||
nonce: Nonce (32 bytes)
|
|
||||||
key: Key (32 bytes)
|
key: Key (32 bytes)
|
||||||
|
nonce: Nonce (32 bytes)
|
||||||
|
data: Data to MAC
|
||||||
maclen: MAC length (16 or 32, default 16)
|
maclen: MAC length (16 or 32, default 16)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
MAC bytes
|
MAC bytes
|
||||||
"""
|
"""
|
||||||
mac_state = Mac(nonce, key)
|
mac_state = Mac(key, nonce)
|
||||||
mac_state.update(data)
|
mac_state.update(data)
|
||||||
return mac_state.final(maclen)
|
return mac_state.final(maclen)
|
||||||
|
|
||||||
|
|
||||||
class Mac:
|
class Mac:
|
||||||
"""AEGIS-256X4 MAC state wrapper.
|
"""AEGIS-128X4 MAC state wrapper.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
mac = Mac(nonce, key)
|
mac = Mac(key, nonce)
|
||||||
mac.update(data)
|
mac.update(data)
|
||||||
tag = mac.final() # defaults to 16-byte MAC
|
tag = mac.final() # defaults to 16-byte MAC
|
||||||
# or verify:
|
# or verify:
|
||||||
mac2 = Mac(nonce, key); mac2.update(data); mac2.verify(tag)
|
mac2 = Mac(key, nonce); mac2.update(data); mac2.verify(tag)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ("_st", "_nonce", "_key")
|
__slots__ = ("_st", "_nonce", "_key")
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
_other=None,
|
_other=None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize a MAC state with a nonce and key.
|
"""Initialize a MAC state with a nonce and key.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
TypeError: If key or nonce lengths are invalid.
|
TypeError: If key or nonce lengths are invalid.
|
||||||
"""
|
"""
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128x4_mac_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis128x4_mac_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis128x4_mac_state *", raw)
|
st = ffi.cast("aegis128x4_mac_state *", raw)
|
||||||
self._st = ffi.gc(st, libc.free)
|
self._st = ffi.gc(st, libc.free)
|
||||||
if _other is not None:
|
if _other is not None:
|
||||||
@@ -553,12 +561,12 @@ class Encryptor:
|
|||||||
|
|
||||||
__slots__ = ("_st",)
|
__slots__ = ("_st",)
|
||||||
|
|
||||||
def __init__(self, nonce: Buffer, key: Buffer, ad: Buffer | None = None):
|
def __init__(self, key: Buffer, nonce: Buffer, ad: Buffer | None = None):
|
||||||
"""Create an incremental encryptor.
|
"""Create an incremental encryptor.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ad: Associated data to bind to the encryption (optional).
|
ad: Associated data to bind to the encryption (optional).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@@ -570,7 +578,7 @@ class Encryptor:
|
|||||||
raise TypeError(f"key length must be {KEYBYTES}")
|
raise TypeError(f"key length must be {KEYBYTES}")
|
||||||
if nonce.nbytes != NPUBBYTES:
|
if nonce.nbytes != NPUBBYTES:
|
||||||
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128x4_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis128x4_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis128x4_state *", raw)
|
st = ffi.cast("aegis128x4_state *", raw)
|
||||||
st = ffi.gc(st, libc.free)
|
st = ffi.gc(st, libc.free)
|
||||||
_lib.aegis128x4_state_init(
|
_lib.aegis128x4_state_init(
|
||||||
@@ -704,12 +712,12 @@ class Decryptor:
|
|||||||
|
|
||||||
__slots__ = ("_st",)
|
__slots__ = ("_st",)
|
||||||
|
|
||||||
def __init__(self, nonce: Buffer, key: Buffer, ad: Buffer | None = None):
|
def __init__(self, key: Buffer, nonce: Buffer, ad: Buffer | None = None):
|
||||||
"""Create an incremental decryptor for detached tags.
|
"""Create an incremental decryptor for detached tags.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ad: Associated data used during encryption (optional).
|
ad: Associated data used during encryption (optional).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@@ -721,7 +729,7 @@ class Decryptor:
|
|||||||
raise TypeError(f"key length must be {KEYBYTES}")
|
raise TypeError(f"key length must be {KEYBYTES}")
|
||||||
if nonce.nbytes != NPUBBYTES:
|
if nonce.nbytes != NPUBBYTES:
|
||||||
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128x4_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis128x4_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis128x4_state *", raw)
|
st = ffi.cast("aegis128x4_state *", raw)
|
||||||
st = ffi.gc(st, libc.free)
|
st = ffi.gc(st, libc.free)
|
||||||
_lib.aegis128x4_state_init(
|
_lib.aegis128x4_state_init(
|
||||||
@@ -812,15 +820,15 @@ def new_state():
|
|||||||
|
|
||||||
The returned object is an ffi cdata pointer with automatic finalizer.
|
The returned object is an ffi cdata pointer with automatic finalizer.
|
||||||
"""
|
"""
|
||||||
# Allocate with 64-byte alignment using libc.posix_memalign
|
# Allocate with required alignment using libc.posix_memalign
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128x4_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis128x4_state"), ALIGNMENT)
|
||||||
ptr = ffi.cast("aegis128x4_state *", raw)
|
ptr = ffi.cast("aegis128x4_state *", raw)
|
||||||
return ffi.gc(ptr, libc.free)
|
return ffi.gc(ptr, libc.free)
|
||||||
|
|
||||||
|
|
||||||
def new_mac_state():
|
def new_mac_state():
|
||||||
"""Allocate and return a new aegis128x4_mac_state* with proper alignment."""
|
"""Allocate and return a new aegis128x4_mac_state* with proper alignment."""
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis128x4_mac_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis128x4_mac_state"), ALIGNMENT)
|
||||||
ptr = ffi.cast("aegis128x4_mac_state *", raw)
|
ptr = ffi.cast("aegis128x4_mac_state *", raw)
|
||||||
return ffi.gc(ptr, libc.free)
|
return ffi.gc(ptr, libc.free)
|
||||||
|
|
||||||
@@ -832,6 +840,7 @@ __all__ = [
|
|||||||
"ABYTES_MIN",
|
"ABYTES_MIN",
|
||||||
"ABYTES_MAX",
|
"ABYTES_MAX",
|
||||||
"TAILBYTES_MAX",
|
"TAILBYTES_MAX",
|
||||||
|
"ALIGNMENT",
|
||||||
# one-shot functions
|
# one-shot functions
|
||||||
"encrypt_detached",
|
"encrypt_detached",
|
||||||
"decrypt_detached",
|
"decrypt_detached",
|
||||||
|
|||||||
+47
-38
@@ -18,6 +18,7 @@ NPUBBYTES = _lib.aegis256_npubbytes()
|
|||||||
ABYTES_MIN = _lib.aegis256_abytes_min()
|
ABYTES_MIN = _lib.aegis256_abytes_min()
|
||||||
ABYTES_MAX = _lib.aegis256_abytes_max()
|
ABYTES_MAX = _lib.aegis256_abytes_max()
|
||||||
TAILBYTES_MAX = _lib.aegis256_tailbytes_max()
|
TAILBYTES_MAX = _lib.aegis256_tailbytes_max()
|
||||||
|
ALIGNMENT = 16
|
||||||
|
|
||||||
|
|
||||||
def _ptr(buf):
|
def _ptr(buf):
|
||||||
@@ -33,10 +34,11 @@ def _ptr(buf):
|
|||||||
|
|
||||||
|
|
||||||
def encrypt_detached(
|
def encrypt_detached(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
message: Buffer,
|
message: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
ct_into: Buffer | None = None,
|
ct_into: Buffer | None = None,
|
||||||
mac_into: Buffer | None = None,
|
mac_into: Buffer | None = None,
|
||||||
@@ -44,8 +46,8 @@ def encrypt_detached(
|
|||||||
"""Encrypt message with associated data, returning ciphertext and MAC separately.
|
"""Encrypt message with associated data, returning ciphertext and MAC separately.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
message: The plaintext message to encrypt.
|
message: The plaintext message to encrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -99,18 +101,19 @@ def encrypt_detached(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt_detached(
|
def decrypt_detached(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
ct: Buffer,
|
ct: Buffer,
|
||||||
mac: Buffer,
|
mac: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext with detached MAC and associated data.
|
"""Decrypt ciphertext with detached MAC and associated data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ct: The ciphertext to decrypt.
|
ct: The ciphertext to decrypt.
|
||||||
mac: The MAC to verify.
|
mac: The MAC to verify.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
@@ -158,18 +161,19 @@ def decrypt_detached(
|
|||||||
|
|
||||||
|
|
||||||
def encrypt(
|
def encrypt(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
message: Buffer,
|
message: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Encrypt message with associated data, returning ciphertext with appended MAC.
|
"""Encrypt message with associated data, returning ciphertext with appended MAC.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
message: The plaintext message to encrypt.
|
message: The plaintext message to encrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -216,18 +220,19 @@ def encrypt(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt(
|
def decrypt(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
ct: Buffer,
|
ct: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext with appended MAC and associated data.
|
"""Decrypt ciphertext with appended MAC and associated data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ct: The ciphertext with MAC to decrypt.
|
ct: The ciphertext with MAC to decrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -274,16 +279,17 @@ def decrypt(
|
|||||||
|
|
||||||
|
|
||||||
def stream(
|
def stream(
|
||||||
nonce: Buffer | None,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer | None,
|
||||||
length: int | None = None,
|
length: int | None = None,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Generate a stream of pseudorandom bytes.
|
"""Generate a stream of pseudorandom bytes.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes, uses zeroes for nonce if None).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes, uses zeroes for nonce if None).
|
||||||
length: Number of bytes to generate (required if into is None).
|
length: Number of bytes to generate (required if into is None).
|
||||||
into: Buffer to write stream into (default: bytearray created).
|
into: Buffer to write stream into (default: bytearray created).
|
||||||
|
|
||||||
@@ -314,17 +320,18 @@ def stream(
|
|||||||
|
|
||||||
|
|
||||||
def encrypt_unauthenticated(
|
def encrypt_unauthenticated(
|
||||||
message: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
message: Buffer,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Encrypt message without authentication (for testing/debugging).
|
"""Encrypt message without authentication (for testing/debugging).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message: The plaintext message to encrypt.
|
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
message: The plaintext message to encrypt.
|
||||||
into: Buffer to write ciphertext into (default: bytearray created).
|
into: Buffer to write ciphertext into (default: bytearray created).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -356,17 +363,18 @@ def encrypt_unauthenticated(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt_unauthenticated(
|
def decrypt_unauthenticated(
|
||||||
ct: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
ct: Buffer,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext without authentication (for testing/debugging).
|
"""Decrypt ciphertext without authentication (for testing/debugging).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
ct: The ciphertext to decrypt.
|
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
ct: The ciphertext to decrypt.
|
||||||
into: Buffer to write plaintext into (default: bytearray created).
|
into: Buffer to write plaintext into (default: bytearray created).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -399,56 +407,56 @@ def decrypt_unauthenticated(
|
|||||||
|
|
||||||
# This is missing from C API but convenient to have here
|
# This is missing from C API but convenient to have here
|
||||||
def mac(
|
def mac(
|
||||||
data: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
data: Buffer,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Compute a MAC for the given data in one shot.
|
"""Compute a MAC for the given data in one shot.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
data: Data to MAC
|
|
||||||
nonce: Nonce (32 bytes)
|
|
||||||
key: Key (32 bytes)
|
key: Key (32 bytes)
|
||||||
|
nonce: Nonce (32 bytes)
|
||||||
|
data: Data to MAC
|
||||||
maclen: MAC length (16 or 32, default 16)
|
maclen: MAC length (16 or 32, default 16)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
MAC bytes
|
MAC bytes
|
||||||
"""
|
"""
|
||||||
mac_state = Mac(nonce, key)
|
mac_state = Mac(key, nonce)
|
||||||
mac_state.update(data)
|
mac_state.update(data)
|
||||||
return mac_state.final(maclen)
|
return mac_state.final(maclen)
|
||||||
|
|
||||||
|
|
||||||
class Mac:
|
class Mac:
|
||||||
"""AEGIS-256X4 MAC state wrapper.
|
"""AEGIS-256 MAC state wrapper.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
mac = Mac(nonce, key)
|
mac = Mac(key, nonce)
|
||||||
mac.update(data)
|
mac.update(data)
|
||||||
tag = mac.final() # defaults to 16-byte MAC
|
tag = mac.final() # defaults to 16-byte MAC
|
||||||
# or verify:
|
# or verify:
|
||||||
mac2 = Mac(nonce, key); mac2.update(data); mac2.verify(tag)
|
mac2 = Mac(key, nonce); mac2.update(data); mac2.verify(tag)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ("_st", "_nonce", "_key")
|
__slots__ = ("_st", "_nonce", "_key")
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
_other=None,
|
_other=None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize a MAC state with a nonce and key.
|
"""Initialize a MAC state with a nonce and key.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
TypeError: If key or nonce lengths are invalid.
|
TypeError: If key or nonce lengths are invalid.
|
||||||
"""
|
"""
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256_mac_state"), 16)
|
raw = alloc_aligned(ffi.sizeof("aegis256_mac_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis256_mac_state *", raw)
|
st = ffi.cast("aegis256_mac_state *", raw)
|
||||||
self._st = ffi.gc(st, libc.free)
|
self._st = ffi.gc(st, libc.free)
|
||||||
if _other is not None:
|
if _other is not None:
|
||||||
@@ -553,12 +561,12 @@ class Encryptor:
|
|||||||
|
|
||||||
__slots__ = ("_st",)
|
__slots__ = ("_st",)
|
||||||
|
|
||||||
def __init__(self, nonce: Buffer, key: Buffer, ad: Buffer | None = None):
|
def __init__(self, key: Buffer, nonce: Buffer, ad: Buffer | None = None):
|
||||||
"""Create an incremental encryptor.
|
"""Create an incremental encryptor.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ad: Associated data to bind to the encryption (optional).
|
ad: Associated data to bind to the encryption (optional).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@@ -570,7 +578,7 @@ class Encryptor:
|
|||||||
raise TypeError(f"key length must be {KEYBYTES}")
|
raise TypeError(f"key length must be {KEYBYTES}")
|
||||||
if nonce.nbytes != NPUBBYTES:
|
if nonce.nbytes != NPUBBYTES:
|
||||||
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256_state"), 16)
|
raw = alloc_aligned(ffi.sizeof("aegis256_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis256_state *", raw)
|
st = ffi.cast("aegis256_state *", raw)
|
||||||
st = ffi.gc(st, libc.free)
|
st = ffi.gc(st, libc.free)
|
||||||
_lib.aegis256_state_init(
|
_lib.aegis256_state_init(
|
||||||
@@ -704,12 +712,12 @@ class Decryptor:
|
|||||||
|
|
||||||
__slots__ = ("_st",)
|
__slots__ = ("_st",)
|
||||||
|
|
||||||
def __init__(self, nonce: Buffer, key: Buffer, ad: Buffer | None = None):
|
def __init__(self, key: Buffer, nonce: Buffer, ad: Buffer | None = None):
|
||||||
"""Create an incremental decryptor for detached tags.
|
"""Create an incremental decryptor for detached tags.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ad: Associated data used during encryption (optional).
|
ad: Associated data used during encryption (optional).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@@ -721,7 +729,7 @@ class Decryptor:
|
|||||||
raise TypeError(f"key length must be {KEYBYTES}")
|
raise TypeError(f"key length must be {KEYBYTES}")
|
||||||
if nonce.nbytes != NPUBBYTES:
|
if nonce.nbytes != NPUBBYTES:
|
||||||
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256_state"), 16)
|
raw = alloc_aligned(ffi.sizeof("aegis256_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis256_state *", raw)
|
st = ffi.cast("aegis256_state *", raw)
|
||||||
st = ffi.gc(st, libc.free)
|
st = ffi.gc(st, libc.free)
|
||||||
_lib.aegis256_state_init(
|
_lib.aegis256_state_init(
|
||||||
@@ -812,15 +820,15 @@ def new_state():
|
|||||||
|
|
||||||
The returned object is an ffi cdata pointer with automatic finalizer.
|
The returned object is an ffi cdata pointer with automatic finalizer.
|
||||||
"""
|
"""
|
||||||
# Allocate with 64-byte alignment using libc.posix_memalign
|
# Allocate with required alignment using libc.posix_memalign
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256_state"), 16)
|
raw = alloc_aligned(ffi.sizeof("aegis256_state"), ALIGNMENT)
|
||||||
ptr = ffi.cast("aegis256_state *", raw)
|
ptr = ffi.cast("aegis256_state *", raw)
|
||||||
return ffi.gc(ptr, libc.free)
|
return ffi.gc(ptr, libc.free)
|
||||||
|
|
||||||
|
|
||||||
def new_mac_state():
|
def new_mac_state():
|
||||||
"""Allocate and return a new aegis256_mac_state* with proper alignment."""
|
"""Allocate and return a new aegis256_mac_state* with proper alignment."""
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256_mac_state"), 16)
|
raw = alloc_aligned(ffi.sizeof("aegis256_mac_state"), ALIGNMENT)
|
||||||
ptr = ffi.cast("aegis256_mac_state *", raw)
|
ptr = ffi.cast("aegis256_mac_state *", raw)
|
||||||
return ffi.gc(ptr, libc.free)
|
return ffi.gc(ptr, libc.free)
|
||||||
|
|
||||||
@@ -832,6 +840,7 @@ __all__ = [
|
|||||||
"ABYTES_MIN",
|
"ABYTES_MIN",
|
||||||
"ABYTES_MAX",
|
"ABYTES_MAX",
|
||||||
"TAILBYTES_MAX",
|
"TAILBYTES_MAX",
|
||||||
|
"ALIGNMENT",
|
||||||
# one-shot functions
|
# one-shot functions
|
||||||
"encrypt_detached",
|
"encrypt_detached",
|
||||||
"decrypt_detached",
|
"decrypt_detached",
|
||||||
|
|||||||
+47
-38
@@ -18,6 +18,7 @@ NPUBBYTES = _lib.aegis256x2_npubbytes()
|
|||||||
ABYTES_MIN = _lib.aegis256x2_abytes_min()
|
ABYTES_MIN = _lib.aegis256x2_abytes_min()
|
||||||
ABYTES_MAX = _lib.aegis256x2_abytes_max()
|
ABYTES_MAX = _lib.aegis256x2_abytes_max()
|
||||||
TAILBYTES_MAX = _lib.aegis256x2_tailbytes_max()
|
TAILBYTES_MAX = _lib.aegis256x2_tailbytes_max()
|
||||||
|
ALIGNMENT = 32
|
||||||
|
|
||||||
|
|
||||||
def _ptr(buf):
|
def _ptr(buf):
|
||||||
@@ -33,10 +34,11 @@ def _ptr(buf):
|
|||||||
|
|
||||||
|
|
||||||
def encrypt_detached(
|
def encrypt_detached(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
message: Buffer,
|
message: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
ct_into: Buffer | None = None,
|
ct_into: Buffer | None = None,
|
||||||
mac_into: Buffer | None = None,
|
mac_into: Buffer | None = None,
|
||||||
@@ -44,8 +46,8 @@ def encrypt_detached(
|
|||||||
"""Encrypt message with associated data, returning ciphertext and MAC separately.
|
"""Encrypt message with associated data, returning ciphertext and MAC separately.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
message: The plaintext message to encrypt.
|
message: The plaintext message to encrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -99,18 +101,19 @@ def encrypt_detached(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt_detached(
|
def decrypt_detached(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
ct: Buffer,
|
ct: Buffer,
|
||||||
mac: Buffer,
|
mac: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext with detached MAC and associated data.
|
"""Decrypt ciphertext with detached MAC and associated data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ct: The ciphertext to decrypt.
|
ct: The ciphertext to decrypt.
|
||||||
mac: The MAC to verify.
|
mac: The MAC to verify.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
@@ -158,18 +161,19 @@ def decrypt_detached(
|
|||||||
|
|
||||||
|
|
||||||
def encrypt(
|
def encrypt(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
message: Buffer,
|
message: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Encrypt message with associated data, returning ciphertext with appended MAC.
|
"""Encrypt message with associated data, returning ciphertext with appended MAC.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
message: The plaintext message to encrypt.
|
message: The plaintext message to encrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -216,18 +220,19 @@ def encrypt(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt(
|
def decrypt(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
ct: Buffer,
|
ct: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext with appended MAC and associated data.
|
"""Decrypt ciphertext with appended MAC and associated data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ct: The ciphertext with MAC to decrypt.
|
ct: The ciphertext with MAC to decrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -274,16 +279,17 @@ def decrypt(
|
|||||||
|
|
||||||
|
|
||||||
def stream(
|
def stream(
|
||||||
nonce: Buffer | None,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer | None,
|
||||||
length: int | None = None,
|
length: int | None = None,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Generate a stream of pseudorandom bytes.
|
"""Generate a stream of pseudorandom bytes.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes, uses zeroes for nonce if None).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes, uses zeroes for nonce if None).
|
||||||
length: Number of bytes to generate (required if into is None).
|
length: Number of bytes to generate (required if into is None).
|
||||||
into: Buffer to write stream into (default: bytearray created).
|
into: Buffer to write stream into (default: bytearray created).
|
||||||
|
|
||||||
@@ -314,17 +320,18 @@ def stream(
|
|||||||
|
|
||||||
|
|
||||||
def encrypt_unauthenticated(
|
def encrypt_unauthenticated(
|
||||||
message: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
message: Buffer,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Encrypt message without authentication (for testing/debugging).
|
"""Encrypt message without authentication (for testing/debugging).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message: The plaintext message to encrypt.
|
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
message: The plaintext message to encrypt.
|
||||||
into: Buffer to write ciphertext into (default: bytearray created).
|
into: Buffer to write ciphertext into (default: bytearray created).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -356,17 +363,18 @@ def encrypt_unauthenticated(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt_unauthenticated(
|
def decrypt_unauthenticated(
|
||||||
ct: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
ct: Buffer,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext without authentication (for testing/debugging).
|
"""Decrypt ciphertext without authentication (for testing/debugging).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
ct: The ciphertext to decrypt.
|
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
ct: The ciphertext to decrypt.
|
||||||
into: Buffer to write plaintext into (default: bytearray created).
|
into: Buffer to write plaintext into (default: bytearray created).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -399,56 +407,56 @@ def decrypt_unauthenticated(
|
|||||||
|
|
||||||
# This is missing from C API but convenient to have here
|
# This is missing from C API but convenient to have here
|
||||||
def mac(
|
def mac(
|
||||||
data: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
data: Buffer,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Compute a MAC for the given data in one shot.
|
"""Compute a MAC for the given data in one shot.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
data: Data to MAC
|
|
||||||
nonce: Nonce (32 bytes)
|
|
||||||
key: Key (32 bytes)
|
key: Key (32 bytes)
|
||||||
|
nonce: Nonce (32 bytes)
|
||||||
|
data: Data to MAC
|
||||||
maclen: MAC length (16 or 32, default 16)
|
maclen: MAC length (16 or 32, default 16)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
MAC bytes
|
MAC bytes
|
||||||
"""
|
"""
|
||||||
mac_state = Mac(nonce, key)
|
mac_state = Mac(key, nonce)
|
||||||
mac_state.update(data)
|
mac_state.update(data)
|
||||||
return mac_state.final(maclen)
|
return mac_state.final(maclen)
|
||||||
|
|
||||||
|
|
||||||
class Mac:
|
class Mac:
|
||||||
"""AEGIS-256X4 MAC state wrapper.
|
"""AEGIS-256X2 MAC state wrapper.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
mac = Mac(nonce, key)
|
mac = Mac(key, nonce)
|
||||||
mac.update(data)
|
mac.update(data)
|
||||||
tag = mac.final() # defaults to 16-byte MAC
|
tag = mac.final() # defaults to 16-byte MAC
|
||||||
# or verify:
|
# or verify:
|
||||||
mac2 = Mac(nonce, key); mac2.update(data); mac2.verify(tag)
|
mac2 = Mac(key, nonce); mac2.update(data); mac2.verify(tag)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ("_st", "_nonce", "_key")
|
__slots__ = ("_st", "_nonce", "_key")
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
_other=None,
|
_other=None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize a MAC state with a nonce and key.
|
"""Initialize a MAC state with a nonce and key.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
TypeError: If key or nonce lengths are invalid.
|
TypeError: If key or nonce lengths are invalid.
|
||||||
"""
|
"""
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256x2_mac_state"), 32)
|
raw = alloc_aligned(ffi.sizeof("aegis256x2_mac_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis256x2_mac_state *", raw)
|
st = ffi.cast("aegis256x2_mac_state *", raw)
|
||||||
self._st = ffi.gc(st, libc.free)
|
self._st = ffi.gc(st, libc.free)
|
||||||
if _other is not None:
|
if _other is not None:
|
||||||
@@ -553,12 +561,12 @@ class Encryptor:
|
|||||||
|
|
||||||
__slots__ = ("_st",)
|
__slots__ = ("_st",)
|
||||||
|
|
||||||
def __init__(self, nonce: Buffer, key: Buffer, ad: Buffer | None = None):
|
def __init__(self, key: Buffer, nonce: Buffer, ad: Buffer | None = None):
|
||||||
"""Create an incremental encryptor.
|
"""Create an incremental encryptor.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ad: Associated data to bind to the encryption (optional).
|
ad: Associated data to bind to the encryption (optional).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@@ -570,7 +578,7 @@ class Encryptor:
|
|||||||
raise TypeError(f"key length must be {KEYBYTES}")
|
raise TypeError(f"key length must be {KEYBYTES}")
|
||||||
if nonce.nbytes != NPUBBYTES:
|
if nonce.nbytes != NPUBBYTES:
|
||||||
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256x2_state"), 32)
|
raw = alloc_aligned(ffi.sizeof("aegis256x2_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis256x2_state *", raw)
|
st = ffi.cast("aegis256x2_state *", raw)
|
||||||
st = ffi.gc(st, libc.free)
|
st = ffi.gc(st, libc.free)
|
||||||
_lib.aegis256x2_state_init(
|
_lib.aegis256x2_state_init(
|
||||||
@@ -704,12 +712,12 @@ class Decryptor:
|
|||||||
|
|
||||||
__slots__ = ("_st",)
|
__slots__ = ("_st",)
|
||||||
|
|
||||||
def __init__(self, nonce: Buffer, key: Buffer, ad: Buffer | None = None):
|
def __init__(self, key: Buffer, nonce: Buffer, ad: Buffer | None = None):
|
||||||
"""Create an incremental decryptor for detached tags.
|
"""Create an incremental decryptor for detached tags.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ad: Associated data used during encryption (optional).
|
ad: Associated data used during encryption (optional).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@@ -721,7 +729,7 @@ class Decryptor:
|
|||||||
raise TypeError(f"key length must be {KEYBYTES}")
|
raise TypeError(f"key length must be {KEYBYTES}")
|
||||||
if nonce.nbytes != NPUBBYTES:
|
if nonce.nbytes != NPUBBYTES:
|
||||||
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256x2_state"), 32)
|
raw = alloc_aligned(ffi.sizeof("aegis256x2_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis256x2_state *", raw)
|
st = ffi.cast("aegis256x2_state *", raw)
|
||||||
st = ffi.gc(st, libc.free)
|
st = ffi.gc(st, libc.free)
|
||||||
_lib.aegis256x2_state_init(
|
_lib.aegis256x2_state_init(
|
||||||
@@ -812,15 +820,15 @@ def new_state():
|
|||||||
|
|
||||||
The returned object is an ffi cdata pointer with automatic finalizer.
|
The returned object is an ffi cdata pointer with automatic finalizer.
|
||||||
"""
|
"""
|
||||||
# Allocate with 64-byte alignment using libc.posix_memalign
|
# Allocate with required alignment using libc.posix_memalign
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256x2_state"), 32)
|
raw = alloc_aligned(ffi.sizeof("aegis256x2_state"), ALIGNMENT)
|
||||||
ptr = ffi.cast("aegis256x2_state *", raw)
|
ptr = ffi.cast("aegis256x2_state *", raw)
|
||||||
return ffi.gc(ptr, libc.free)
|
return ffi.gc(ptr, libc.free)
|
||||||
|
|
||||||
|
|
||||||
def new_mac_state():
|
def new_mac_state():
|
||||||
"""Allocate and return a new aegis256x2_mac_state* with proper alignment."""
|
"""Allocate and return a new aegis256x2_mac_state* with proper alignment."""
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256x2_mac_state"), 32)
|
raw = alloc_aligned(ffi.sizeof("aegis256x2_mac_state"), ALIGNMENT)
|
||||||
ptr = ffi.cast("aegis256x2_mac_state *", raw)
|
ptr = ffi.cast("aegis256x2_mac_state *", raw)
|
||||||
return ffi.gc(ptr, libc.free)
|
return ffi.gc(ptr, libc.free)
|
||||||
|
|
||||||
@@ -832,6 +840,7 @@ __all__ = [
|
|||||||
"ABYTES_MIN",
|
"ABYTES_MIN",
|
||||||
"ABYTES_MAX",
|
"ABYTES_MAX",
|
||||||
"TAILBYTES_MAX",
|
"TAILBYTES_MAX",
|
||||||
|
"ALIGNMENT",
|
||||||
# one-shot functions
|
# one-shot functions
|
||||||
"encrypt_detached",
|
"encrypt_detached",
|
||||||
"decrypt_detached",
|
"decrypt_detached",
|
||||||
|
|||||||
+46
-37
@@ -18,6 +18,7 @@ NPUBBYTES = _lib.aegis256x4_npubbytes()
|
|||||||
ABYTES_MIN = _lib.aegis256x4_abytes_min()
|
ABYTES_MIN = _lib.aegis256x4_abytes_min()
|
||||||
ABYTES_MAX = _lib.aegis256x4_abytes_max()
|
ABYTES_MAX = _lib.aegis256x4_abytes_max()
|
||||||
TAILBYTES_MAX = _lib.aegis256x4_tailbytes_max()
|
TAILBYTES_MAX = _lib.aegis256x4_tailbytes_max()
|
||||||
|
ALIGNMENT = 64
|
||||||
|
|
||||||
|
|
||||||
def _ptr(buf):
|
def _ptr(buf):
|
||||||
@@ -33,10 +34,11 @@ def _ptr(buf):
|
|||||||
|
|
||||||
|
|
||||||
def encrypt_detached(
|
def encrypt_detached(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
message: Buffer,
|
message: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
ct_into: Buffer | None = None,
|
ct_into: Buffer | None = None,
|
||||||
mac_into: Buffer | None = None,
|
mac_into: Buffer | None = None,
|
||||||
@@ -44,8 +46,8 @@ def encrypt_detached(
|
|||||||
"""Encrypt message with associated data, returning ciphertext and MAC separately.
|
"""Encrypt message with associated data, returning ciphertext and MAC separately.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
message: The plaintext message to encrypt.
|
message: The plaintext message to encrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -99,18 +101,19 @@ def encrypt_detached(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt_detached(
|
def decrypt_detached(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
ct: Buffer,
|
ct: Buffer,
|
||||||
mac: Buffer,
|
mac: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext with detached MAC and associated data.
|
"""Decrypt ciphertext with detached MAC and associated data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ct: The ciphertext to decrypt.
|
ct: The ciphertext to decrypt.
|
||||||
mac: The MAC to verify.
|
mac: The MAC to verify.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
@@ -158,18 +161,19 @@ def decrypt_detached(
|
|||||||
|
|
||||||
|
|
||||||
def encrypt(
|
def encrypt(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
message: Buffer,
|
message: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Encrypt message with associated data, returning ciphertext with appended MAC.
|
"""Encrypt message with associated data, returning ciphertext with appended MAC.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
message: The plaintext message to encrypt.
|
message: The plaintext message to encrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -216,18 +220,19 @@ def encrypt(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt(
|
def decrypt(
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
ct: Buffer,
|
ct: Buffer,
|
||||||
ad: Buffer | None = None,
|
ad: Buffer | None = None,
|
||||||
|
*,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext with appended MAC and associated data.
|
"""Decrypt ciphertext with appended MAC and associated data.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ct: The ciphertext with MAC to decrypt.
|
ct: The ciphertext with MAC to decrypt.
|
||||||
ad: Associated data (optional).
|
ad: Associated data (optional).
|
||||||
maclen: MAC length (16 or 32, default 16).
|
maclen: MAC length (16 or 32, default 16).
|
||||||
@@ -274,16 +279,17 @@ def decrypt(
|
|||||||
|
|
||||||
|
|
||||||
def stream(
|
def stream(
|
||||||
nonce: Buffer | None,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer | None,
|
||||||
length: int | None = None,
|
length: int | None = None,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Generate a stream of pseudorandom bytes.
|
"""Generate a stream of pseudorandom bytes.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes, uses zeroes for nonce if None).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes, uses zeroes for nonce if None).
|
||||||
length: Number of bytes to generate (required if into is None).
|
length: Number of bytes to generate (required if into is None).
|
||||||
into: Buffer to write stream into (default: bytearray created).
|
into: Buffer to write stream into (default: bytearray created).
|
||||||
|
|
||||||
@@ -314,17 +320,18 @@ def stream(
|
|||||||
|
|
||||||
|
|
||||||
def encrypt_unauthenticated(
|
def encrypt_unauthenticated(
|
||||||
message: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
message: Buffer,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Encrypt message without authentication (for testing/debugging).
|
"""Encrypt message without authentication (for testing/debugging).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message: The plaintext message to encrypt.
|
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
message: The plaintext message to encrypt.
|
||||||
into: Buffer to write ciphertext into (default: bytearray created).
|
into: Buffer to write ciphertext into (default: bytearray created).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -356,17 +363,18 @@ def encrypt_unauthenticated(
|
|||||||
|
|
||||||
|
|
||||||
def decrypt_unauthenticated(
|
def decrypt_unauthenticated(
|
||||||
ct: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
ct: Buffer,
|
||||||
|
*,
|
||||||
into: Buffer | None = None,
|
into: Buffer | None = None,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Decrypt ciphertext without authentication (for testing/debugging).
|
"""Decrypt ciphertext without authentication (for testing/debugging).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
ct: The ciphertext to decrypt.
|
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
ct: The ciphertext to decrypt.
|
||||||
into: Buffer to write plaintext into (default: bytearray created).
|
into: Buffer to write plaintext into (default: bytearray created).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -399,23 +407,23 @@ def decrypt_unauthenticated(
|
|||||||
|
|
||||||
# This is missing from C API but convenient to have here
|
# This is missing from C API but convenient to have here
|
||||||
def mac(
|
def mac(
|
||||||
data: Buffer,
|
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
|
data: Buffer,
|
||||||
maclen: int = ABYTES_MIN,
|
maclen: int = ABYTES_MIN,
|
||||||
) -> memoryview:
|
) -> memoryview:
|
||||||
"""Compute a MAC for the given data in one shot.
|
"""Compute a MAC for the given data in one shot.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
data: Data to MAC
|
|
||||||
nonce: Nonce (32 bytes)
|
|
||||||
key: Key (32 bytes)
|
key: Key (32 bytes)
|
||||||
|
nonce: Nonce (32 bytes)
|
||||||
|
data: Data to MAC
|
||||||
maclen: MAC length (16 or 32, default 16)
|
maclen: MAC length (16 or 32, default 16)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
MAC bytes
|
MAC bytes
|
||||||
"""
|
"""
|
||||||
mac_state = Mac(nonce, key)
|
mac_state = Mac(key, nonce)
|
||||||
mac_state.update(data)
|
mac_state.update(data)
|
||||||
return mac_state.final(maclen)
|
return mac_state.final(maclen)
|
||||||
|
|
||||||
@@ -424,31 +432,31 @@ class Mac:
|
|||||||
"""AEGIS-256X4 MAC state wrapper.
|
"""AEGIS-256X4 MAC state wrapper.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
mac = Mac(nonce, key)
|
mac = Mac(key, nonce)
|
||||||
mac.update(data)
|
mac.update(data)
|
||||||
tag = mac.final() # defaults to 16-byte MAC
|
tag = mac.final() # defaults to 16-byte MAC
|
||||||
# or verify:
|
# or verify:
|
||||||
mac2 = Mac(nonce, key); mac2.update(data); mac2.verify(tag)
|
mac2 = Mac(key, nonce); mac2.update(data); mac2.verify(tag)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ("_st", "_nonce", "_key")
|
__slots__ = ("_st", "_nonce", "_key")
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
nonce: Buffer,
|
|
||||||
key: Buffer,
|
key: Buffer,
|
||||||
|
nonce: Buffer,
|
||||||
_other=None,
|
_other=None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize a MAC state with a nonce and key.
|
"""Initialize a MAC state with a nonce and key.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
TypeError: If key or nonce lengths are invalid.
|
TypeError: If key or nonce lengths are invalid.
|
||||||
"""
|
"""
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256x4_mac_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis256x4_mac_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis256x4_mac_state *", raw)
|
st = ffi.cast("aegis256x4_mac_state *", raw)
|
||||||
self._st = ffi.gc(st, libc.free)
|
self._st = ffi.gc(st, libc.free)
|
||||||
if _other is not None:
|
if _other is not None:
|
||||||
@@ -553,12 +561,12 @@ class Encryptor:
|
|||||||
|
|
||||||
__slots__ = ("_st",)
|
__slots__ = ("_st",)
|
||||||
|
|
||||||
def __init__(self, nonce: Buffer, key: Buffer, ad: Buffer | None = None):
|
def __init__(self, key: Buffer, nonce: Buffer, ad: Buffer | None = None):
|
||||||
"""Create an incremental encryptor.
|
"""Create an incremental encryptor.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ad: Associated data to bind to the encryption (optional).
|
ad: Associated data to bind to the encryption (optional).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@@ -570,7 +578,7 @@ class Encryptor:
|
|||||||
raise TypeError(f"key length must be {KEYBYTES}")
|
raise TypeError(f"key length must be {KEYBYTES}")
|
||||||
if nonce.nbytes != NPUBBYTES:
|
if nonce.nbytes != NPUBBYTES:
|
||||||
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256x4_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis256x4_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis256x4_state *", raw)
|
st = ffi.cast("aegis256x4_state *", raw)
|
||||||
st = ffi.gc(st, libc.free)
|
st = ffi.gc(st, libc.free)
|
||||||
_lib.aegis256x4_state_init(
|
_lib.aegis256x4_state_init(
|
||||||
@@ -704,12 +712,12 @@ class Decryptor:
|
|||||||
|
|
||||||
__slots__ = ("_st",)
|
__slots__ = ("_st",)
|
||||||
|
|
||||||
def __init__(self, nonce: Buffer, key: Buffer, ad: Buffer | None = None):
|
def __init__(self, key: Buffer, nonce: Buffer, ad: Buffer | None = None):
|
||||||
"""Create an incremental decryptor for detached tags.
|
"""Create an incremental decryptor for detached tags.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nonce: Nonce (32 bytes).
|
|
||||||
key: Key (32 bytes).
|
key: Key (32 bytes).
|
||||||
|
nonce: Nonce (32 bytes).
|
||||||
ad: Associated data used during encryption (optional).
|
ad: Associated data used during encryption (optional).
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
@@ -721,7 +729,7 @@ class Decryptor:
|
|||||||
raise TypeError(f"key length must be {KEYBYTES}")
|
raise TypeError(f"key length must be {KEYBYTES}")
|
||||||
if nonce.nbytes != NPUBBYTES:
|
if nonce.nbytes != NPUBBYTES:
|
||||||
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
raise TypeError(f"nonce length must be {NPUBBYTES}")
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256x4_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis256x4_state"), ALIGNMENT)
|
||||||
st = ffi.cast("aegis256x4_state *", raw)
|
st = ffi.cast("aegis256x4_state *", raw)
|
||||||
st = ffi.gc(st, libc.free)
|
st = ffi.gc(st, libc.free)
|
||||||
_lib.aegis256x4_state_init(
|
_lib.aegis256x4_state_init(
|
||||||
@@ -812,15 +820,15 @@ def new_state():
|
|||||||
|
|
||||||
The returned object is an ffi cdata pointer with automatic finalizer.
|
The returned object is an ffi cdata pointer with automatic finalizer.
|
||||||
"""
|
"""
|
||||||
# Allocate with 64-byte alignment using libc.posix_memalign
|
# Allocate with required alignment using libc.posix_memalign
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256x4_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis256x4_state"), ALIGNMENT)
|
||||||
ptr = ffi.cast("aegis256x4_state *", raw)
|
ptr = ffi.cast("aegis256x4_state *", raw)
|
||||||
return ffi.gc(ptr, libc.free)
|
return ffi.gc(ptr, libc.free)
|
||||||
|
|
||||||
|
|
||||||
def new_mac_state():
|
def new_mac_state():
|
||||||
"""Allocate and return a new aegis256x4_mac_state* with proper alignment."""
|
"""Allocate and return a new aegis256x4_mac_state* with proper alignment."""
|
||||||
raw = alloc_aligned(ffi.sizeof("aegis256x4_mac_state"), 64)
|
raw = alloc_aligned(ffi.sizeof("aegis256x4_mac_state"), ALIGNMENT)
|
||||||
ptr = ffi.cast("aegis256x4_mac_state *", raw)
|
ptr = ffi.cast("aegis256x4_mac_state *", raw)
|
||||||
return ffi.gc(ptr, libc.free)
|
return ffi.gc(ptr, libc.free)
|
||||||
|
|
||||||
@@ -832,6 +840,7 @@ __all__ = [
|
|||||||
"ABYTES_MIN",
|
"ABYTES_MIN",
|
||||||
"ABYTES_MAX",
|
"ABYTES_MAX",
|
||||||
"TAILBYTES_MAX",
|
"TAILBYTES_MAX",
|
||||||
|
"ALIGNMENT",
|
||||||
# one-shot functions
|
# one-shot functions
|
||||||
"encrypt_detached",
|
"encrypt_detached",
|
||||||
"decrypt_detached",
|
"decrypt_detached",
|
||||||
|
|||||||
+10
-10
@@ -30,9 +30,9 @@ def demo():
|
|||||||
|
|
||||||
# Detached encrypt/decrypt
|
# Detached encrypt/decrypt
|
||||||
ciphertext, mac = a.encrypt_detached(
|
ciphertext, mac = a.encrypt_detached(
|
||||||
nonce, key, message, associated_data, maclen=16
|
key, nonce, message, associated_data, maclen=16
|
||||||
)
|
)
|
||||||
plaintext = a.decrypt_detached(nonce, key, ciphertext, mac, associated_data)
|
plaintext = a.decrypt_detached(key, nonce, ciphertext, mac, associated_data)
|
||||||
print(
|
print(
|
||||||
"detached enc: c=",
|
"detached enc: c=",
|
||||||
hx(ciphertext),
|
hx(ciphertext),
|
||||||
@@ -43,30 +43,30 @@ def demo():
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Attached encrypt/decrypt
|
# Attached encrypt/decrypt
|
||||||
ciphertext_with_tag = a.encrypt(nonce, key, message, associated_data, maclen=32)
|
ciphertext_with_tag = a.encrypt(key, nonce, message, associated_data, maclen=32)
|
||||||
plaintext2 = a.decrypt(nonce, key, ciphertext_with_tag, associated_data, maclen=32)
|
plaintext2 = a.decrypt(key, nonce, ciphertext_with_tag, associated_data, maclen=32)
|
||||||
print(
|
print(
|
||||||
"attached enc: ct=", hx(ciphertext_with_tag), " dec_ok=", plaintext2 == message
|
"attached enc: ct=", hx(ciphertext_with_tag), " dec_ok=", plaintext2 == message
|
||||||
)
|
)
|
||||||
|
|
||||||
# Stream generation (None nonce allowed) -> deterministic for a given key
|
# Stream generation (None nonce allowed) -> deterministic for a given key
|
||||||
stream = bytearray(64)
|
stream = bytearray(64)
|
||||||
a.stream(None, key, into=stream)
|
a.stream(key, None, into=stream)
|
||||||
print("stream (first 16 bytes):", hx(stream, 16))
|
print("stream (first 16 bytes):", hx(stream, 16))
|
||||||
|
|
||||||
# Unauthenticated mode round-trip (INSECURE; compatibility only)
|
# Unauthenticated mode round-trip (INSECURE; compatibility only)
|
||||||
c2 = bytearray(len(message))
|
c2 = bytearray(len(message))
|
||||||
a.encrypt_unauthenticated(message, nonce, key, into=c2)
|
a.encrypt_unauthenticated(key, nonce, message, into=c2)
|
||||||
m2 = bytearray(len(message))
|
m2 = bytearray(len(message))
|
||||||
a.decrypt_unauthenticated(c2, nonce, key, into=m2)
|
a.decrypt_unauthenticated(key, nonce, c2, into=m2)
|
||||||
print("unauth round-trip ok:", bytes(m2) == message)
|
print("unauth round-trip ok:", bytes(m2) == message)
|
||||||
|
|
||||||
# MAC: compute then verify
|
# MAC: compute then verify
|
||||||
mac_state = a.Mac(nonce, key)
|
mac_state = a.Mac(key, nonce)
|
||||||
mac_state.update(message)
|
mac_state.update(message)
|
||||||
mac32 = mac_state.final(32)
|
mac32 = mac_state.final(32)
|
||||||
|
|
||||||
mac_verify_state = a.Mac(nonce, key)
|
mac_verify_state = a.Mac(key, nonce)
|
||||||
mac_verify_state.update(message)
|
mac_verify_state.update(message)
|
||||||
try:
|
try:
|
||||||
mac_verify_state.verify(mac32)
|
mac_verify_state.verify(mac32)
|
||||||
@@ -81,7 +81,7 @@ def demo():
|
|||||||
src = bytearray(total)
|
src = bytearray(total)
|
||||||
dst = bytearray(total)
|
dst = bytearray(total)
|
||||||
t0 = time.perf_counter()
|
t0 = time.perf_counter()
|
||||||
a.encrypt_unauthenticated(src, nonce, key, into=dst)
|
a.encrypt_unauthenticated(key, nonce, src, into=dst)
|
||||||
t1 = time.perf_counter()
|
t1 = time.perf_counter()
|
||||||
secs = t1 - t0
|
secs = t1 - t0
|
||||||
gib = total / float(1 << 30)
|
gib = total / float(1 << 30)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ def bench_encrypt(alg_name: str, a) -> None:
|
|||||||
|
|
||||||
t0 = time.perf_counter()
|
t0 = time.perf_counter()
|
||||||
for _ in range(ITERATIONS):
|
for _ in range(ITERATIONS):
|
||||||
a.encrypt(nonce, key, mview, None, maclen=maclen, into=buf)
|
a.encrypt(key, nonce, mview, None, maclen=maclen, into=buf)
|
||||||
t1 = time.perf_counter()
|
t1 = time.perf_counter()
|
||||||
|
|
||||||
# Prevent any unrealistic optimization assumptions
|
# Prevent any unrealistic optimization assumptions
|
||||||
@@ -66,7 +66,7 @@ def bench_mac(alg_name: str, a) -> None:
|
|||||||
buf = bytearray(MSG_LEN)
|
buf = bytearray(MSG_LEN)
|
||||||
buf[:] = _random_bytes(len(buf))
|
buf[:] = _random_bytes(len(buf))
|
||||||
|
|
||||||
mac0 = a.Mac(nonce, key)
|
mac0 = a.Mac(key, nonce)
|
||||||
mac_out = bytearray(a.ABYTES_MAX)
|
mac_out = bytearray(a.ABYTES_MAX)
|
||||||
|
|
||||||
t0 = time.perf_counter()
|
t0 = time.perf_counter()
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Regenerate aegis*.py modules from the canonical template aegis256x4.py.
|
||||||
|
|
||||||
|
Changes per variant:
|
||||||
|
- Replace module name (aegis256x4 -> target)
|
||||||
|
- Replace label (AEGIS-256X4 -> target label like AEGIS-128L)
|
||||||
|
- Replace only the ALIGNMENT = <int> value
|
||||||
|
|
||||||
|
We do not touch alloc_aligned(...) calls or any code formatting. Blank lines
|
||||||
|
after ALIGNMENT are preserved.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import pathlib
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Template and target locations
|
||||||
|
ROOT = (
|
||||||
|
pathlib.Path(__file__).resolve().parents[2]
|
||||||
|
if (pathlib.Path(__file__).resolve().parents[0].name == "tools")
|
||||||
|
else pathlib.Path.cwd()
|
||||||
|
)
|
||||||
|
PY_DIR = ROOT / "python"
|
||||||
|
AEGIS_DIR = PY_DIR / "aegis"
|
||||||
|
TEMPLATE = AEGIS_DIR / "aegis256x4.py"
|
||||||
|
|
||||||
|
# Variants to generate (template excluded) and their ALIGNMENT values
|
||||||
|
VARIANT_ALIGN = {
|
||||||
|
"aegis256": 16,
|
||||||
|
"aegis256x2": 32,
|
||||||
|
"aegis256x4": 64,
|
||||||
|
"aegis128l": 32,
|
||||||
|
"aegis128x2": 64,
|
||||||
|
"aegis128x4": 64,
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMPLATE_NAME = "aegis256x4"
|
||||||
|
TEMPLATE_LABEL = "AEGIS-256X4"
|
||||||
|
|
||||||
|
ALIGNMENT_LINE_RE = re.compile(r"^(ALIGNMENT\s*=\s*)(\d+)(\s*)$", re.MULTILINE)
|
||||||
|
|
||||||
|
|
||||||
|
def set_alignment_only(text: str, value: int) -> str:
|
||||||
|
"""Replace only the numeric ALIGNMENT value, preserving surrounding whitespace and lines.
|
||||||
|
|
||||||
|
This preserves any empty lines following the ALIGNMENT assignment because
|
||||||
|
the line ending is not part of the match; we keep any trailing spaces too.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _sub(m: re.Match[str]) -> str:
|
||||||
|
prefix, _num, suffix = m.group(1), m.group(2), m.group(3)
|
||||||
|
return f"{prefix}{value}{suffix}"
|
||||||
|
|
||||||
|
return ALIGNMENT_LINE_RE.sub(_sub, text)
|
||||||
|
|
||||||
|
|
||||||
|
def algo_label(name: str) -> str:
|
||||||
|
"""Return the canonical label like AEGIS-256X4 for a module name like aegis256x4."""
|
||||||
|
if not name.startswith("aegis"):
|
||||||
|
raise ValueError(f"Unexpected algorithm name: {name}")
|
||||||
|
return "AEGIS-" + name[5:].upper()
|
||||||
|
|
||||||
|
|
||||||
|
def generate_variant(template_src: str, variant: str) -> str:
|
||||||
|
# 1) replace lowercase template name
|
||||||
|
s = template_src.replace(TEMPLATE_NAME, variant)
|
||||||
|
# 2) replace uppercase label
|
||||||
|
s = s.replace(TEMPLATE_LABEL, algo_label(variant))
|
||||||
|
# 3) set ALIGNMENT constant value using fallback map
|
||||||
|
align_value = VARIANT_ALIGN.get(variant, 64)
|
||||||
|
s = set_alignment_only(s, align_value)
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
if not TEMPLATE.exists():
|
||||||
|
print(f"Template not found: {TEMPLATE}", file=sys.stderr)
|
||||||
|
return 2
|
||||||
|
template_src = TEMPLATE.read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
# Safety: ensure we are working from an up-to-date template that contains expected tokens
|
||||||
|
if TEMPLATE_NAME not in template_src or TEMPLATE_LABEL not in template_src:
|
||||||
|
print(
|
||||||
|
"Template file does not contain expected identifiers; aborting.",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
return 3
|
||||||
|
|
||||||
|
wrote = []
|
||||||
|
for variant in VARIANT_ALIGN.keys():
|
||||||
|
# Skip the template itself; recreate all other modules
|
||||||
|
if variant == TEMPLATE_NAME:
|
||||||
|
continue
|
||||||
|
dst = AEGIS_DIR / f"{variant}.py"
|
||||||
|
content = generate_variant(template_src, variant)
|
||||||
|
dst.write_text(content, encoding="utf-8")
|
||||||
|
wrote.append(dst.relative_to(ROOT))
|
||||||
|
|
||||||
|
print("Generated modules:")
|
||||||
|
for p in wrote:
|
||||||
|
print(" -", p)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Reference in New Issue
Block a user