Add aeg.cipher(alg) for loading modules by name in str. Added aeg.CIPHERS mapping of the nominal names to module names and Cipher for typing literals.
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import importlib
|
||||
|
||||
from ._ciphers import CIPHERS, CipherName
|
||||
from ._typing import Cipher
|
||||
|
||||
__all__ = ["cipher", "CIPHERS", "Cipher", "CipherName"]
|
||||
|
||||
|
||||
def cipher(alg: CipherName) -> Cipher:
|
||||
"""Acquire a cipher module by name."""
|
||||
name = alg.lower().replace("-", "")
|
||||
if name == "aegis128":
|
||||
name = "aegis128l" # AEGIS-128 is dead, the user meant AEGIS-128L
|
||||
if name in CIPHERS.values():
|
||||
return importlib.import_module(f".{name}", __package__) # type: ignore[return-value]
|
||||
raise ValueError(f"Unknown algorithm {alg!r}. Valid options: {', '.join(CIPHERS)}")
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# This file is generated by tools/generate.py. Do not edit.
|
||||
from typing import Literal
|
||||
|
||||
CipherName = Literal[
|
||||
"AEGIS-128L",
|
||||
"AEGIS-128X2",
|
||||
"AEGIS-128X4",
|
||||
"AEGIS-256",
|
||||
"AEGIS-256X2",
|
||||
"AEGIS-256X4",
|
||||
]
|
||||
|
||||
CIPHERS: dict[CipherName, str] = {
|
||||
"AEGIS-128L": "aegis128l",
|
||||
"AEGIS-128X2": "aegis128x2",
|
||||
"AEGIS-128X4": "aegis128x4",
|
||||
"AEGIS-256": "aegis256",
|
||||
"AEGIS-256X2": "aegis256x2",
|
||||
"AEGIS-256X4": "aegis256x4",
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
from typing import TYPE_CHECKING, Protocol
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .util import Buffer
|
||||
|
||||
__all__ = ["Cipher"]
|
||||
|
||||
|
||||
class _Mac(Protocol):
|
||||
def reset(self) -> None: ...
|
||||
def clone(self) -> "_Mac": ...
|
||||
def update(self, data: "Buffer") -> None: ...
|
||||
def final(self, into: "Buffer | None" = None) -> bytearray | memoryview: ...
|
||||
def digest(self) -> bytes: ...
|
||||
def hexdigest(self) -> str: ...
|
||||
def verify(self, mac: "Buffer") -> None: ...
|
||||
|
||||
|
||||
class _Encryptor(Protocol):
|
||||
def update(
|
||||
self, message: "Buffer", into: "Buffer | None" = None
|
||||
) -> bytearray | memoryview: ...
|
||||
def final(self, into: "Buffer | None" = None) -> bytearray | memoryview: ...
|
||||
|
||||
|
||||
class _Decryptor(Protocol):
|
||||
def update(
|
||||
self, ct: "Buffer", into: "Buffer | None" = None
|
||||
) -> bytearray | memoryview: ...
|
||||
def final(self, mac: "Buffer") -> None: ...
|
||||
|
||||
|
||||
class Cipher(Protocol):
|
||||
NAME: str
|
||||
KEYBYTES: int
|
||||
NONCEBYTES: int
|
||||
MACBYTES: int
|
||||
MACBYTES_LONG: int
|
||||
ALIGNMENT: int
|
||||
RATE: int
|
||||
|
||||
Mac: type[_Mac]
|
||||
Encryptor: type[_Encryptor]
|
||||
Decryptor: type[_Decryptor]
|
||||
|
||||
@staticmethod
|
||||
def random_key() -> bytearray: ...
|
||||
@staticmethod
|
||||
def random_nonce() -> bytearray: ...
|
||||
@staticmethod
|
||||
def encrypt_detached(
|
||||
key: "Buffer",
|
||||
nonce: "Buffer",
|
||||
message: "Buffer",
|
||||
ad: "Buffer | None" = None,
|
||||
*,
|
||||
maclen: int = ...,
|
||||
ct_into: "Buffer | None" = None,
|
||||
mac_into: "Buffer | None" = None,
|
||||
) -> tuple[bytearray | memoryview, bytearray | memoryview]: ...
|
||||
@staticmethod
|
||||
def decrypt_detached(
|
||||
key: "Buffer",
|
||||
nonce: "Buffer",
|
||||
ct: "Buffer",
|
||||
mac: "Buffer",
|
||||
ad: "Buffer | None" = None,
|
||||
*,
|
||||
into: "Buffer | None" = None,
|
||||
) -> bytearray | memoryview: ...
|
||||
@staticmethod
|
||||
def encrypt(
|
||||
key: "Buffer",
|
||||
nonce: "Buffer",
|
||||
message: "Buffer",
|
||||
ad: "Buffer | None" = None,
|
||||
*,
|
||||
maclen: int = ...,
|
||||
into: "Buffer | None" = None,
|
||||
) -> bytearray | memoryview: ...
|
||||
@staticmethod
|
||||
def decrypt(
|
||||
key: "Buffer",
|
||||
nonce: "Buffer",
|
||||
ct: "Buffer",
|
||||
ad: "Buffer | None" = None,
|
||||
*,
|
||||
maclen: int = ...,
|
||||
into: "Buffer | None" = None,
|
||||
) -> bytearray | memoryview: ...
|
||||
@staticmethod
|
||||
def stream(
|
||||
key: "Buffer",
|
||||
nonce: "Buffer | None",
|
||||
length: int | None = None,
|
||||
*,
|
||||
into: "Buffer | None" = None,
|
||||
) -> "bytearray | Buffer": ...
|
||||
@staticmethod
|
||||
def encrypt_unauthenticated(
|
||||
key: "Buffer",
|
||||
nonce: "Buffer",
|
||||
message: "Buffer",
|
||||
*,
|
||||
into: "Buffer | None" = None,
|
||||
) -> bytearray | memoryview: ...
|
||||
@staticmethod
|
||||
def decrypt_unauthenticated(
|
||||
key: "Buffer",
|
||||
nonce: "Buffer",
|
||||
ct: "Buffer",
|
||||
*,
|
||||
into: "Buffer | None" = None,
|
||||
) -> bytearray | memoryview: ...
|
||||
@staticmethod
|
||||
def mac(
|
||||
key: "Buffer",
|
||||
nonce: "Buffer",
|
||||
data: "Buffer",
|
||||
maclen: int = ...,
|
||||
into: "Buffer | None" = None,
|
||||
) -> bytearray | memoryview: ...
|
||||
+31
-1
@@ -273,6 +273,23 @@ def generate_python_modules(
|
||||
return updated, unchanged
|
||||
|
||||
|
||||
def generate_ciphers_module(constants: Dict[str, Dict[str, int]]) -> str:
|
||||
labels = [algo_label(variant) for variant in constants]
|
||||
literal_items = ", ".join(f'"{label}"' for label in labels)
|
||||
lines = [
|
||||
"# This file is generated by tools/generate.py. Do not edit.",
|
||||
"from typing import Literal",
|
||||
"",
|
||||
f"CipherName = Literal[{literal_items}]",
|
||||
"",
|
||||
"CIPHERS: dict[CipherName, str] = {",
|
||||
]
|
||||
for variant in constants:
|
||||
lines.append(f' "{algo_label(variant)}": "{variant}",')
|
||||
lines.append("}")
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def main() -> int:
|
||||
root = pathlib.Path(__file__).parent.parent
|
||||
libaegis_src_dir = root / "libaegis" / "src"
|
||||
@@ -304,7 +321,20 @@ def main() -> int:
|
||||
cdef_path.write_bytes(cdef_content.encode())
|
||||
print(f" - Updated {cdef_path}", file=sys.stderr)
|
||||
|
||||
print("Step 3: Generating Python modules...", file=sys.stderr)
|
||||
print("Step 3: Generating _ciphers.py...", file=sys.stderr)
|
||||
ciphers_path = pyaegis_dir / "_ciphers.py"
|
||||
ciphers_content = generate_ciphers_module(constants)
|
||||
|
||||
if (
|
||||
ciphers_path.exists()
|
||||
and ciphers_path.read_text(encoding="utf-8") == ciphers_content
|
||||
):
|
||||
print(f" - No changes to {ciphers_path.name}", file=sys.stderr)
|
||||
else:
|
||||
ciphers_path.write_bytes(ciphers_content.encode())
|
||||
print(f" - Updated {ciphers_path.name}", file=sys.stderr)
|
||||
|
||||
print("Step 4: Generating Python modules...", file=sys.stderr)
|
||||
try:
|
||||
updated, unchanged = generate_python_modules(
|
||||
pyaegis_dir / "aegis256x4.py", pyaegis_dir, constants
|
||||
|
||||
Reference in New Issue
Block a user