3.8 KiB
engines/sodium-sign-engine
(no submodules)
Purpose
sodiumSignEngine implements the SignEngine interface from @suaveplan/crypto using libsodium's Ed25519 signing primitives. Ed25519 is a deterministic signature scheme based on the Edwards-curve digital signature algorithm — it provides strong security guarantees, fast verification, and small key and signature sizes.
This engine replaces the noble-curves default in performance-sensitive or server-side scenarios where the libsodium WASM path is preferred for its maturity and NIST/IETF certification heritage.
Features
- Ed25519 keypair generation via
crypto_sign_keypair— uses libsodium's internal secure entropy. - Detached signature creation via
crypto_sign_detached— signature is separate from the message. - Detached signature verification via
crypto_sign_verify_detached— returns boolean, never throws on invalid signatures. - 32-byte public keys, 64-byte secret keys (includes seed), 64-byte signatures.
- Conforms to
SignEnginefrom@suaveplan/crypto/engines— drop-in for the noble default.
Usage: Basic Example
import { sodiumReady } from "@suaveplan/crypto-sodium/init";
import { sodiumSignEngine } from "@suaveplan/crypto-sodium/engines/sign";
await sodiumReady();
const kp = sodiumSignEngine.generateKeypair();
const msg = new TextEncoder().encode("sign this");
const sig = sodiumSignEngine.sign(kp.secretKey, msg);
const valid = sodiumSignEngine.verify(kp.publicKey, sig, msg);
console.log(valid); // true
Usage: Advanced Example
Using sodiumSignEngine as a pluggable engine with @suaveplan/crypto:
import { sodiumReady } from "@suaveplan/crypto-sodium/init";
import { sodiumSignEngine } from "@suaveplan/crypto-sodium/engines/sign";
import type { SignEngine } from "@suaveplan/crypto/engines";
await sodiumReady();
function signDocument(
engine: SignEngine,
secretKey: Uint8Array,
document: Uint8Array
): Uint8Array {
return engine.sign(secretKey, document);
}
const kp = sodiumSignEngine.generateKeypair();
const doc = new TextEncoder().encode("legal document text");
const sig = signDocument(sodiumSignEngine, kp.secretKey, doc);
// Verify on the receiving side:
const ok = sodiumSignEngine.verify(kp.publicKey, sig, doc);
API Reference
sodiumSignEngine: SignEngine
Singleton engine object.
generateKeypair(byteSource?: ByteSource): SignKeypair
Generates a fresh Ed25519 keypair. The byteSource parameter is accepted for interface compatibility but ignored — libsodium manages its own CSPRNG.
Returns: { publicKey: Uint8Array (32 bytes), secretKey: Uint8Array (64 bytes) }
sign(secretKey: Uint8Array, message: Uint8Array): Uint8Array
Produces a 64-byte detached Ed25519 signature over message.
verify(publicKey: Uint8Array, signature: Uint8Array, message: Uint8Array): boolean
Verifies a detached signature. Returns false rather than throwing on any verification failure (wrong key, tampered sig, wrong message). Exceptions from libsodium are caught and mapped to false.
Implementation Notes
libsodium's crypto_sign_keypair() returns { publicKey, privateKey } — note the property is named privateKey in the TS bindings despite being the full 64-byte secret key (seed + public key concatenated). The engine remaps this to secretKey to match the SignKeypair interface.
The byteSource parameter is not forwarded to libsodium because libsodium's WASM module manages entropy internally. Callers cannot substitute an alternative random source for key generation via this engine.
verify wraps crypto_sign_verify_detached in a try/catch because libsodium throws for structurally malformed inputs (e.g., a signature buffer that is not 64 bytes), mapping those to false for consistency with the SignEngine contract.