Metadata-Version: 2.4
Name: kpqc
Version: 0.1.0
Summary: Python APIs for AIMer, HAETAE, NTRU+, and SMAUG-T.
License-Expression: MIT
Project-URL: Homepage, https://github.com/osuolfou/kpqc-py
Project-URL: Repository, https://github.com/osuolfou/kpqc-py
Project-URL: Issues, https://github.com/osuolfou/kpqc-py/issues
Keywords: kpqc,post-quantum,cryptography,aimer,haetae,ntruplus,smaug-t
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: C
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: vendor/AIMer/LICENSE
License-File: vendor/HAETAE/LICENSE
License-File: vendor/NTRUplus/LICENSE
License-File: vendor/SMAUG-T/LICENSE
License-File: THIRD_PARTY_NOTICES.md
Dynamic: license-file

# KpqC

KpqC provides typed, synchronous Python APIs for AIMer, HAETAE, NTRU+,
and SMAUG-T.

## Runtime support

- CPython 3.10 or newer
- macOS or Linux
- A C11 compiler and Python development headers when building from source

## Install

```sh
python -m pip install kpqc
```

## Available schemes

| Algorithm | Type | Exports |
| --- | --- | --- |
| **AIMer** | Signature | `aimer128f`, `aimer128s`, `aimer192f`, `aimer192s`, `aimer256f`, `aimer256s` |
| **HAETAE** | Signature | `haetae2`, `haetae3`, `haetae5` |
| **NTRU+** | Key encapsulation | `ntruplus768`, `ntruplus864`, `ntruplus1152` |
| **SMAUG&#8209;T** | Key encapsulation | `smaugt128`, `smaugt192`, `smaugt256`, `timer` |

Importing from an algorithm module keeps the entry point focused:

```python
from kpqc.aimer import aimer128f

payload = b"release-manifest:v3"
keys = aimer128f.generate_key_pair()
proof = aimer128f.sign(payload, keys.secret_key)

if not aimer128f.verify(payload, proof, keys.public_key):
    raise RuntimeError("Signature verification failed")
```

### Signature contexts

AIMer and HAETAE accept an optional context. A context separates signatures
created for different application purposes and may contain up to 255 bytes.

```python
from kpqc.haetae import haetae3

payload = b"account=42"
context = b"audit-record"
keys = haetae3.generate_key_pair()

signature = haetae3.sign(payload, keys.secret_key, context=context)
valid = haetae3.verify(
    payload,
    signature,
    keys.public_key,
    context=context,
)

print(valid)  # True
```

Verification fails when the supplied context does not match the one used for
signing.

### Key encapsulation

A KEM creates a shared secret for a sender and a recipient. The public key may
be distributed; the secret key and resulting shared secret must remain private.

```python
from kpqc.smaugt import smaugt192

recipient = smaugt192.generate_key_pair()

outbound = smaugt192.encapsulate(recipient.public_key)
# Send outbound.ciphertext to the recipient.

inbound_secret = smaugt192.decapsulate(
    outbound.ciphertext,
    recipient.secret_key,
)

print(inbound_secret == outbound.shared_secret)  # True
```

## Imports

Each family has a dedicated module:

```python
from kpqc.aimer import aimer256s
from kpqc.haetae import haetae5
from kpqc.ntruplus import ntruplus1152
from kpqc.smaugt import timer
```

All named algorithms are also exported from the package root:

```python
from kpqc import (
    KeyEncapsulationAlgorithm,
    SignatureAlgorithm,
    aimer192f,
    ntruplus864,
)

signer: SignatureAlgorithm = aimer192f
key_exchange: KeyEncapsulationAlgorithm = ntruplus864
```

## Data and failures

Inputs and outputs are `bytes` instances. Each algorithm exposes an `id` and
an immutable `sizes` object.

### Parameter sizes

All sizes are in bytes.

#### Signatures

| Algorithm | Public key | Secret key | Signature |
| --- | ---: | ---: | ---: |
| `aimer128f` | 32 | 48 | 5,888 |
| `aimer128s` | 32 | 48 | 4,160 |
| `aimer192f` | 48 | 72 | 13,056 |
| `aimer192s` | 48 | 72 | 9,120 |
| `aimer256f` | 64 | 96 | 25,120 |
| `aimer256s` | 64 | 96 | 17,056 |
| `haetae2` | 992 | 1,408 | 1,474 |
| `haetae3` | 1,472 | 2,112 | 2,349 |
| `haetae5` | 2,080 | 2,752 | 2,948 |

#### Key encapsulation

| Algorithm | Public key | Secret key | Ciphertext | Shared secret |
| --- | ---: | ---: | ---: | ---: |
| `ntruplus768` | 1,152 | 2,336 | 1,152 | 32 |
| `ntruplus864` | 1,296 | 2,624 | 1,296 | 32 |
| `ntruplus1152` | 1,728 | 3,488 | 1,728 | 32 |
| `smaugt128` | 672 | 832 | 672 | 32 |
| `smaugt192` | 1,088 | 1,312 | 992 | 32 |
| `smaugt256` | 1,440 | 1,728 | 1,376 | 32 |
| `timer` | 672 | 832 | 608 | 32 |

Methods reject values of the wrong type or size. Signature verification returns
`False` for an invalid signature. NTRU+ rejects an invalid ciphertext.
SMAUG-T performs implicit rejection and returns a replacement secret instead;
that value will not equal the sender's shared secret.

## Distribution

The published package includes Python modules, type information, and native
extensions. Each parameter set is initialized on first use. The package has no
runtime dependencies.

## Security

The native cores are compiled from the upstream algorithm implementations.
This package has not received an independent security audit and does not provide
a constant-time execution guarantee. Assess those constraints before using it
with sensitive production keys.

Third-party licenses and attributions are listed in
[THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md).
