diff --git a/src/crypto.ts b/src/crypto.ts new file mode 100644 index 0000000..ae900ff --- /dev/null +++ b/src/crypto.ts @@ -0,0 +1,49 @@ +import { randomBytes, generateKeyPair as _generateKeyPair, sign, verify } from "node:crypto"; + +export interface KeyPair { + readonly privateKey: string; + readonly publicKey: string; + readonly algorithm: "Ed25519"; +} + +export async function generateKeyPair(): Promise { + const { publicKey, privateKey } = await new Promise<{ publicKey: string; privateKey: string }>((resolve, reject) => { + _generateKeyPair( + "ed25519", + { + publicKeyEncoding: { type: "spki", format: "pem" }, + privateKeyEncoding: { type: "pkcs8", format: "pem" }, + }, + (err, pubKey, privKey) => (err ? reject(err) : resolve({ publicKey: pubKey, privateKey: privKey })) + ); + }); + return { privateKey, publicKey, algorithm: "Ed25519" }; +} + +export async function signMessage(privateKeyPem: string, message: Buffer | string): Promise { + return sign(null, typeof message === "string" ? Buffer.from(message) : message, privateKeyPem).toString("base64"); +} + +export async function verifySignature(publicKeyPem: string, message: Buffer | string, signature: string): Promise { + try { + return verify(null, typeof message === "string" ? Buffer.from(message) : message, publicKeyPem, Buffer.from(signature, "base64")); + } catch { + return false; + } +} + +export function generatePairingCode(): string { + const bytes = randomBytes(8); + const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; + let code = ""; + for (let i = 0; i < 12; i++) code += chars[bytes[i % bytes.length] % chars.length]; + return `${code.slice(0, 4)}-${code.slice(4, 8)}-${code.slice(8, 12)}`; +} + +export function generateSecret(): string { + return randomBytes(32).toString("base64url"); +} + +export function generateNonce(): string { + return randomBytes(18).toString("base64url").slice(0, 24); +} diff --git a/src/index.ts b/src/index.ts index b910275..c3d15f9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,3 +2,4 @@ export * from "./types.js"; export * from "./codec.js"; export * from "./errors.js"; export * from "./auth.js"; +export * from "./crypto.js";