# chunk ## Purpose Encodes and parses the wire-format v1 chunk in its entirety: `metadata(100) || sig(64) || ciphertext(payloadLen)`. Composes `encodeHeader` / `parseHeader` with byte-level concatenation, length validation, and the canonical signing-payload helper. Every receive path in the packer (chunked unpacker, chunk verifier, mesh transport) calls `parseChunk` before any cryptographic work; every send path calls `encodeChunk` once metadata, signature, and ciphertext are ready. ## Features - `encodeChunk({ metadata, sig, ciphertext })` returns a single `Uint8Array` of `164 + payloadLen` bytes. - `parseChunk(buf)` returns `{ metadata, sig, ciphertext }` with all three fields as zero-copy subarrays of `buf`. - `signingPayload(metadataBytes, ciphertext)` returns the canonical bytes the server signs / receivers verify. - Length and structural validation lifted from `parseHeader`; chunk-level validation adds the total-length check. ## Usage: Basic Example ```ts import { encodeChunk, parseChunk } from "@suaveplan/packer/chunked"; const wire = encodeChunk({ metadata, // ChunkV1Metadata sig: new Uint8Array(64), // ed25519 signature ciphertext: new Uint8Array(payloadLen), }); const back = parseChunk(wire); // back.metadata, back.sig, back.ciphertext ``` ## Usage: Advanced Example ```ts import { encodeChunk, parseChunk, signingPayload, encodeHeader } from "@suaveplan/packer/chunked"; import { ed25519 } from "@noble/curves/ed25519"; // Producer: const headerBytes = encodeHeader(metadata); const signed = signingPayload(headerBytes, ciphertext); const sig = ed25519.sign(signed, serverPrivKey); const wire = encodeChunk({ metadata, sig, ciphertext }); // Receiver: const { metadata: m, sig: s, ciphertext: c } = parseChunk(wire); const signedAgain = signingPayload(encodeHeader(m), c); if (!ed25519.verify(s, signedAgain, serverPubKey)) { throw new Error("bad sig"); } ``` ## API Reference - **`interface EncodeChunkInput { metadata: ChunkV1Metadata; sig: Uint8Array; ciphertext: Uint8Array }`** - **`encodeChunk(input: EncodeChunkInput): Uint8Array`** — total length `164 + payloadLen`. Throws `PackerError(PACKER.INVALID_FORMAT)` on `sig.byteLength !== 64` and `PackerError(PACKER.PAYLOAD_LEN_INVALID)` on ciphertext-length mismatch. - **`parseChunk(buf: Uint8Array): ParsedChunkV1`** — validates total length matches `164 + metadata.payloadLen`. Throws on header-parse failures and on length mismatch. - **`signingPayload(metadataBytes: Uint8Array, ciphertext: Uint8Array): Uint8Array`** — concatenates the two for ed25519 sign/verify. ## Implementation Notes `encodeChunk` performs `metadata` field-length validation indirectly via `encodeHeader`, then writes a single fresh `Uint8Array(164 + payloadLen)` with three `set` calls — no intermediate copy of the metadata or ciphertext beyond the final placement. `parseChunk` re-uses `parseHeader`'s zero-copy subarray pattern; the returned struct shares its underlying buffer with the input, so callers must clone if they intend to mutate either side independently. `signingPayload` allocates a fresh buffer because the AEAD-side callers must not mutate the wire bytes after sig generation.