first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
# Unpacker
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Whole-file unpacker. Reverses the `Packer` pipeline — optionally verifies the ed25519 server signature, AEAD-decrypts, gunzips, optionally verifies the SHA-256 checksum — and returns `{ data: Uint8Array, metadata: PackedDataMetadata }`. The metadata that arrived with the packed envelope is passed through unchanged so callers retain the timestamp, mime, custom fields, etc.
## Features
- ed25519 signature verification (off by default; opt-in via `verifySignature: true`).
- AEAD decryption with algorithm picked from `metadata.encryptionAlgorithm`.
- gzip decompression triggered by `metadata.compressionAlgorithm === "gzip"`.
- SHA-256 checksum verification (opt-in via `verifyChecksum: true`).
- Typed events `unpack:start`, `unpack:verified`, `unpack:decrypted`, `unpack:decompressed`, `unpack:complete`.
## Usage: Basic Example
```ts
import { Unpacker } from "@suaveplan/packer";
const unpacker = new Unpacker();
const { data } = await unpacker.unpack(packedEnvelope);
```
## Usage: Advanced Example
```ts
import { Unpacker } from "@suaveplan/packer";
const unpacker = new Unpacker();
const result = await unpacker.unpack(packedEnvelope, {
key: fileKey,
verifySignature: true,
verifyKey: serverPubKey,
verifyChecksum: true,
});
// result.data === original plaintext, byte-identical
```
## API Reference
- **`class Unpacker extends AbstractPacker`**
- `unpack(packed: PackedData, opts?: UnpackOptions): Promise<UnpackResult>`.
- `pack()` — inherited contract; throws `PackerError(PACKER.INVALID_FORMAT)` (use `Packer` for packing).
### Failure modes
- `PACKER.VERIFICATION_FAILED` — signature did not verify; `verifyKey` not supplied while `verifySignature: true`; `verifyKey` of wrong length; checksum mismatch.
- `PACKER.INVALID_FORMAT` — `metadata.signed` set but `signature` missing; `metadata.encrypted` set but `key`/`nonce`/`aeadTag`/`encryptionAlgorithm` missing.
## Implementation Notes
The order of operations on the receive path is the reverse of the send path: `verify → decrypt → decompress → checksum`. Signature verification runs against the post-encryption ciphertext (matching how `Packer` signs), so it works without the AEAD key — a peer can forward signed-but-encrypted packed bundles and recipients verify provenance without ever decrypting. Checksum verification runs against the post-decompression plaintext, matching what `Packer.checksum(...)` computed pre-transform — a true integrity round-trip.