Ed25519 (RFC 8032 / FIPS 186-5 §7.6) — EdDSA pure + ph (preHash) + ctx (context).
Module ed25519 | Source packages/front/fw/src/crypto/pkc/ed25519.js | Deps sha512, bitArray | Worker-safe yes
EdDSA over Curve25519 (cofactor 8). Faster than ECDSA, deterministic by construction (no RNG required to sign). Ed448 explicit reject (FIPS 186-5 §7.7 out of scope).
Resolve
const ed25519 = runtime.resolve('ed25519');
// Returns: { keyPair, sign, verify, signPh, verifyPh, signCtx, verifyCtx, ed448 }
API
| Method | Signature | Returns |
|---|---|---|
keyPair(seed) |
(Uint8Array(32)) => {publicKey, privateKey} | false |
Derives the pair from the seed; false if seed absent or ≠ 32 bytes |
sign(privateKey, msg) |
(Uint8Array(64), Uint8Array) => Uint8Array(64) | false |
Pure Ed25519 signature (privateKey = seed ‖ pubKey, 64 bytes) |
verify(publicKey, msg, sig) |
(Uint8Array(32), Uint8Array, Uint8Array(64)) => boolean |
Verifies + rejects s≥L constant-time |
signPh(privateKey, msg, ctx?) |
(Uint8Array(64), Uint8Array, Uint8Array?) => Uint8Array(64) | false |
Ed25519ph — pass the raw message (SHA-512 applied internally) |
verifyPh(publicKey, msg, sig, ctx?) |
— | boolean |
signCtx(privateKey, msg, ctx) |
(Uint8Array(64), Uint8Array, Uint8Array(1..255)) => Uint8Array(64) | false |
Ed25519ctx (context required, 1..255 bytes) |
verifyCtx(publicKey, msg, sig, ctx) |
— | boolean |
ed448.{keyPair,sign,verify,signPh,verifyPh} |
() => false |
NOT-IMPLEMENTED explicit reject |
Examples
Pure EdDSA
const { ed25519, random } = fw.runtime.resolveAll(['ed25519', 'random']);
const { privateKey, publicKey } = ed25519.keyPair(random.bytes(32));
const msg = new TextEncoder().encode('Hello, EdDSA!');
const sig = ed25519.sign(privateKey, msg);
const ok = ed25519.verify(publicKey, msg, sig); // true
Ed25519ph (prehash + dom2)
// signPh takes the raw message — SHA-512 is applied internally
const sig = ed25519.signPh(privateKey, msg);
const ok = ed25519.verifyPh(publicKey, msg, sig);
Ed25519ctx (context separation)
const ctx = new TextEncoder().encode('app-v1'); // 1..255 bytes required
const sig = ed25519.signCtx(privateKey, msg, ctx);
const ok = ed25519.verifyCtx(publicKey, msg, sig, ctx);
const bad = ed25519.verifyCtx(publicKey, msg, sig, otherCtx); // false
Ed448 rejected
ed25519.ed448.keyPair(); // false + console.warn('NOT-IMPLEMENTED: ed25519: Ed448 ...')
Worker Usage
const worker = fw.createWorker(
function ({ libs, args }) {
const sig = libs.ed25519.sign(args[0], args[1]);
self.postMessage(sig);
},
{ dependencies: ['ed25519'], args: [privateKey, msg] }
);
Notes
- Deterministic:
sign(sk, msg)does NOT consume any RNG (k derived from sk + msg via SHA-512). Byte-exact reproducible. - s < L check:
verifyrejects signatures wheres ≥ L(constant-time, RFC 8032 §5.1.7 step 2) — prevents malleability (s + k·L would otherwise be valid). keyPair(seed)— seed required:keyPair()without argument returnsfalse+ warn. Userandom.bytes(32)for generation.- Ed25519ph: pass the raw message —
signPhapplies SHA-512 internally. Do not pre-hash before the call. - Ed448 not implemented — edwards448 curve + SHAKE-256; create a separate
ed448.jsmodule if required for CMVP.
See also
- sha512 — mandatory Ed25519 primitive
- x25519 — companion DH (same curve)
- ecc — alternative ECDSA
- Conformance ed25519.acvp.md