diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..eff1926
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,27 @@
+# Contributing to Cryptonite-go
+
+## Development Setup
+```bash
+git clone https://github.com/AeonDave/cryptonite-go
+cd cryptonite-go
+go test ./...
+```
+
+## Guidelines
+
+- **Tests required**: Add KAT vectors for new algorithms
+- **Formatting**: Run `go fmt ./...` and `golangci-lint run`
+- **Performance**: Include benchmarks in `test/`
+- **Documentation**: Update docs/ if adding features
+
+## Adding Test Vectors
+
+See [docs/TESTING.md](docs/TESTING.md) for KAT format.
+
+## PR Checklist
+
+- [ ] Tests pass (`go test -race ./...`)
+- [ ] Benchmarks included
+- [ ] Documentation updated
+- [ ] Commit messages descriptive
+
diff --git a/README.md b/README.md
index 0ff185e..75f3502 100644
--- a/README.md
+++ b/README.md
@@ -28,151 +28,41 @@ Minimal, modern, ultra-fast, dependency-free cryptography go library, using only
go get github.com/AeonDave/cryptonite-go
```
-## Supported algorithms
-
-### AEAD
-
-| Algorithm | Constructor(s) | Key | Nonce | Tag | Notes | RFC / Spec |
-|--------------------|------------------------------------------------|-----------|---------------------|-----|------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
-| ASCON-128a | `aead.NewAscon128()` | 16B | 16B | 16B | NIST LwC winner | [FIPS 208](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.208.pdf) |
-| ASCON-80pq | `aead.NewAscon80pq()` | 20B | 16B | 16B | PQ-hardened variant | [FIPS 208](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.208.pdf) |
-| GIFT-COFB | `aead.NewGiftCofb()` | 16B | 16B | 16B | Ultra-lightweight finalist | [IACR 2018/803](https://eprint.iacr.org/2018/803.pdf) |
-| SKINNY-AEAD-M1 | `aead.NewSkinnyAead()` | 16B | 16B | 16B | Tweakable block-cipher AEAD (128-bit tag) | [NIST LwC Round 1 submission](https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/round-1/submissions/SKINNY.pdf) |
-| Xoodyak-Encrypt | `aead.NewXoodyak()` | 16B | 16B | 16B | Cyclist mode | [Xoodyak specification](https://keccak.team/files/Xoodyak-specification.pdf) |
-| ChaCha20-Poly1305 | `aead.NewChaCha20Poly1305()` | 32B | 12B | 16B | RFC 8439 layout | [RFC 8439](https://www.rfc-editor.org/rfc/rfc8439.html) |
-| XChaCha20-Poly1305 | `aead.NewXChaCha20Poly1305()` | 32B | 24B | 16B | Derives nonce via HChaCha20 | [draft-irtf-cfrg-xchacha-03](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha-03) |
-| AES-GCM | `aead.NewAESGCM()` | 16/24/32B | 12B | 16B | AES-NI optional | [NIST SP 800-38D](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf) |
-| AES-GCM-SIV | `aead.NewAesGcmSiv()` | 16/32B | 12B | 16B | Nonce misuse resistant | [RFC 8452](https://www.rfc-editor.org/rfc/rfc8452.html) |
-| AES-SIV (128/256) | `aead.NewAES128SIV()`
`aead.NewAES256SIV()` | 32B / 64B | Deterministic (AAD) | 16B | Deterministic SIV construction; optional multi-AD support via `aead.MultiAssociatedData` | [RFC 5297](https://www.rfc-editor.org/rfc/rfc5297.html) |
-| Deoxys-II-256-128 | `aead.NewDeoxysII128()` | 32B | 15B | 16B | NIST LwC finalist | [NIST LWC finalist spec](https://csrc.nist.gov/csrc/media/Projects/lightweight-cryptography/documents/finalists/deoxys-spec-final.pdf) |
-
-### Hashing
-
-Every hashing entry point lives under the `hash` package so callers can rely on the uniform `hash.Hasher` interface or
-the Go `hash.Hash` type without importing algorithm-specific subpackages.
-
-| Algorithm | Streaming constructor | Single-shot helper(s) | Notes | RFC / Spec |
-|--------------|--------------------------------------------------|-------------------------------------------------|----------------------------------------------------|------------------------------------------------------------------------------|
-| SHA3-224 | `hash.NewSHA3224()` | `hash.NewSHA3224Hasher()` / `hash.Sum224` | 224-bit (28B) digest | [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) |
-| SHA3-256 | `hash.NewSHA3256()` | `hash.NewSHA3256Hasher()` / `hash.Sum256` | 256-bit (32B) digest | [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) |
-| SHA3-384 | `hash.NewSHA3384()` | `hash.NewSHA3384Hasher()` / `hash.Sum384` | 384-bit (48B) digest | [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) |
-| SHA3-512 | `hash.NewSHA3512()` | `hash.NewSHA3512Hasher()` / `hash.Sum512` | 512-bit (64B) digest | [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) |
-| BLAKE2b | `hash.NewBlake2b()` / `hash.NewBlake2bBuilder()` | `hash.NewBlake2bHasher()` | Configurable 1–64B digest, optional keyed MAC mode | [RFC 7693](https://www.rfc-editor.org/rfc/rfc7693.html) |
-| BLAKE2s | `hash.NewBlake2s()` / `hash.NewBlake2sBuilder()` | `hash.NewBlake2sHasher()` | Configurable 1–32B digest, optional keyed MAC mode | [RFC 7693](https://www.rfc-editor.org/rfc/rfc7693.html) |
-| Xoodyak Hash | `hash.NewXoodyak()` | `hash.NewXoodyakHasher()` / `hash.SumXoodyak()` | 32B Cyclist hash | [Xoodyak specification](https://keccak.team/files/Xoodyak-specification.pdf) |
-
-#### SP 800-185 constructions
-
-| Algorithm | Helper(s) | Notes | RFC / Spec |
-|-----------------------|----------------------------------------------------------------------------------------|-----------------------------------------------|----------------------------------------------------------------------------------------------|
-| TupleHash128 / 256 | `hash.TupleHash128(tuple, outLen, customization)` / `hash.TupleHash256` | Tuple of byte-strings, optional customization | [NIST SP 800-185](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf) |
-| ParallelHash128 / 256 | `hash.ParallelHash128(msg, blockSize, outLen, customization)` / `hash.ParallelHash256` | Parallel-friendly hashing for large messages | [NIST SP 800-185](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf) |
-
-### XOF (Extendable-output function)
-
-Constructors live under the dedicated `xof` package and return the shared `xof.XOF` interface so extendable-output
-primitives can be swapped transparently.
-
-| Algorithm | Constructor | Notes | RFC / Spec |
-|-------------|------------------|--------------------------------------------|------------------------------------------------------------------------------|
-| SHAKE128 | `xof.SHAKE128()` | Arbitrary-length output (FIPS 202) | [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) |
-| SHAKE256 | `xof.SHAKE256()` | Wider security margin, arbitrary output | [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) |
-| BLAKE2b XOF | `xof.Blake2b()` | Supports fixed-length and streaming output | [BLAKE2 XOF](https://www.blake2.net/blake2x.pdf) |
-| BLAKE2s XOF | `xof.Blake2s()` | Lightweight XOF with keyed support | [BLAKE2 XOF](https://www.blake2.net/blake2x.pdf) |
-| Xoodyak XOF | `xof.Xoodyak()` | Cyclist extendable-output mode | [Xoodyak specification](https://keccak.team/files/Xoodyak-specification.pdf) |
-
-### KDF (Key derivation function)
-
-| Algorithm | Deriver constructor | Single-shot helper(s) | Notes | RFC / Spec |
-|---------------------|------------------------------------------------------|-----------------------------------------------------------------------------|--------------------------------------------------------------|---------------------------------------------------------|
-| HKDF-SHA256 | `kdf.NewHKDFSHA256()` | `kdf.HKDFSHA256()`
`kdf.HKDFSHA256Extract()`
`kdf.HKDFSHA256Expand()` | Max length 255 × 32B (RFC 5869) | [RFC 5869](https://www.rfc-editor.org/rfc/rfc5869.html) |
-| HKDF (generic hash) | `kdf.NewHKDF(func() hash.Hash)` | `kdf.HKDF()`
`kdf.HKDFExtractWith()`
`kdf.HKDFExpandWith()` | Length bound = 255 × hash.Size() | [RFC 5869](https://www.rfc-editor.org/rfc/rfc5869.html) |
-| HKDF-BLAKE2b | `kdf.NewHKDFBlake2b()` | `kdf.HKDFBlake2b()` | 64B digest variant | [RFC 5869](https://www.rfc-editor.org/rfc/rfc5869.html) |
-| PBKDF2-SHA1 | `kdf.NewPBKDF2SHA1()` | `kdf.PBKDF2SHA1()`
`kdf.PBKDF2SHA1Into()` | See `kdf.CheckParams` for policy checks | [RFC 8018](https://www.rfc-editor.org/rfc/rfc8018.html) |
-| PBKDF2-SHA256 | `kdf.NewPBKDF2SHA256()` | `kdf.PBKDF2SHA256()`
`kdf.PBKDF2SHA256Into()` | Iterations > 0; variable output length | [RFC 8018](https://www.rfc-editor.org/rfc/rfc8018.html) |
-| Argon2id | `kdf.NewArgon2id()`
`kdf.NewArgon2idWithParams()` | `kdf.Argon2id()` | RFC 9106 Argon2id; defaults to time=1, memory=64MiB, lanes=1 | [RFC 9106](https://www.rfc-editor.org/rfc/rfc9106.html) |
-| scrypt | `kdf.NewScrypt(n, r, p)` | `kdf.Scrypt()` | RFC 7914 constraints on n,r,p; variable output length | [RFC 7914](https://www.rfc-editor.org/rfc/rfc7914.html) |
-
-### MAC (Message authentication code)
-
-| Algorithm | Entry points | Key | Tag | Notes | RFC / Spec |
-|-------------|-------------------------------------------------------------------------|----------------|-----|-------------------------------------|---------------------------------------------------------|
-| HMAC-SHA256 | `mac.Sum(key, data)`
`mac.Verify(key, data, tag)` | Any length | 32B | Single-shot helpers over SHA-256 | [RFC 2104](https://www.rfc-editor.org/rfc/rfc2104.html) |
-| Poly1305 | `mac.NewPoly1305(key)`
`mac.SumPoly1305()`
`mac.VerifyPoly1305()` | 32B (one-time) | 16B | One-time key per message (RFC 7539) | [RFC 7539](https://www.rfc-editor.org/rfc/rfc7539.html) |
-
-### Stream ciphers
-
-`stream.NewChaCha20` and `stream.NewXChaCha20` expose the shared `stream.Stream` interface (with `Reset`, `KeyStream`,
-and `XORKeyStream`) so applications can swap keystream generators without touching call sites.
-
-| Algorithm | Constructor | Key | Nonce | Notes | RFC / Spec |
-|-----------|-------------------------|-----------|-------|------------------------------------------------|---------------------------------------------------------------------------|
-| AES-CTR | `stream.NewAESCTR()` | 16/24/32B | 12B | 96-bit nonce with 32-bit counter (NIST layout) | [NIST SP 800-38A](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf) |
-| ChaCha20 | `stream.NewChaCha20()` | 32B | 12B | IETF variant with configurable counter | [RFC 8439](https://www.rfc-editor.org/rfc/rfc8439.html) |
-| XChaCha20 | `stream.NewXChaCha20()` | 32B | 24B | HChaCha20-derived subkeys and raw keystream | [draft-irtf-cfrg-xchacha-03](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha-03) |
-
-
-### Block ciphers
-
-Block primitives are instantiated through `block.NewAES128` / `block.NewAES256`, both returning the shared
-`block.Cipher` interface.
-
-| Algorithm | Constructor | Key | Block | Notes | RFC / Spec |
-|-----------|---------------------|-----|-------|------------------------------|----------------------------------------------------------------------|
-| AES-128 | `block.NewAES128()` | 16B | 16B | Thin wrapper over stdlib AES | [FIPS 197](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf) |
-| AES-256 | `block.NewAES256()` | 32B | 16B | Thin wrapper over stdlib AES | [FIPS 197](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf) |
-
-### Signatures (ECDSA, EdDSA)
-
-| Algorithm | Constructor(s) | Public | Private | Signature | Notes | RFC / Spec |
-|-------------|----------------------|--------------------|------------|----------------------|---------------------------------------------------------------------------------|--------------------------------------------------------------------------|
-| Ed25519 | `sig.NewEd25519()` | 32B | 64B | 64B | Deterministic; `sig.FromSeed(32B)` supported | [RFC 8032](https://www.rfc-editor.org/rfc/rfc8032.html) |
-| ECDSA P-256 | `sig.NewECDSAP256()` | 65B (uncompressed) | 32B scalar | ASN.1 DER (variable) | Helpers: `sig.GenerateKeyECDSAP256`, `sig.SignECDSAP256`, `sig.VerifyECDSAP256` | [FIPS 186-5](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf) |
-
-Ed25519 builds directly on Go's standard library implementation (`crypto/ed25519`) and re-exports the canonical buffer
-sizes via `sig.PublicKeySize`, `sig.PrivateKeySize`, `sig.SeedSize`, and `sig.SignatureSize`. The package also provides
-an alias for `ed25519.Options` together with helpers that cover all RFC 8032 variants:
-
-- `sig.SignWithOptions(priv, msg, opts)` – supports standard, context-bound, and pre-hash signing through the stdlib's
- `ed25519.PrivateKey.Sign` API.
-- `sig.VerifyWithOptions(pub, msg, sig, opts)` – validates inputs, defaults to RFC 8032 parameters, and dispatches to
- `crypto/ed25519.VerifyWithOptions`.
-
-These additions allow advanced Ed25519 flows without reimplementing the algorithm or importing `crypto/ed25519` at call
-sites.
-
-| Algorithm | Constructor | Public | Private | Shared | Notes | RFC / Spec |
-|-----------|------------------|--------------------|------------|--------|-----------------------------------------|--------------------------------------------------------------------------|
-| X25519 | `ecdh.NewX25519()` | 32B | 32B | 32B | RFC 7748 (crypto/ecdh) | [RFC 7748](https://www.rfc-editor.org/rfc/rfc7748.html) |
-| P-256 | `ecdh.NewP256()` | 65B (uncompressed) | 32B scalar | 32B | Uncompressed public: 0x04 \|\| X \|\| Y | [FIPS 186-5](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf) |
-| P-384 | `ecdh.NewP384()` | 97B (uncompressed) | 48B scalar | 48B | Uncompressed public: 0x04 \|\| X \|\| Y | [FIPS 186-5](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf) |
-
-### Post-quantum key encapsulation
-
-The `kem` package defines a shared `kem.KEM` interface together with a deployable
-hybrid construction:
-
-* `kem.New()` - classical KEM adapter built on top of the existing
- `ecdh` helpers (deployable today, pure Go, stdlib only). The adapter lives in
- the `kem` package to highlight that it provides classical security and can be
- reused by non-PQ code paths.
-* `pq.NewHybridX25519()` - versioned hybrid format that composes the X25519
- exchange with an optional ML-KEM component. Callers can inject a vetted ML-KEM
- implementation via `pq.NewHybrid(classical, mlkem)` without changing encoded
- formats or downstream APIs.
+## Supported Algorithms
-Key material and ciphertexts produced by the hybrid construction are encoded as
-`version || len(classical) || classical || len(pq) || pq`, providing forwards
-compatibility when the PQ component is introduced.
-
-To encrypt payloads, the package also includes the convenience `pq.Seal` and
-`pq.Open` helpers which perform the standard `KEM → HKDF → AEAD` flow. The
-envelope format embeds the encapsulated key (length-prefixed), a key-schedule
-identifier, and the AEAD ciphertext so that the receiver can deterministically
-reproduce the derived key/nonce pair. The key schedule currently covers modern
-AEADs such as ChaCha20-Poly1305, AES-256-GCM, AES-GCM-SIV, XChaCha20-Poly1305,
-ASCON-128a, Deoxys-II-256-128, and the AES-SIV family.
+### AEAD (Authenticated Encryption)
+- **Mainstream**: AES-GCM, ChaCha20-Poly1305, XChaCha20-Poly1305, AES-GCM-SIV
+- **Lightweight**: ASCON-128a/80pq ⭐ (NIST winner), Xoodyak, GIFT-COFB, SKINNY, Deoxys-II
+- **Nonce-misuse resistant**: AES-SIV, AES-GCM-SIV
+### Hashing & XOF
+- **Fast**: BLAKE2b/s (742 MB/s), SHA-3 family
+- **Streaming**: SHAKE128/256, BLAKE2 XOF, Xoodyak
+- **Specialized**: TupleHash, ParallelHash (SP 800-185)
+
+### Key Derivation (KDF)
+- **Modern**: HKDF-SHA256/BLAKE2b, Argon2id, scrypt
+- **Password**: PBKDF2-SHA1/SHA256
+
+### MAC & Stream Ciphers
+- **MAC**: HMAC-SHA256, Poly1305 (3+ GB/s)
+- **Stream**: ChaCha20, XChaCha20, AES-CTR
+
+### Public Key Crypto
+- **Signatures**: Ed25519, ECDSA P-256
+- **Key Exchange**: X25519, ECDH P-256/P-384
+- **Post-Quantum**: Hybrid X25519+ML-KEM ready (via `pq` package)
+
+
+📋 Full algorithm matrix with specs
+
+See [docs/ALGORITHMS.md](docs/ALGORITHMS.md) for:
+- Complete key/nonce/tag sizes
+- RFC/FIPS references
+- Interoperability notes
+- Test vectors
+
+
## API
Common interface in `aead/aead.go`:
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..146b7bc
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,22 @@
+# Security Policy
+
+## Supported Versions
+
+| Version | Supported |
+| ------- | ------------------ |
+| main | :white_check_mark: |
+
+## Reporting a Vulnerability
+
+**DO NOT open public issues for security vulnerabilities.**
+
+Email: [your-email] or use GitHub's private vulnerability reporting.
+
+We aim to respond within 48 hours.
+
+## Known Limitations
+
+- No independent security audit conducted
+- Constant-time guarantees: best-effort (review before deploying in side-channel sensitive environments)
+- Caller responsible for nonce uniqueness and key zeroization
+
diff --git a/docs/ALGORITHMS.md b/docs/ALGORITHMS.md
new file mode 100644
index 0000000..ee5241c
--- /dev/null
+++ b/docs/ALGORITHMS.md
@@ -0,0 +1,140 @@
+# Algorithm Reference
+
+This document captures the complete algorithm matrix for Cryptonite-go. It mirrors the tables previously hosted in
+`README.md` and includes key sizes, nonce formats, tags, and primary specification references.
+
+## AEAD
+
+| Algorithm | Constructor(s) | Key | Nonce | Tag | Notes | RFC / Spec |
+|--------------------|------------------------------------------------|-----------|---------------------|-----|-----------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|
+| ASCON-128a | `aead.NewAscon128()` | 16B | 16B | 16B | NIST LwC winner | [FIPS 208](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.208.pdf) |
+| ASCON-80pq | `aead.NewAscon80pq()` | 20B | 16B | 16B | PQ-hardened variant | [FIPS 208](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.208.pdf) |
+| GIFT-COFB | `aead.NewGiftCofb()` | 16B | 16B | 16B | Ultra-lightweight finalist | [IACR 2018/803](https://eprint.iacr.org/2018/803.pdf) |
+| SKINNY-AEAD-M1 | `aead.NewSkinnyAead()` | 16B | 16B | 16B | Tweakable block-cipher AEAD (128-bit tag) | [NIST LwC Round 1 submission](https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/round-1/submissions/SKINNY.pdf) |
+| Xoodyak-Encrypt | `aead.NewXoodyak()` | 16B | 16B | 16B | Cyclist mode | [Xoodyak specification](https://keccak.team/files/Xoodyak-specification.pdf) |
+| ChaCha20-Poly1305 | `aead.NewChaCha20Poly1305()` | 32B | 12B | 16B | RFC 8439 layout | [RFC 8439](https://www.rfc-editor.org/rfc/rfc8439.html) |
+| XChaCha20-Poly1305 | `aead.NewXChaCha20Poly1305()` | 32B | 24B | 16B | Derives nonce via HChaCha20 | [draft-irtf-cfrg-xchacha-03](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha-03) |
+| AES-GCM | `aead.NewAESGCM()` | 16/24/32B | 12B | 16B | AES-NI optional | [NIST SP 800-38D](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf) |
+| AES-GCM-SIV | `aead.NewAesGcmSiv()` | 16/32B | 12B | 16B | Nonce misuse resistant | [RFC 8452](https://www.rfc-editor.org/rfc/rfc8452.html) |
+| AES-SIV (128/256) | `aead.NewAES128SIV()`
`aead.NewAES256SIV()` | 32B / 64B | Deterministic (AAD) | 16B | Deterministic SIV construction; optional multi-AD support via `aead.MultiAssociatedData` | [RFC 5297](https://www.rfc-editor.org/rfc/rfc5297.html) |
+| Deoxys-II-256-128 | `aead.NewDeoxysII128()` | 32B | 15B | 16B | NIST LwC finalist | [NIST LWC finalist spec](https://csrc.nist.gov/csrc/media/Projects/lightweight-cryptography/documents/finalists/deoxys-spec-final.pdf) |
+
+## Hashing
+
+Every hashing entry point lives under the `hash` package so callers can rely on the uniform `hash.Hasher` interface or
+the Go `hash.Hash` type without importing algorithm-specific subpackages.
+
+| Algorithm | Streaming constructor | Single-shot helper(s) | Notes | RFC / Spec |
+|--------------|--------------------------------------------------|-------------------------------------------------|-------------------------------------------------|------------------------------------------------------------------------------|
+| SHA3-224 | `hash.NewSHA3224()` | `hash.NewSHA3224Hasher()` / `hash.Sum224` | 224-bit (28B) digest | [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) |
+| SHA3-256 | `hash.NewSHA3256()` | `hash.NewSHA3256Hasher()` / `hash.Sum256` | 256-bit (32B) digest | [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) |
+| SHA3-384 | `hash.NewSHA3384()` | `hash.NewSHA3384Hasher()` / `hash.Sum384` | 384-bit (48B) digest | [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) |
+| SHA3-512 | `hash.NewSHA3512()` | `hash.NewSHA3512Hasher()` / `hash.Sum512` | 512-bit (64B) digest | [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) |
+| BLAKE2b | `hash.NewBlake2b()` / `hash.NewBlake2bBuilder()` | `hash.NewBlake2bHasher()` | Configurable 1–64B digest, optional keyed MAC mode | [RFC 7693](https://www.rfc-editor.org/rfc/rfc7693.html) |
+| BLAKE2s | `hash.NewBlake2s()` / `hash.NewBlake2sBuilder()` | `hash.NewBlake2sHasher()` | Configurable 1–32B digest, optional keyed MAC mode | [RFC 7693](https://www.rfc-editor.org/rfc/rfc7693.html) |
+| Xoodyak Hash | `hash.NewXoodyak()` | `hash.NewXoodyakHasher()` / `hash.SumXoodyak()` | 32B Cyclist hash | [Xoodyak specification](https://keccak.team/files/Xoodyak-specification.pdf) |
+
+### SP 800-185 constructions
+
+| Algorithm | Helper(s) | Notes | RFC / Spec |
+|-----------------------|----------------------------------------------------------------------------------------|---------------------------------------------------|----------------------------------------------------------------------------------------------|
+| TupleHash128 / 256 | `hash.TupleHash128(tuple, outLen, customization)` / `hash.TupleHash256` | Tuple of byte-strings, optional customization | [NIST SP 800-185](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf) |
+| ParallelHash128 / 256 | `hash.ParallelHash128(msg, blockSize, outLen, customization)` / `hash.ParallelHash256` | Parallel-friendly hashing for large messages | [NIST SP 800-185](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf) |
+
+## XOF (Extendable-output function)
+
+Constructors live under the dedicated `xof` package and return the shared `xof.XOF` interface so extendable-output
+primitives can be swapped transparently.
+
+| Algorithm | Constructor | Notes | RFC / Spec |
+|-------------|------------------|--------------------------------------------|-------------------------------------------------|
+| SHAKE128 | `xof.NewShake128()` | 256-bit security level; arbitrary output length | [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) |
+| SHAKE256 | `xof.NewShake256()` | 512-bit security level; arbitrary output length | [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) |
+| BLAKE2XOF | `xof.NewBlake2XOF()` | BLAKE2b-based extendable-output mode | [RFC 7693](https://www.rfc-editor.org/rfc/rfc7693.html) |
+| Xoodyak XOF | `xof.NewXoodyakXOF()` | Cyclist XOF variant | [Xoodyak specification](https://keccak.team/files/Xoodyak-specification.pdf) |
+
+## Key Derivation (KDF)
+
+| Algorithm | Constructor / Helper(s) | Notes | RFC / Spec |
+|-----------|--------------------------------------------------------------|--------------------------------------------------------------|-----------------------------------------------------------------------------|
+| HKDF | `kdf.NewHKDF(sha256)` / `kdf.NewHKDF(blake2b)` | Modern extract-and-expand with pluggable hash | [RFC 5869](https://www.rfc-editor.org/rfc/rfc5869.html) |
+| Argon2id | `kdf.Argon2id(params)` | Memory-hard password hashing | [RFC 9106](https://www.rfc-editor.org/rfc/rfc9106.html) |
+| scrypt | `kdf.Scrypt(params)` | Memory-hard password hashing | [RFC 7914](https://www.rfc-editor.org/rfc/rfc7914.html) |
+| PBKDF2 | `kdf.PBKDF2(password, salt, iter, keyLen, hashFunc)` | Password-based KDF with SHA-1 / SHA-256 | [PKCS #5 v2.1](https://www.rfc-editor.org/rfc/rfc8018.html) |
+
+## MAC
+
+| Algorithm | Helper(s) | Key | Tag | Notes | RFC / Spec |
+|-------------|---------------------------------------------------------------------|------------|-----|------------------------------------------------|--------------------------------------------------|
+| HMAC-SHA256 | `mac.Sum(key, data)`
`mac.Verify(key, data, tag)` | Any length | 32B | Single-shot helpers over SHA-256 | [RFC 2104](https://www.rfc-editor.org/rfc/rfc2104.html) |
+| Poly1305 | `mac.NewPoly1305(key)`
`mac.SumPoly1305()`
`mac.VerifyPoly1305()` | 32B (one-time) | 16B | One-time key per message (RFC 7539) | [RFC 7539](https://www.rfc-editor.org/rfc/rfc7539.html) |
+
+## Stream ciphers
+
+`stream.NewChaCha20` and `stream.NewXChaCha20` expose the shared `stream.Stream` interface (with `Reset`, `KeyStream`,
+and `XORKeyStream`) so applications can swap keystream generators without touching call sites.
+
+| Algorithm | Constructor | Key | Nonce | Notes | RFC / Spec |
+|-----------|-------------------------|-----------|-------|------------------------------------------------|----------------------------------------------------------------------------------------|
+| AES-CTR | `stream.NewAESCTR()` | 16/24/32B | 12B | 96-bit nonce with 32-bit counter (NIST layout) | [NIST SP 800-38A](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf) |
+| ChaCha20 | `stream.NewChaCha20()` | 32B | 12B | IETF variant with configurable counter | [RFC 8439](https://www.rfc-editor.org/rfc/rfc8439.html) |
+| XChaCha20 | `stream.NewXChaCha20()` | 32B | 24B | HChaCha20-derived subkeys and raw keystream | [draft-irtf-cfrg-xchacha-03](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha-03) |
+
+## Block ciphers
+
+Block primitives are instantiated through `block.NewAES128` / `block.NewAES256`, both returning the shared
+`block.Cipher` interface.
+
+| Algorithm | Constructor | Key | Block | Notes | RFC / Spec |
+|-----------|---------------------|-----|-------|------------------------------|--------------------------------------------------|
+| AES-128 | `block.NewAES128()` | 16B | 16B | Thin wrapper over stdlib AES | [FIPS 197](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf) |
+| AES-256 | `block.NewAES256()` | 32B | 16B | Thin wrapper over stdlib AES | [FIPS 197](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf) |
+
+## Signatures
+
+| Algorithm | Constructor(s) | Public | Private | Signature | Notes | RFC / Spec |
+|-------------|----------------------|--------------------|------------|----------------------|------------------------------------------------------|--------------------------------------------------------------------------|
+| Ed25519 | `sig.NewEd25519()` | 32B | 64B | 64B | Deterministic; `sig.FromSeed(32B)` supported | [RFC 8032](https://www.rfc-editor.org/rfc/rfc8032.html) |
+| ECDSA P-256 | `sig.NewECDSAP256()` | 65B (uncompressed) | 32B scalar | ASN.1 DER (variable) | Helpers: `sig.GenerateKeyECDSAP256`, `sig.SignECDSAP256`, `sig.VerifyECDSAP256` | [FIPS 186-5](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf) |
+
+Ed25519 builds directly on Go's standard library implementation (`crypto/ed25519`) and re-exports the canonical buffer
+sizes via `sig.PublicKeySize`, `sig.PrivateKeySize`, `sig.SeedSize`, and `sig.SignatureSize`. The package also provides
+an alias for `ed25519.Options` together with helpers that cover all RFC 8032 variants:
+
+- `sig.SignWithOptions(priv, msg, opts)` – supports standard, context-bound, and pre-hash signing through the stdlib's
+ `ed25519.PrivateKey.Sign` API.
+- `sig.VerifyWithOptions(pub, msg, sig, opts)` – validates inputs, defaults to RFC 8032 parameters, and dispatches to
+ `crypto/ed25519.VerifyWithOptions`.
+
+These additions allow advanced Ed25519 flows without reimplementing the algorithm or importing `crypto/ed25519` at call
+sites.
+
+## Key Exchange (ECDH)
+
+| Algorithm | Constructor | Public | Private | Shared | Notes | RFC / Spec |
+|-----------|------------------|--------------------|------------|--------|-----------------------------------------|--------------------------------------------------------------------------|
+| X25519 | `ecdh.NewX25519()` | 32B | 32B | 32B | RFC 7748 (crypto/ecdh) | [RFC 7748](https://www.rfc-editor.org/rfc/rfc7748.html) |
+| P-256 | `ecdh.NewP256()` | 65B (uncompressed) | 32B scalar | 32B | Uncompressed public: 0x04 || X || Y | [FIPS 186-5](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf) |
+| P-384 | `ecdh.NewP384()` | 97B (uncompressed) | 48B scalar | 48B | Uncompressed public: 0x04 || X || Y | [FIPS 186-5](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf) |
+
+## Post-quantum key encapsulation
+
+The `kem` package defines a shared `kem.KEM` interface together with a deployable hybrid construction:
+
+- `kem.New()` - classical KEM adapter built on top of the existing `ecdh` helpers (deployable today, pure Go, stdlib only).
+ The adapter lives in the `kem` package to highlight that it provides classical security and can be reused by non-PQ
+ code paths.
+- `pq.NewHybridX25519()` - versioned hybrid format that composes the X25519 exchange with an optional ML-KEM component.
+ Callers can inject a vetted ML-KEM implementation via `pq.NewHybrid(classical, mlkem)` without changing encoded
+ formats or downstream APIs.
+
+Key material and ciphertexts produced by the hybrid construction are encoded as
+`version || len(classical) || classical || len(pq) || pq`, providing forwards compatibility when the PQ component is
+introduced.
+
+To encrypt payloads, the package also includes the convenience `pq.Seal` and `pq.Open` helpers which perform the
+standard `KEM → HKDF → AEAD` flow. The envelope format embeds the encapsulated key (length-prefixed), a key-schedule
+identifier, and the AEAD ciphertext so that the receiver can deterministically reproduce the derived key/nonce pair. The
+key schedule currently covers modern AEADs such as ChaCha20-Poly1305, AES-256-GCM, AES-GCM-SIV, XChaCha20-Poly1305,
+ASCON-128a, Deoxys-II-256-128, and the AES-SIV family.
+
diff --git a/docs/HPKE.md b/docs/HPKE.md
new file mode 100644
index 0000000..30322f3
--- /dev/null
+++ b/docs/HPKE.md
@@ -0,0 +1,39 @@
+# Hybrid Public Key Encryption (HPKE)
+
+Cryptonite-go implements RFC 9180 Hybrid Public Key Encryption (HPKE) in the `hpke` package. This document explains the
+available modes, suite configuration, and integration guidance.
+
+## Supported Modes and Suites
+
+- **Base mode (mode 0)** is fully supported. Auth, PSK, and AuthPSK modes share the same API surface and are reachable by
+ supplying the appropriate options structures.
+- Predefined ciphersuite helpers mirror RFC 9180 labels:
+ - `hpke.SuiteX25519ChaCha20` → KEM: DHKEM(X25519, HKDF-SHA256), KDF: HKDF-SHA256, AEAD: ChaCha20-Poly1305.
+ - `hpke.SuiteX25519AESGCM` → KEM: DHKEM(X25519, HKDF-SHA256), KDF: HKDF-SHA256, AEAD: AES-256-GCM.
+ - `hpke.SuiteP256ChaCha20` → KEM: DHKEM(P-256, HKDF-SHA256), KDF: HKDF-SHA256, AEAD: ChaCha20-Poly1305.
+
+Callers can construct custom suites via `hpke.NewSuite(kemID, kdfID, aeadID)` which validates identifiers against the
+registry.
+
+## Usage Pattern
+
+1. **Setup** – The sender creates a context with `suite.SetupBaseSender(publicKey, info)` which returns the encapsulated
+ key (`enc`) and a `Context` instance. The receiver calls `suite.SetupBaseReceiver(enc, privateKey, info)`.
+2. **Seal/Open** – Use `ctx.Seal(nonce, aad, pt)` and `ctx.Open(nonce, aad, ct)` to protect data. Nonces are 96-bit values
+ that increment per message.
+3. **Export** – Derive exporter secrets via `ctx.Export(secret, length)` for key schedule chaining.
+
+## Deterministic Nonces
+
+HPKE leaves nonce generation to the application. Combine the exporter interface with the HKDF-based helpers in
+`secret.NewDeterministicNonce` to derive deterministic nonces that are bound to the encapsulated key and associated data.
+
+## Integration with `pq`
+
+The `pq` package wraps HPKE contexts to produce hybrid envelopes that mix classical and post-quantum KEMs. The flow is:
+
+1. Call `pq.NewHybrid(classicalKEM, mlkem)` to construct the hybrid encapsulation object.
+2. Use `pq.Seal` / `pq.Open` to perform HPKE-based key establishment with AEAD payload encryption.
+3. The resulting format encodes HPKE metadata, AEAD identifiers, and ciphertext to ensure deterministic re-derivation of
+ keys during decryption.
+
diff --git a/docs/INTEROP.md b/docs/INTEROP.md
new file mode 100644
index 0000000..d2c924d
--- /dev/null
+++ b/docs/INTEROP.md
@@ -0,0 +1,56 @@
+# Interoperability Guide
+
+Cryptonite-go aims to interoperate with existing cryptography stacks. This guide documents wire formats, encoding rules,
+and compatibility notes.
+
+## AEAD Payloads
+
+- **Ciphertext layout** – All AEAD encryptors return `ciphertext || tag`. For streaming AEADs, tags are always appended to
+ the end of the slice.
+- **Associated Data** – Provided associated data is not included in the ciphertext and must be supplied verbatim during
+ decryption.
+- **Nonce encoding** – Callers are responsible for storing nonces alongside ciphertext. Use big-endian encoding when
+ serializing counters.
+
+## Signature Encodings
+
+- **Ed25519** – Signatures are 64-byte raw buffers. Public keys are 32-byte little-endian values as defined in RFC 8032.
+- **ECDSA P-256** – Public keys default to uncompressed SEC1 format (`0x04 || X || Y`). Signatures follow ASN.1 DER.
+
+## ECDH Keys
+
+- `ecdh.NewX25519` expects 32-byte private keys and outputs 32-byte Montgomery u-coordinates. Use the standard base point
+ defined in RFC 7748.
+- `ecdh.NewP256` / `NewP384` accept scalar private keys and return uncompressed SEC1 public points.
+
+## HPKE Records
+
+- HPKE `enc` values are written exactly as produced by the underlying KEM (32 bytes for X25519, 65 for P-256).
+- Ciphertexts include a 96-bit nonce supplied by the caller, AEAD ciphertext, and tag. Persist the nonce to decrypt.
+
+## PQ Hybrid Envelopes
+
+Hybrid envelopes emitted by `pq.Seal` are length-prefixed structures:
+
+```
+version (1 byte)
+classical_ct_len (2 bytes, big-endian)
+classical_ct (variable)
+pq_ct_len (2 bytes, big-endian)
+pq_ct (variable)
+aead_id (1 byte)
+nonce (len depends on AEAD)
+ciphertext (variable)
+tag (16 bytes typical)
+```
+
+Decoders must validate lengths before slicing the input to prevent panics. Unknown `version` values should trigger a
+feature negotiation or graceful failure.
+
+## Hashing and KDFs
+
+- Hash functions follow the same digest outputs as Go's standard library implementations, so interoperability is
+ straightforward.
+- HKDF uses little-endian uint16 labels when deriving AEAD keys for the hybrid envelope format, matching the docs in
+ `pq`.
+
diff --git a/docs/NONCE_MANAGEMENT.md b/docs/NONCE_MANAGEMENT.md
new file mode 100644
index 0000000..b352e52
--- /dev/null
+++ b/docs/NONCE_MANAGEMENT.md
@@ -0,0 +1,58 @@
+# Nonce and Counter Management
+
+Cryptonite-go offers both deterministic SIV constructions and classic nonce-based AEADs. Correctly managing nonces and
+counters is critical for security; this guide summarizes best practices across the library.
+
+## General Guidelines
+
+- **Uniqueness is mandatory**: For nonce-based AEADs (AES-GCM, ChaCha20-Poly1305, ASCON, etc.) never reuse a nonce with
+the same key. Reuse undermines confidentiality and integrity.
+- **Leverage `secret.Nonce` helpers**: The `secret` package exposes reference types for random nonces and monotonic
+ counters. Use them to reduce mistakes and enable zeroization via `Destroy()`.
+- **Avoid truncating randomness**: When generating nonces, use the exact byte length required by the algorithm. Trimming
+ randomness to a smaller size introduces collisions.
+- **Secure storage**: Persist counters alongside encrypted data so you can resume sequences safely after restarts.
+- **Parallelization**: When encrypting in parallel, partition the nonce space (e.g., prefix worker ID bits) or derive
+ subkeys with HKDF so each worker owns an independent key/nonce pair.
+
+## AEAD-specific Recommendations
+
+### ChaCha20-Poly1305 and AES-GCM
+
+- Use 96-bit nonces (`12 bytes`). Compose a deterministic nonce by concatenating a 32-bit big-endian counter with a
+ 64-bit random prefix, or derive nonces via HKDF when using key encapsulation flows (see `pq.Seal`).
+- For AES-GCM counters, ensure the low 32 bits increment monotonically and never wrap. Callers should detect counter
+ exhaustion and rotate keys before the 2³² limit.
+
+### XChaCha20-Poly1305
+
+- Supply a full 192-bit (`24-byte`) nonce. The constructor internally runs HChaCha20 to derive a subkey and 96-bit nonce
+ for ChaCha20, so uniqueness of the 192-bit input is sufficient.
+
+### AES-GCM-SIV and AES-SIV
+
+- These constructions are nonce-misuse resistant but **not** misuse-proof. Repeating nonces will not leak plaintext, yet
+ it still enables replay. Generate high-entropy nonces and include strict associated data for replay detection.
+- When using `aead.MultiAssociatedData`, keep the ordering of pieces consistent between encryption and decryption.
+
+### Lightweight AEADs (ASCON, SKINNY, GIFT-COFB, Xoodyak)
+
+- Follow the same 128-bit nonce uniqueness rules. For microcontrollers, monotonic counters stored in flash are
+ acceptable as long as updates are atomic (use double-buffering or sequence numbers).
+
+## Counter Utilities
+
+The `secret` package provides reusable counter implementations:
+
+- `secret.NewMonotonicCounter(size)` – returns a fixed-width big-endian counter. Use `Increment()` to advance and
+ `Bytes()` to obtain the current value.
+- `secret.NewDeterministicNonce(key, salt, info)` – HKDF-based determinstic nonce derivation that binds context strings
+ to the output.
+- `secret.Zeroize()` – helper to clear sensitive buffers once a nonce or counter leaves scope.
+
+## Zeroization Checklist
+
+1. Destroy nonce/counter structures once completed (`defer nonce.Destroy()`).
+2. Wipe temporary copies of nonces stored in slices or structs.
+3. Guard against double-destruction by setting references to `nil` after zeroization.
+
diff --git a/docs/PQ.md b/docs/PQ.md
new file mode 100644
index 0000000..34f7344
--- /dev/null
+++ b/docs/PQ.md
@@ -0,0 +1,43 @@
+# Post-Quantum Integration
+
+Cryptonite-go approaches post-quantum readiness through hybrid KEM constructions that pair classical elliptic-curve
+schemes with pluggable ML-KEM implementations.
+
+## Hybrid Format Overview
+
+- **Versioning** – Hybrids produced by `pq.NewHybrid` begin with a version byte so new PQ algorithms can be introduced
+ without breaking decoders.
+- **Length prefixes** – Classical and PQ ciphertexts are both length-prefixed, enabling variable-size payloads and simple
+ framing.
+- **Key schedule** – Derived shared secrets feed HKDF (SHA-256) to produce AEAD keys and nonces. The HKDF info string
+ encodes the chosen AEAD to ensure domain separation.
+
+## Classical Component
+
+The default classical KEM is `kem.New()`, which wraps X25519 or P-256 ECDH and exposes the shared `kem.KEM` interface.
+Callers can substitute their own classical implementation if they match the same interface (GenerateKey, Encapsulate,
+Decapsulate).
+
+## ML-KEM Component
+
+To integrate ML-KEM (Kyber/ML-KEM 512/768/1024):
+
+1. Import or implement a Go type satisfying `kem.KEM` for the desired ML-KEM parameter set.
+2. Pass it to `pq.NewHybrid(classical, mlkem)`.
+3. Ensure the ML-KEM public key, secret key, and ciphertext encodings follow the draft FIPS 203 byte layouts.
+
+## Envelope Helpers
+
+`pq.Seal` and `pq.Open` provide a turnkey envelope construction:
+
+- The sender encapsulates via both classical and PQ components, concatenates the ciphertexts, and derives AEAD keys.
+- The receiver decapsulates each component independently and recombines secrets. If the PQ side fails, implementations
+ should treat the message as invalid even if the classical component succeeds.
+
+## Key Management Tips
+
+- **Rotate keys** regularly: publish new hybrid public keys once PQ implementations are updated.
+- **Secure storage**: Store ML-KEM secret keys with strong access controls; they are typically larger than classical keys.
+- **Fallbacks**: If the PQ component is unavailable, degrade gracefully by using the classical KEM only, but log the event
+ so operators are aware of reduced security.
+
diff --git a/docs/TESTING.md b/docs/TESTING.md
new file mode 100644
index 0000000..01f133a
--- /dev/null
+++ b/docs/TESTING.md
@@ -0,0 +1,38 @@
+# Testing Guidance
+
+Cryptonite-go relies heavily on deterministic Known Answer Tests (KATs), fuzzing harnesses, and regression suites. This
+document covers how to extend the testing matrix when adding new primitives.
+
+## Running the Test Suite
+
+```bash
+go test ./...
+go test ./test/...
+go test -race ./...
+```
+
+Run these commands before submitting pull requests. Include `-bench` benchmarks when performance regressions are a
+concern.
+
+## Adding KAT Vectors
+
+1. Place vector files under the relevant package's `testdata/` directory or the shared `test/` folder.
+2. Use JSON or the existing delimiter-separated formats for consistency.
+3. Document the vector source (RFC, NIST, academic paper) in a comment within the test file.
+4. Ensure tests cover both valid and invalid cases (e.g., tag tampering, nonce misuse).
+
+## Fuzzing
+
+- Leverage Go's built-in fuzzing (`go test -fuzz=Fuzz*`) for stateful primitives.
+- Fuzz targets live under `test/fuzz/`. If you add a new fuzz target, include seed corpus files to accelerate discovery.
+
+## Benchmarks
+
+- Benchmarks reside in `test/benchmark_*.go` or package-level `_test.go` files.
+- Include throughput numbers for new primitives and compare them against baseline implementations.
+
+## Continuous Integration Expectations
+
+- Pull requests should run `go fmt ./...`, `go vet ./...`, and `golangci-lint run` locally before submission.
+- Keep benchmark output in PR descriptions when performance optimizations are proposed.
+