2.6 KiB
sign
Purpose
Server-side signing helper that turns an unsigned DriveTemplate into a fully-formed envelope (DTP-04). Produces an Ed25519 signature over canonicalSerialize(template) and returns a new template object with the serverSignature field populated. The function never fabricates timestamps or nonces; the caller is responsible for supplying a fresh 16-byte nonce, a recent issuedAt, and an expiresAt window inside the 24-hour issuance budget.
Features
signTemplate(template, serverSecretKey)— pure function; no global state.- Built on the deterministic
canonicalSerializebyte stream so the signed payload is portable across runtimes. - Returns a frozen-shape
DriveTemplateready to broadcast on the bus or persist to the FileLocationIndex.
Usage: Basic Example
import {
randomPrivateKey,
} from "@suaveplan/crypto-curve/ed25519";
import { signTemplate } from "@suaveplan/drive-template";
const secret = randomPrivateKey();
const tpl = signTemplate(
{
schemaVersion: 1,
driveId: "drive-1",
rootFolder: { name: "/", children: [] },
policy: { defaultPolicy: { autoDownload: false, meshAllowed: true, cdnAllowed: true } },
issuer: "00".repeat(32),
issuedAt: Date.now(),
expiresAt: Date.now() + 60_000,
nonce: new Uint8Array(16).fill(7),
},
secret
);
Usage: Advanced Example
import {
getPublicKey,
randomPrivateKey,
} from "@suaveplan/crypto-curve/ed25519";
import { toHex } from "@suaveplan/crypto-utils";
import { signTemplate, verifyTemplateSignature } from "@suaveplan/drive-template";
const secret = randomPrivateKey();
const issuer = toHex(getPublicKey(secret));
const tpl = signTemplate({ /* ... */ issuer } as never, secret);
verifyTemplateSignature(tpl); // throws on any tampering
API Reference
signTemplate(template: Omit<DriveTemplate, "serverSignature">, serverSecretKey: Uint8Array): DriveTemplate.
Implementation Notes
signTemplate is intentionally synchronous — @noble/curves Ed25519 is fast enough that a 4096-byte template signs in well under a millisecond on commodity hardware, and the async overhead would dwarf the actual work. Callers that need to sign in a worker thread can wrap in queueMicrotask themselves; baking that into the API would force every consumer through an unnecessary Promise. The sign path performs zero memory allocations beyond the canonical buffer and the resulting signature, which keeps it suitable for high-throughput template-issuance pipelines that mint thousands of distributions per minute.