Files
suaveplan/packages/foundation/data/packer/src/chunked/verifier/chunk-verifier.md
2026-05-27 23:47:53 +01:00

2.8 KiB

chunk-verifier

(no submodules)

Purpose

Verifies the structural validity and ed25519 server signature of a v1 chunk without the file decryption key. Used by mesh peers that forward chunks they cannot themselves read, by drive's chunks-plugin during the receive-side gate (sig-verify before persistence), and by any consumer that wants to reject forged chunks before engaging the AEAD path.

Features

  • ChunkVerifier(serverPubKey) — single-server-key instance; reusable across many chunks.
  • verify(chunkBytes): VerifyResult — returns { ok: true, metadata } or { ok: false, code, message }. Never throws on verifiable-but-bad input; only throws on programmer error (wrong-length pubkey).
  • Performs the full PACKER-CHUNK-* invariant chain (version, flags, payloadLen) before signature check.

Usage: Basic Example

import { ChunkVerifier } from "@suaveplan/packer/chunked";

const verifier = new ChunkVerifier(serverPubKey);
const result = verifier.verify(receivedChunkBytes);
if (!result.ok) {
    console.warn("rejected chunk:", result.code, result.message);
} else {
    persistChunk(receivedChunkBytes, result.metadata);
}

Usage: Advanced Example

import { ChunkVerifier, PACKER_CODES } from "@suaveplan/packer/chunked";

const verifier = new ChunkVerifier(serverPubKey);
async function gate(stream: AsyncIterable<Uint8Array>) {
    let valid = 0;
    let badSig = 0;
    let badFormat = 0;
    for await (const raw of stream) {
        const r = verifier.verify(raw);
        if (r.ok) { valid += 1; continue; }
        if (r.code === PACKER_CODES.VERIFICATION_FAILED) badSig += 1;
        else badFormat += 1;
    }
    return { valid, badSig, badFormat };
}

API Reference

  • interface VerifyOk { ok: true; metadata: ChunkV1Metadata }
  • interface VerifyFail { ok: false; code: PackerErrorCode; message: string }
  • type VerifyResult = VerifyOk | VerifyFail
  • class ChunkVerifier
    • constructor(serverPubKey: Uint8Array) — throws PackerError(PACKER.INVALID_FORMAT) if serverPubKey.byteLength !== 32.
    • verify(chunkBytes: Uint8Array): VerifyResult — never throws on bad chunks; rejected chunks come back as VerifyFail.

Implementation Notes

verify first runs parseChunk, which surfaces structural failures (INVALID_FORMAT, VERSION_UNSUPPORTED, FLAGS_RESERVED_NONZERO, PAYLOAD_LEN_INVALID) as PackerError — these are caught and folded into VerifyFail. Only after the structural gate is the ed25519 signature checked against the canonical signing payload metadata[0..100] ‖ ciphertext[0..payloadLen]. Cost: one parseChunk (zero-copy), one 100-byte encodeHeader allocation, one signing-payload concatenation (allocates 100 + payloadLen bytes), one ed25519.verify.