first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
# build
## Purpose
Constructs a server-signed `Manifest` for an ingested file: bundles the file metadata (`fileId`, `fileSize`, `chunkSize`, `totalChunks`), encryption envelope (`algo`, `fileKeyWrapped`, `baseNonce`), and per-chunk integrity hashes into a single record, then signs the canonical encoding under the server private key. The manifest is the consensus artefact: peers that trust the server public key can verify it without holding any chunk bytes.
## Features
- `buildManifest(options): Manifest` — pure function, no I/O, no global state.
- `canonicalSerialize(manifest): Uint8Array` — deterministic big-endian length-prefixed encoding suitable for cross-platform Ed25519 signing.
- `algo` is encoded as a length-prefixed UTF-8 string so future encryption algorithms can be added without breaking the wire format.
- Per-chunk entries pack `(chunkId: u32, hash: 32 bytes, payloadLen: u32)` into 40 bytes — bounded growth, predictable memory.
## Usage: Basic Example
```ts
import { buildManifest } from "@suaveplan/drive-plugin-chunks";
const manifest = buildManifest({
fileId: sha256Bytes,
fileSize: 12n,
chunkSize: 1024,
totalChunks: 1,
encryption: { algo: "xchacha20poly1305", fileKeyWrapped: fileKey, baseNonce },
chunks: [{ chunkId: 0, hash: chunkHash, payloadLen: 12 }],
serverPrivKey,
});
```
## Usage: Advanced Example
```ts
import { buildManifest, canonicalSerialize } from "@suaveplan/drive-plugin-chunks";
import { verify } from "@suaveplan/crypto-curve/ed25519";
const manifest = buildManifest({ /* ... */ });
const { sig, ...base } = manifest;
const ok = verify(sig, canonicalSerialize(base), serverPubKey);
```
## API Reference
- `buildManifest(options): Manifest` — returns `{ version, fileId, fileSize, chunkSize, totalChunks, encryption, chunks, sig }`.
- `canonicalSerialize(manifest: Omit<Manifest, "sig">): Uint8Array` — used both for signing and for verification.
## Implementation Notes
Field order in `canonicalSerialize` is fixed and big-endian; changing it would break every previously-stored manifest. The `algo` length prefix makes the encoded form self-delimiting so receivers don't need an explicit version bump to add new algorithms — they only need to add a parsing branch keyed on the algo string. The final `buf.slice(0, off)` trims any over-allocated tail, but `totalLen` is computed exactly so this is normally a no-op.