Metadata-Version: 2.4
Name: aegis-verifier
Version: 0.1.2
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security :: Cryptography
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Summary: Aegis: ML-DSA-65 post-quantum agent identity verifier
License-Expression: Apache-2.0
Requires-Python: >=3.11
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# aegis-verifier

ML-DSA-65 (FIPS 204) post-quantum agent identity verifier for the Aegis platform.

Verifies Merkle Tree Agent Certificates (MTACs) issued by an Aegis Certificate
Authority. Built with PyO3 + maturin from a Rust core.

## Requirements

- Python 3.11 or later
- No native build dependencies at install time (liboqs is statically bundled)

## Installation

```sh
pip install aegis-verifier
```

A pre-built wheel is available for Linux x86_64/aarch64 (glibc and musl),
macOS universal2 (Intel + Apple Silicon), and Windows x86_64.

## Basic usage

```python
import aegis_verifier

# All inputs are raw bytes in wire-v1 format (see docs/spec/wire-v1.md).
try:
    result = aegis_verifier.verify_inclusion(
        leaf_bytes=leaf_bytes,        # dcbor-encoded MtacLeaf
        proof_bytes=proof_bytes,      # wire-v1 encoded InclusionProof
        sth_bytes=sth_bytes,          # wire-v1 STH envelope (the bytes ML-DSA signed)
        signature=signature,          # 3309-byte ML-DSA-65 signature
        ca_public_key=ca_public_key,  # 1952-byte ML-DSA-65 public key
    )
    print(f"Verified: leaf_index={result.leaf_index}, "
          f"tree_size={result.tree_size}, "
          f"timestamp_ms={result.timestamp_ms}")
except aegis_verifier.AegisInvalidProofError as e:
    print(f"Proof or signature invalid: {e}")
except aegis_verifier.AegisStaleSthError as e:
    print(f"STH is stale: {e}")
except aegis_verifier.AegisVerificationError as e:
    print(f"Verification error: {e}")
```

## Exception hierarchy

```
Exception
  AegisVerificationError          # base class for all Aegis failures
    AegisInvalidProofError        # signature invalid, proof mismatch, or leaf hash fail
    AegisStaleSthError            # STH older than caller-supplied max_age
```

`verify_inclusion` RAISES on all failure paths. It never returns a
`verified=False` sentinel — a successful return always means verification passed.

## Wire format

- `leaf_bytes`: dcbor canonical encoding of `MtacLeaf` (RFC 8949 §4.2.1 CDER profile)
- `proof_bytes`: CBOR `array(3)` of `[tree_size: uint, leaf_index: uint, path: array<bstr(32)>]`
- `sth_bytes`: CBOR `array(2)` of `[tstr("AEGIS-STH-v1"), bstr(body)]` where body is
  `array(5)` of `[log_id: bstr(32), tree_size: uint, timestamp: uint, root_hash: bstr(32), extensions: array]`
- `signature`: 3309-byte raw ML-DSA-65 signature (FIPS 204, Algorithm 3)
- `ca_public_key`: 1952-byte raw ML-DSA-65 public key (FIPS 204)

See `docs/spec/wire-v1.md` in the source repository for the full normative spec.

## Cryptographic details

- Algorithm: ML-DSA-65 (FIPS 204 final), also known as CRYSTALS-Dilithium level 3
- Tree: RFC 9162-inspired binary Merkle hash tree with SHA-256 leaf and node hashing
- Domain separation: dual-layer per AD-1.6-02 — envelope context string
  `"AEGIS-STH-v1"` in wire bytes (auditor-visible) PLUS FIPS 204 §5.2 ctx
  parameter `b"AEGIS-STH-v1"` (cryptographically bound, not in wire bytes)
- Native library: liboqs 0.11.0 (Open Quantum Safe), statically bundled

## License

Apache-2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE) for details.

