mesh/merge-gate head 1bc5719b8b85 merged into trunk a2d2af00dc5d beside mesh-host#116@bff1ac14 — pass, with a note: builds mesh-sdk (+40 dependent(s)) → ac…
mesh/repo-check head 1bc5719b8b85 merged into trunk a2d2af00dc5d beside mesh-host#116@bff1ac14 — pass: its merge-check.sh passed, each part in its toolchai…
mesh/delivery delivered
mesh/delivery-group group release/57-config-and-provisioning delivered: every member is delivered
30 lines
1.2 KiB
TypeScript
30 lines
1.2 KiB
TypeScript
// Sealing to one recipient (novox/hq ADR 0183, ADR 0206): X25519 for the agreement, HKDF-SHA256 for the
|
|
// key, AES-256-GCM for the box. The TypeScript twin of the Go package `go/seal`, byte for byte: the same
|
|
// fixtures prove both. A box is `{ v: 1, eph, iv, tag, ct }`; keys travel as PEM (SPKI public, PKCS #8
|
|
// private).
|
|
|
|
import { generateKeyPairSync, randomBytes } from "node:crypto";
|
|
import { sealWith, open, VERSION, type SealedBox } from "./box.js";
|
|
|
|
export { open, VERSION, type SealedBox };
|
|
|
|
/** A recipient's keypair as the two PEM strings it is kept and sent as. */
|
|
export interface KeyPair {
|
|
readonly publicKey: string;
|
|
readonly privateKey: string;
|
|
}
|
|
|
|
/** A fresh X25519 keypair, PEM-encoded. */
|
|
export function generateKeyPair(): KeyPair {
|
|
const { publicKey, privateKey } = generateKeyPairSync("x25519");
|
|
return {
|
|
publicKey: publicKey.export({ format: "pem", type: "spki" }) as string,
|
|
privateKey: privateKey.export({ format: "pem", type: "pkcs8" }) as string,
|
|
};
|
|
}
|
|
|
|
/** Seal plaintext to the recipient's PEM public key, with a fresh one-time key and iv. */
|
|
export function seal(plaintext: string, recipientPem: string): SealedBox {
|
|
return sealWith(plaintext, recipientPem, generateKeyPairSync("x25519").privateKey, randomBytes(12));
|
|
}
|