import sys
from pathlib import Path
import pytest
try:
from cryptography.x509 import load_der_x509_certificate, load_pem_x509_certificate
from cryptography.exceptions import UnsupportedAlgorithm
_HAS_CRYPTOGRAPHY = True
except ImportError:
_HAS_CRYPTOGRAPHY = False
pytestmark = pytest.mark.skipif(
not _HAS_CRYPTOGRAPHY,
reason="cryptography package not installed",
)
_WORKSPACE = Path(__file__).resolve().parent.parent.parent
_CERT_DIR = _WORKSPACE / "tests" / "vectors" / "dilithium-certificates" / "examples"
_CERTS = [
("ML-DSA-44", _CERT_DIR / "ML-DSA-44.crt"),
("ML-DSA-65", _CERT_DIR / "ML-DSA-65.crt"),
("ML-DSA-87", _CERT_DIR / "ML-DSA-87.crt"),
]
def _load_cert(path: Path):
if not path.exists():
pytest.skip(f"certificate not found: {path} — run the Rust benchmark first")
raw = path.read_bytes()
if raw.lstrip().startswith(b"-----"):
return load_pem_x509_certificate(raw)
return load_der_x509_certificate(raw)
@pytest.mark.parametrize("variant,path", _CERTS)
def test_pyca_mldsa_public_key(variant: str, path: Path) -> None:
cert = _load_cert(path)
assert cert.subject is not None
assert cert.not_valid_before_utc is not None
try:
key = cert.public_key()
key_type = type(key).__name__
print(f"\n {variant}: public_key() returned {key_type}")
except UnsupportedAlgorithm as exc:
print(f"\n {variant}: public_key() raised UnsupportedAlgorithm: {exc}")
def main() -> None:
if not _HAS_CRYPTOGRAPHY:
print("SKIP: cryptography package not installed.")
print(" Run with: uv run --with cryptography python tests/python/test_pyca_mldsa.py")
sys.exit(0)
print("PyCA ML-DSA public-key access test")
print(f"cryptography version: ", end="")
import cryptography
print(cryptography.__version__)
print()
failed = 0
for variant, path in _CERTS:
if not path.exists():
print(f" SKIP {variant}: {path} not found")
continue
raw = path.read_bytes()
cert = (load_pem_x509_certificate(raw) if raw.lstrip().startswith(b"-----")
else load_der_x509_certificate(raw))
print(f" {variant}:")
print(f" subject: {cert.subject.rfc4514_string()}")
print(f" not_before: {cert.not_valid_before_utc}")
print(f" not_after: {cert.not_valid_after_utc}")
try:
key = cert.public_key()
print(f" public_key: {type(key).__name__} [OK]")
except UnsupportedAlgorithm as exc:
print(f" public_key: UnsupportedAlgorithm — {exc}")
except Exception as exc:
print(f" public_key: ERROR — {exc}")
failed += 1
print()
sys.exit(1 if failed else 0)
if __name__ == "__main__":
main()