first commit
This commit is contained in:
55
docs/foundation/data/packer/src/unpacker/unpacker.md
Normal file
55
docs/foundation/data/packer/src/unpacker/unpacker.md
Normal 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.
|
||||
Reference in New Issue
Block a user