Files
skills/docs/networking/drive/drive-plugin-chunks/src/pipeline/sign-chunk.md
2026-05-29 08:20:56 +01:00

2.6 KiB

sign-chunk

Purpose

Signs a chunk under the server's Ed25519 private key. Signatures cover the full encoded chunk (metadata header bytes plus the encrypted payload) so receivers can verify integrity without first decrypting. The output is fixed at 64 bytes, which is the slot reserved by header.ts (SIG_SIZE = 64).

Features

  • signChunk(chunk, privKey): Uint8Array — produces a deterministic Ed25519 signature over metadata || ciphertext.
  • buildSignedChunk(chunk, privKey): Chunk — convenience wrapper that returns a chunk with the freshly-computed signature inlined.
  • Pure function — no global state, no side effects, deterministic for fixed inputs (Ed25519 with seeded keys).

Usage: Basic Example

import { randomPrivateKey } from "@suaveplan/crypto-curve/ed25519";
import { signChunk } from "@suaveplan/drive-plugin-chunks";

const privKey = randomPrivateKey();
const chunk = {
    metadata: { /* ChunkMetadata */ } as never,
    sig: new Uint8Array(64),
    ciphertext: new Uint8Array([1, 2, 3]),
};
const sig = signChunk(chunk, privKey);

Usage: Advanced Example

import {
    buildSignedChunk,
    parseChunk,
    verifyChunkSig,
} from "@suaveplan/drive-plugin-chunks";

const signed = buildSignedChunk(parseChunk(rawChunk), serverPriv);
verifyChunkSig(/* raw bytes containing signed.sig */, serverPub);

API Reference

  • signChunk(chunk: Chunk, privKey: Uint8Array): Uint8Array — returns 64-byte signature. Concatenates encodeHeader(metadata) and chunk.ciphertext then signs the concatenation.
  • buildSignedChunk(chunk: Chunk, privKey: Uint8Array): Chunk — same chunk with a populated sig field.

Implementation Notes

The signature input deliberately excludes the existing chunk.sig field — re-signing a chunk produces the same signature for fixed inputs even though Ed25519 is not strictly deterministic across implementations (suaveplan pins to @noble/curves which is RFC-8032 deterministic). Verification is implemented in verify-chunk.ts using the matching getPublicKey derivation.

The signed payload is encodeHeader(metadata) || ciphertext rather than the full raw chunk because the signature occupies a fixed slot inside the raw bytes; including it in the signing input would be circular. This split also lets transports verify a chunk in two passes: parse the metadata to learn payloadLen, then sign-verify a contiguous range of the buffer without copying. Signing happens at ingest time and is the only place the serverPrivKey ever leaves the plugin's option object — verification only needs the public key.