2.9 KiB
aead
(no submodules)
Purpose
Wraps @suaveplan/crypto.aeadEncrypt / aeadDecrypt (XChaCha20-Poly1305) into helpers that match the v1 chunk wire format, where the ciphertext and Poly1305 tag are stored in separate fields rather than as the noble-style concatenated ciphertext || tag buffer. Also provides the deterministic per-chunk nonce derivation used by the chunked packer.
Features
aeadSeal(key, nonce, plaintext)— encrypts and returns{ ciphertext, aeadTag }as detachedUint8Arrayinstances.aeadOpen(key, nonce, ciphertext, aeadTag)— re-joins the two and decrypts; throws on tag mismatch.deriveChunkNonce(baseNonce, chunkId)—baseNonce[0..4] XOR chunkId-as-u32-BE, deterministic and unique per chunk.- All inputs validated; failures wrapped as
PackerError(PACKER.ENCRYPTION_FAILED).
Usage: Basic Example
import { aeadSeal, aeadOpen, deriveChunkNonce } from "@suaveplan/packer/chunked";
const fileKey = new Uint8Array(32); // caller-supplied
const baseNonce = crypto.getRandomValues(new Uint8Array(24));
const nonce = deriveChunkNonce(baseNonce, 0);
const { ciphertext, aeadTag } = aeadSeal(fileKey, nonce, plaintext);
const back = aeadOpen(fileKey, nonce, ciphertext, aeadTag);
Usage: Advanced Example
import { aeadSeal, deriveChunkNonce } from "@suaveplan/packer/chunked";
// Seal each chunk with a derived nonce so the manifest only stores baseNonce.
function sealAll(plaintexts: Uint8Array[], fileKey: Uint8Array, baseNonce: Uint8Array) {
return plaintexts.map((p, i) => {
const nonce = deriveChunkNonce(baseNonce, i);
const { ciphertext, aeadTag } = aeadSeal(fileKey, nonce, p);
return { ciphertext, aeadTag, nonce };
});
}
API Reference
AeadSealResult—{ ciphertext: Uint8Array; aeadTag: Uint8Array }.aeadSeal(key, nonce, plaintext): AeadSealResult—key32 B,nonce24 B. Returns ciphertext (same length as plaintext) and 16-byte tag.aeadOpen(key, nonce, ciphertext, aeadTag): Uint8Array— returns plaintext. ThrowsPackerError(PACKER.ENCRYPTION_FAILED)on tag mismatch or invalid lengths.deriveChunkNonce(baseNonce, chunkId): Uint8Array— 24-byte nonce, deterministic per(baseNonce, chunkId)pair.- Constants:
AEAD_KEY_LEN = 32,AEAD_NONCE_LEN = 24,AEAD_TAG_LEN = 16,FILE_ID_LEN = 32.
Implementation Notes
The seal helper detaches the returned ciphertext and aeadTag from the underlying combined buffer with new Uint8Array(view) so callers can mutate one without aliasing the other. Nonce derivation XORs only the first 32 bits to keep the rest of baseNonce intact — the manifest's baseNonce plus a chunkId is sufficient to reconstruct any chunk's nonce. The tag length is fixed at 16 (Poly1305); AEAD_TAG_LEN is exported for callers writing their own decoders.