Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,199 @@
# @suaveplan/crypto-core - Universal cryptographic primitives (formerly @suaveplan/crypto) — AEAD (AES-256-GCM, ChaCha20-Poly1305, XChaCha20-Poly1305), Ed25519 / X25519 / ECDSA-P256, sealed-box, auth-box, constant-time compare, zeroize. Engine-pluggable via noble defaults. Consumed by @suaveplan/crypto (the opinionated keychain/vault/packer layer); other packages must go through @suaveplan/crypto, not this package directly.
## Summary
Universal cryptographic primitives — engine-pluggable AEAD, Ed25519/ECDSA-P256 signing, X25519 key agreement, sealed-box, and auth-box. Built on audited [@noble/*](https://paulmillr.com/noble/) libraries with zero WASM.
<!-- begin:auto-docs -->
## Documentation tree
- [aead](./src/aead/aead.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->- noble-aead-engine — <!-- begin:auto-docs --> _(no su…
- [noble-aead-engine](./src/aead/noble-aead-engine/noble-aead-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [noble-aead-engine](./src/aead/noble-aead-engine/noble-aead-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [aead](./src/aead/aead.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->- noble-aead-engine — <!-- begin:auto-docs --> _(no su…
- [noble-agree-engine](./src/agree/noble-agree-engine/noble-agree-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [noble-agree-engine](./src/agree/noble-agree-engine/noble-agree-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [x25519](./src/agree/x25519/x25519.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [x25519](./src/agree/x25519/x25519.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [auth-box](./src/auth-box/auth-box.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->- noble-auth-box-engine — <!-- begin:auto-docs --> _(n…
- [noble-auth-box-engine](./src/auth-box/noble-auth-box-engine/noble-auth-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [noble-auth-box-engine](./src/auth-box/noble-auth-box-engine/noble-auth-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [auth-box](./src/auth-box/auth-box.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->- noble-auth-box-engine — <!-- begin:auto-docs --> _(n…
- [codes](./src/errors/codes/codes.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [codes](./src/errors/codes/codes.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [crypto-error](./src/errors/crypto-error/crypto-error.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [crypto-error](./src/errors/crypto-error/crypto-error.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [constant-time-equal](./src/primitives/constant-time-equal/constant-time-equal.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [constant-time-equal](./src/primitives/constant-time-equal/constant-time-equal.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [random-bytes](./src/primitives/random-bytes/random-bytes.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [random-bytes](./src/primitives/random-bytes/random-bytes.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [zeroize](./src/primitives/zeroize/zeroize.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [zeroize](./src/primitives/zeroize/zeroize.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [sealed-box](./src/sealed-box/sealed-box.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->- noble-sealed-box-engine — <!-- begin:auto-docs --> _…
- [noble-sealed-box-engine](./src/sealed-box/noble-sealed-box-engine/noble-sealed-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [noble-sealed-box-engine](./src/sealed-box/noble-sealed-box-engine/noble-sealed-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [sealed-box](./src/sealed-box/sealed-box.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->- noble-sealed-box-engine — <!-- begin:auto-docs --> _…
- [ecdsa-p256](./src/sign/ecdsa-p256/ecdsa-p256.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [ecdsa-p256](./src/sign/ecdsa-p256/ecdsa-p256.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [ed25519](./src/sign/ed25519/ed25519.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [ed25519](./src/sign/ed25519/ed25519.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [noble-sign-engine](./src/sign/noble-sign-engine/noble-sign-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [noble-sign-engine](./src/sign/noble-sign-engine/noble-sign-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
<!-- end:auto-docs --> - [noble-aead-engine](./src/aead/noble-aead-engine/noble-aead-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-aead-engine](./src/aead/noble-aead-engine/noble-aead-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [aead](./src/aead/aead.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-agree-engine](./src/agree/noble-agree-engine/noble-agree-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-agree-engine](./src/agree/noble-agree-engine/noble-agree-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [x25519](./src/agree/x25519/x25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [x25519](./src/agree/x25519/x25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [auth-box](./src/auth-box/auth-box.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-auth-box-engine](./src/auth-box/noble-auth-box-engine/noble-auth-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-auth-box-engine](./src/auth-box/noble-auth-box-engine/noble-auth-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [auth-box](./src/auth-box/auth-box.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [crypto-error](./src/errors/crypto-error/crypto-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [crypto-error](./src/errors/crypto-error/crypto-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [constant-time-equal](./src/primitives/constant-time-equal/constant-time-equal.md) — <!-- begin:auto-docs --> _(no submodules)_- [constant-time-equal](./src/primitives/constant-time-equal/constant-time-equal.md) — <!-- begin:auto-docs --> _(no submodules)_- [random-bytes](./src/primitives/random-bytes/random-bytes.md) — <!-- begin:auto-docs --> _(no submodules)_- [random-bytes](./src/primitives/random-bytes/random-bytes.md) — <!-- begin:auto-docs --> _(no submodules)_- [zeroize](./src/primitives/zeroize/zeroize.md) — <!-- begin:auto-docs --> _(no submodules)_- [zeroize](./src/primitives/zeroize/zeroize.md) — <!-- begin:auto-docs --> _(no submodules)_- [sealed-box](./src/sealed-box/sealed-box.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-sealed-box-engine](./src/sealed-box/noble-sealed-box-engine/noble-sealed-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-sealed-box-engine](./src/sealed-box/noble-sealed-box-engine/noble-sealed-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [sealed-box](./src/sealed-box/sealed-box.md) — <!-- begin:auto-docs --> _(no submodules)_- [ecdsa-p256](./src/sign/ecdsa-p256/ecdsa-p256.md) — <!-- begin:auto-docs --> _(no submodules)_- [ecdsa-p256](./src/sign/ecdsa-p256/ecdsa-p256.md) — <!-- begin:auto-docs --> _(no submodules)_- [ed25519](./src/sign/ed25519/ed25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [ed25519](./src/sign/ed25519/ed25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-sign-engine](./src/sign/noble-sign-engine/noble-sign-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-sign-engine](./src/sign/noble-sign-engine/noble-sign-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- noble-aead-engine — <!-- beg…
- [noble-aead-engine](./src/aead/noble-aead-engine/noble-aead-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-aead-engine](./src/aead/noble-aead-engine/noble-aead-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [aead](./src/aead/aead.md) — <!-- begin:auto-docs --> _(no submodules)_- noble-aead-engine — <!-- beg…
- [noble-agree-engine](./src/agree/noble-agree-engine/noble-agree-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-agree-engine](./src/agree/noble-agree-engine/noble-agree-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [x25519](./src/agree/x25519/x25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [x25519](./src/agree/x25519/x25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [auth-box](./src/auth-box/auth-box.md) — <!-- begin:auto-docs --> _(no submodules)_- noble-auth-box-engine — <!--…
- [noble-auth-box-engine](./src/auth-box/noble-auth-box-engine/noble-auth-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-auth-box-engine](./src/auth-box/noble-auth-box-engine/noble-auth-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [auth-box](./src/auth-box/auth-box.md) — <!-- begin:auto-docs --> _(no submodules)_- noble-auth-box-engine — <!--…
- [codes](./src/errors/codes/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [crypto-error](./src/errors/crypto-error/crypto-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [crypto-error](./src/errors/crypto-error/crypto-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [constant-time-equal](./src/primitives/constant-time-equal/constant-time-equal.md) — <!-- begin:auto-docs --> _(no submodules)_- [constant-time-equal](./src/primitives/constant-time-equal/constant-time-equal.md) — <!-- begin:auto-docs --> _(no submodules)_- [random-bytes](./src/primitives/random-bytes/random-bytes.md) — <!-- begin:auto-docs --> _(no submodules)_- [random-bytes](./src/primitives/random-bytes/random-bytes.md) — <!-- begin:auto-docs --> _(no submodules)_- [zeroize](./src/primitives/zeroize/zeroize.md) — <!-- begin:auto-docs --> _(no submodules)_- [zeroize](./src/primitives/zeroize/zeroize.md) — <!-- begin:auto-docs --> _(no submodules)_- [sealed-box](./src/sealed-box/sealed-box.md) — <!-- begin:auto-docs --> _(no submodules)_- noble-sealed-box-engine — <!…
- [noble-sealed-box-engine](./src/sealed-box/noble-sealed-box-engine/noble-sealed-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-sealed-box-engine](./src/sealed-box/noble-sealed-box-engine/noble-sealed-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [sealed-box](./src/sealed-box/sealed-box.md) — <!-- begin:auto-docs --> _(no submodules)_- noble-sealed-box-engine — <!…
- [ecdsa-p256](./src/sign/ecdsa-p256/ecdsa-p256.md) — <!-- begin:auto-docs --> _(no submodules)_- [ecdsa-p256](./src/sign/ecdsa-p256/ecdsa-p256.md) — <!-- begin:auto-docs --> _(no submodules)_- [ed25519](./src/sign/ed25519/ed25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [ed25519](./src/sign/ed25519/ed25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-sign-engine](./src/sign/noble-sign-engine/noble-sign-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-sign-engine](./src/sign/noble-sign-engine/noble-sign-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- noble-aead-engine — <!-- begin:auto-docs --> _(no s…
- [noble-aead-engine](./src/aead/noble-aead-engine/noble-aead-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-aead-engine](./src/aead/noble-aead-engine/noble-aead-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [aead](./src/aead/aead.md) — <!-- begin:auto-docs --> _(no submodules)_- noble-aead-engine — <!-- begin:auto-docs --> _(no s…
- [noble-agree-engine](./src/agree/noble-agree-engine/noble-agree-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-agree-engine](./src/agree/noble-agree-engine/noble-agree-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [x25519](./src/agree/x25519/x25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [x25519](./src/agree/x25519/x25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [auth-box](./src/auth-box/auth-box.md) — <!-- begin:auto-docs --> _(no submodules)_- noble-auth-box-engine — <!-- begin:auto-docs --> _(…
- [noble-auth-box-engine](./src/auth-box/noble-auth-box-engine/noble-auth-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-auth-box-engine](./src/auth-box/noble-auth-box-engine/noble-auth-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [auth-box](./src/auth-box/auth-box.md) — <!-- begin:auto-docs --> _(no submodules)_- noble-auth-box-engine — <!-- begin:auto-docs --> _(…
- [codes](./src/errors/codes/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [crypto-error](./src/errors/crypto-error/crypto-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [crypto-error](./src/errors/crypto-error/crypto-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [constant-time-equal](./src/primitives/constant-time-equal/constant-time-equal.md) — <!-- begin:auto-docs --> _(no submodules)_- [constant-time-equal](./src/primitives/constant-time-equal/constant-time-equal.md) — <!-- begin:auto-docs --> _(no submodules)_- [random-bytes](./src/primitives/random-bytes/random-bytes.md) — <!-- begin:auto-docs --> _(no submodules)_- [random-bytes](./src/primitives/random-bytes/random-bytes.md) — <!-- begin:auto-docs --> _(no submodules)_- [zeroize](./src/primitives/zeroize/zeroize.md) — <!-- begin:auto-docs --> _(no submodules)_- [zeroize](./src/primitives/zeroize/zeroize.md) — <!-- begin:auto-docs --> _(no submodules)_- [sealed-box](./src/sealed-box/sealed-box.md) — <!-- begin:auto-docs --> _(no submodules)_- noble-sealed-box-engine — <!-- begin:auto-docs -->…
- [noble-sealed-box-engine](./src/sealed-box/noble-sealed-box-engine/noble-sealed-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-sealed-box-engine](./src/sealed-box/noble-sealed-box-engine/noble-sealed-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [sealed-box](./src/sealed-box/sealed-box.md) — <!-- begin:auto-docs --> _(no submodules)_- noble-sealed-box-engine — <!-- begin:auto-docs -->…
- [ecdsa-p256](./src/sign/ecdsa-p256/ecdsa-p256.md) — <!-- begin:auto-docs --> _(no submodules)_- [ecdsa-p256](./src/sign/ecdsa-p256/ecdsa-p256.md) — <!-- begin:auto-docs --> _(no submodules)_- [ed25519](./src/sign/ed25519/ed25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [ed25519](./src/sign/ed25519/ed25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-sign-engine](./src/sign/noble-sign-engine/noble-sign-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-sign-engine](./src/sign/noble-sign-engine/noble-sign-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-aead-engine](./src/aead/noble-aead-engine/noble-aead-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ - [noble-aead-engine](./src/aead/noble-aead-engine/noble-aead-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [aead](./src/aead/aead.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-agree-engine](./src/agree/noble-agree-engine/noble-agree-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ - [noble-agree-engine](./src/agree/noble-agree-engine/noble-agree-engine.md) — <!-- begin:auto-docs --> _(no submodules)_- [x25519](./src/agree/x25519/x25519.md) — <!-- begin:auto-docs --> _(no submodules)_ - [x25519](./src/agree/x25519/x25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [auth-box](./src/auth-box/auth-box.md) — <!-- begin:auto-docs --> _(no submodules)_ - [noble-auth-box-engine](./src/auth-box/noble-auth-box-engine/noble-auth-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ - [noble-auth-box-engine](./src/auth-box/noble-auth-box-engine/noble-auth-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ - [auth-box](./src/auth-box/auth-box.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes/codes.md) — <!-- begin:auto-docs --> _(no submodules)_ - [codes](./src/errors/codes/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [crypto-error](./src/errors/crypto-error/crypto-error.md) — <!-- begin:auto-docs --> _(no submodules)_ - [crypto-error](./src/errors/crypto-error/crypto-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [constant-time-equal](./src/primitives/constant-time-equal/constant-time-equal.md) — <!-- begin:auto-docs --> _(no submodules)_ - [constant-time-equal](./src/primitives/constant-time-equal/constant-time-equal.md) — <!-- begin:auto-docs --> _(no submodules)_- [random-bytes](./src/primitives/random-bytes/random-bytes.md) — <!-- begin:auto-docs --> _(no submodules)_ - [random-bytes](./src/primitives/random-bytes/random-bytes.md) — <!-- begin:auto-docs --> _(no submodules)_- [zeroize](./src/primitives/zeroize/zeroize.md) — <!-- begin:auto-docs --> _(no submodules)_ - [zeroize](./src/primitives/zeroize/zeroize.md) — <!-- begin:auto-docs --> _(no submodules)_- [sealed-box](./src/sealed-box/sealed-box.md) — <!-- begin:auto-docs --> _(no submodules)_ - [noble-sealed-box-engine](./src/sealed-box/noble-sealed-box-engine/noble-sealed-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ - [noble-sealed-box-engine](./src/sealed-box/noble-sealed-box-engine/noble-sealed-box-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ - [sealed-box](./src/sealed-box/sealed-box.md) — <!-- begin:auto-docs --> _(no submodules)_- [ecdsa-p256](./src/sign/ecdsa-p256/ecdsa-p256.md) — <!-- begin:auto-docs --> _(no submodules)_ - [ecdsa-p256](./src/sign/ecdsa-p256/ecdsa-p256.md) — <!-- begin:auto-docs --> _(no submodules)_- [ed25519](./src/sign/ed25519/ed25519.md) — <!-- begin:auto-docs --> _(no submodules)_ - [ed25519](./src/sign/ed25519/ed25519.md) — <!-- begin:auto-docs --> _(no submodules)_- [noble-sign-engine](./src/sign/noble-sign-engine/noble-sign-engine.md) — <!-- begin:auto-docs --> _(no submodules)_ - [noble-sign-engine](./src/sign/noble-sign-engine/noble-sign-engine.md) — <!-- begin:auto-docs --> _(no submodules)_
## Install
```bash
bun add @suaveplan/crypto
```
## Primitives
| Surface | What |
|---|---|
| `randomBytes(n, { byteSource? })` | CSPRNG bytes (WebCrypto default; injectable for tests) |
| `constantTimeEqual(a, b)` | Constant-time byte comparison |
| `zeroize(buf)` | Fill a `Uint8Array` with zeros |
| `aeadEncrypt` / `aeadDecrypt` | AES-256-GCM, ChaCha20-Poly1305, XChaCha20-Poly1305 |
| `ed25519.{generateKeypair, sign, verify}` | Ed25519 signing |
| `ecdsaP256.{generateKeypair, sign, verify}` | ECDSA-P256 signing |
| `x25519.{generateKeypair, agree}` | X25519 ECDH key agreement |
| `sealedBox.{seal, open}` | Anonymous-sender sealed box (X25519 + XChaCha20-Poly1305) |
| `authBox.{seal, open}` | Authenticated box (X25519 + XChaCha20-Poly1305) |
> Hashing (SHA-2, HMAC, HKDF, PBKDF2, Argon2id) lives in [`@suaveplan/crypto-hash`](../hash).
## Engine interfaces
Every operation accepts an optional `{ engine?: <EngineType> }` argument. The default engines use `@noble/ciphers` and `@noble/curves`. Swap in a WebCrypto-backed or libsodium-backed engine without changing call sites.
```ts
import type { AeadEngine } from "@suaveplan/crypto-core/engines";
const webCryptoEngine: AeadEngine = { /* ... */ };
aeadEncrypt("AES-256-GCM", key, plaintext, { nonce }, { engine: webCryptoEngine });
```
## ByteSource
`ByteSource = (n: number) => Uint8Array` — the injected randomness type used for key generation. Replaces the old `Rng` alias (which conflicted with `@suaveplan/types`'s `Rng`).
```ts
import { randomBytes, type ByteSource } from "@suaveplan/crypto-core";
// Production
const key = randomBytes(32);
// Tests — deterministic
const seeded: ByteSource = (n) => new Uint8Array(n).fill(0x42);
const kp = ed25519.generateKeypair({ byteSource: seeded });
```
## AEAD
```ts
import { aeadEncrypt, aeadDecrypt, randomBytes } from "@suaveplan/crypto-core";
const key = randomBytes(32);
const nonce = randomBytes(12); // 12 for AES-GCM/ChaCha20, 24 for XChaCha20
const plaintext = new TextEncoder().encode("hello");
const ct = aeadEncrypt("AES-256-GCM", key, plaintext, { nonce });
const pt = aeadDecrypt("AES-256-GCM", key, ct, { nonce });
```
## Signing
```ts
import { ed25519, ecdsaP256 } from "@suaveplan/crypto-core";
const kp = ed25519.generateKeypair();
const sig = ed25519.sign(kp.secretKey, message);
ed25519.verify(kp.publicKey, sig, message); // true
```
## Key Agreement + Sealed Box
```ts
import { x25519, sealedBox, authBox, randomBytes } from "@suaveplan/crypto-core";
const alice = x25519.generateKeypair();
const bob = x25519.generateKeypair();
// Anonymous sender (sealed box)
const sealed = sealedBox.seal(bob.publicKey, plaintext);
const opened = sealedBox.open(bob.secretKey, bob.publicKey, sealed);
// Authenticated (auth box)
const nonce = randomBytes(24);
const ct = authBox.seal(alice.secretKey, bob.publicKey, plaintext, nonce);
const pt = authBox.open(alice.publicKey, bob.secretKey, ct, nonce);
```
## Error surface
Every failure surfaces as `CryptoError` (extends `SuaveplanError`) with a stable `CRYPTO.*` code. Error context never includes raw key bytes, plaintext, or authentication tags.
| Code | When |
|---|---|
| `CRYPTO.KEY.INVALID_LENGTH` | Key is not 32 bytes |
| `CRYPTO.AEAD.INVALID_NONCE` | Nonce length wrong for algorithm |
| `CRYPTO.AEAD.DECRYPT_FAILED` | Authentication tag mismatch |
| `CRYPTO.SIGN.INVALID_KEY` | Key is malformed |
| `CRYPTO.SIGN.VERIFY_FAILED` | Signature verification failed |
| `CRYPTO.RNG.INVALID_LENGTH` | `randomBytes(n)` called with negative/non-integer n |
| `CRYPTO.RNG.UNAVAILABLE` | No CSPRNG available |
## Subpath exports
```ts
import { randomBytes } from "@suaveplan/crypto-core/primitives/random-bytes";
import { constantTimeEqual } from "@suaveplan/crypto-core/primitives/constant-time-equal";
import { zeroize } from "@suaveplan/crypto-core/primitives/zeroize";
import { aeadEncrypt, aeadDecrypt } from "@suaveplan/crypto-core/aead";
import { ed25519, ecdsaP256 } from "@suaveplan/crypto-core/sign";
import { x25519 } from "@suaveplan/crypto-core/agree";
import { sealedBox } from "@suaveplan/crypto-core/sealed-box";
import { authBox } from "@suaveplan/crypto-core/auth-box";
import type { AeadEngine, SignEngine } from "@suaveplan/crypto-core/engines";
import { CryptoError, CRYPTO_CODES } from "@suaveplan/crypto-core/errors";
```
## Co-located docs
- [`src/primitives/random-bytes.md`](src/primitives/random-bytes.md)
- [`src/primitives/constant-time-equal.md`](src/primitives/constant-time-equal.md)
- [`src/primitives/zeroize.md`](src/primitives/zeroize.md)
- [`src/aead/aead.md`](src/aead/aead.md)
- [`src/sign/ed25519.md`](src/sign/ed25519.md)
- [`src/sign/ecdsa-p256.md`](src/sign/ecdsa-p256.md)
- [`src/agree/x25519.md`](src/agree/x25519.md)
- [`src/sealed-box/sealed-box.md`](src/sealed-box/sealed-box.md)
- [`src/auth-box/auth-box.md`](src/auth-box/auth-box.md)
## Foundation rules
- Runtime deps: `@noble/ciphers`, `@noble/curves`, `@suaveplan/crypto-hash`, `@suaveplan/error`, `@suaveplan/types`, `tslib`, `zod`
- `sideEffects: false`, per-primitive subpath exports
- Zero `Math.random`, `Date.now`, or `crypto.getRandomValues` outside `src/primitives/random-bytes.ts` (guarded by `tests/no-disallowed.test.ts`)
- 100% statement / branch / function / line coverage (Layer 1/2 foundation rule)
- fast-check property tests for every primitive
## Testing
```bash
bunx turbo lint typecheck test:coverage --filter=@suaveplan/crypto
```