Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
# chunk-verifier
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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
```ts
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
```ts
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`.