Full TypeScript rewrite of v1 with the same public API. The node bundle now routes RSA primitives through node:crypto whenever possible; the browser bundle defaults to native BigInt.
See CHANGELOG.md for the full list and MIGRATION.md for upgrade guidance.
Highlights
Performance
- Keygen via
crypto.generateKeyPairSync— 2048-bit drops from ~2.3 s to ~50 ms (~45× faster). - PKCS#1 v1.5 / PSS sign+verify via
crypto.sign/crypto.verify— PSS-SHA256 sign on 2048-bit drops from ~17 ms to sub-millisecond. - Browser bundle uses native
BigInt— ~4–5× faster than jsbn on PSS sign/verify. Falls back to jsbn on pre-2020 runtimes.
Security fixes (no API change)
- Constant-time OAEP decode (closes Manger padding-oracle), PKCS#1 v1.5 decode (Bleichenbacher/ROBOT), and PSS verify.
- Private-key operations are blinded (Kocher / Brumley-Boneh defence).
- Miller-Rabin uses CSPRNG witnesses with FIPS 186-4 round counts (was
Math.random()over a fixed 168-element table). - Imported private keys are CRT-consistency-checked — closes a Boneh-DeMillo-Lipton fault-injection vector.
- Hardened PKCS#8 / OpenSSH parsers; public-exponent and RSA-primitive bounds checks per RFC 8017.
generate(B)refusesB < 512and warns below 2048; Fermat-distance defence on|p − q|.
Breaking changes
- Min Node.js is now 20.
- ESM-first with dual ESM/CJS via
package.json#exports. - Browser default return type is
Uint8Array(was aBufferpolyfill); Node still returnsBuffer. - Browser bundle has zero Node-builtin imports — no
Buffer/cryptoshims, CI-enforced. - Default signing scheme switched from
pkcs1topss(RFC 8017 / NIST best practice). PasssigningScheme: 'pkcs1'to keep v1 behaviour. Baresha256shorthand now resolves topss-sha256. - MD4 is Node-only and provider-gated (OpenSSL 3 no longer loads the legacy provider by default).
- Native PKCS#1 v1.5
privateDecryptfalls back to JS engine on modern Node (security-deprecated upstream); plaintext is byte-identical. - Custom MGF for PSS throws on the node bundle —
node:cryptoonly supports MGF1 with hash equal to signing hash. setOptions({environment})is a deprecated no-op (still forces JS engine when set to'browser').asn1npm dependency removed — replaced by an in-tree ~150-line DER reader/writer; byte-identical output.
Added
- TypeScript types for every public surface.
@noble/hashesruntime dependency (~6 KB gzipped, audited).- CI-enforced bundle size budget: browser <100 KB raw / <30 KB gzipped; node <120 KB raw / <35 KB gzipped.
Internal
- Modern tooling:
tsup,vitest,biome, strict TypeScript. - 1006 test cases across 27 files; the v1 mocha suite (61
it()blocks) is ported verbatim and runs in bothnodeandbrowser-emulatedvitest projects.