classDiagram
%% Core Library
class Utils {
<<Namespace>>
+hardenRNG(dkLen, isTemporal, thsConfig)
+wrapTry(asyncFn)
+wrapTrySync(syncFn)
+buff(str, opts)
}
%% Crypto Operations
class Cryptography {
<<Namespace>>
+getCipher(name, opts)
+getHash(name, opts)
+getHmac(name, opts)
+getXof(name, opts)
+getKmac(name, opts)
}
%% Memory Safety
class SecurityMemory {
<<Namespace>>
+zeroBuf(...buffers)
+compare(a, b, opts)
}
%% Advanced Features
class PQC {
<<Namespace>>
+mlkem(algorithm, opts)
+mldsa(algorithm, opts)
+slhdsa(algorithm, opts)
+falcon(algorithm, opts)
}
class Mnemonics {
<<Namespace>>
+bip39.generate(strength)
+bip39.toSeed(mnemonic)
+ikey.generate(strength)
+ikey.validate(phrase)
}
class Encodings {
<<Namespace>>
+codec(name, opts).encode(data)
+codec(name, opts).decode(data)
+wif.encode(privateKey, opts)
+qr.toImage(data, opts)
+qr.toTerminal(data, opts)
}
%% Technology Layers
class NodeNative {
<<Core Native API>>
-node:crypto
}
class NobleWrapper {
<<Third Party Library>>
-@noble/post-quantum
-@noble/ciphers
-@noble/hashes
}
%% Relationships and composition
Utils *-- PQC : Contains
Utils *-- Cryptography : Contains
Utils *-- SecurityMemory : Contains
Utils *-- Mnemonics : Contains
Utils *-- Encodings : Contains
PQC ..> NobleWrapper : Implemented via (default)
Cryptography ..> NodeNative : Uses if extra=false
Cryptography ..> NobleWrapper : Uses if extra=true
High-performance, auditable, memory-safe cryptographic and encoding utilities with first-class post-quantum support.
Built for modern security-critical applications: wallets, key management, secure messaging, and frameworks that need battle-tested primitives without bloat.
Full API context optimized for AI assistants and contributors is available in
llms-full.txt.
- Post-Quantum Cryptography (FIPS 203/204/205 + NIST Round 3)
- Modern Symmetric Crypto (AES-GCM, XChaCha20-Poly1305, etc.)
- Memory Safety — constant-time comparison, secure zeroing, temporal hardening
- Two Mnemonic Systems
- Standard BIP39 (multi-language)
- iKey — high-density 65,536-word mnemonic (16 bits per word)
- KDF: Argon2id (native Node.js)
- Encoding: base16/32/58/64, bech32(m), WIF, QR codes (GIF/SVG/Terminal)
- Extra: Leverages @noble/* for browser compatibility
- Auditable — tiny surface, strict mode, checksum verification on build
npm install @stless/utils
# or
yarn add @stless/utilsRequires Node.js ≥ 24
// ESM
import Utils from '@stless/utils';
// or CJS
const { Utils } = require('@stless/utils');
// Secure random bytes (with optional temporal hardening)
const key = await Utils.hardenRNG(32, true);
// Argon2id KDF
const hash = await Utils.argon2('argon2id', {
msg: 'my password',
salt: await Utils.hardenRNG(16)
});
// Post-Quantum Key Encapsulation
const { publicKey, secretKey } = Utils.mlkem('ml-kem-768', {
seed: await Utils.hardenRNG(64)
});
// Post-Quantum Key Signature
const { publicKey, secretKey } = Utils.mldsa('ml-dsa-65', {
seed: await Utils.hardenRNG(32)
});// Buffer handling & memory safety
const buf = Utils.buff('hello', { encoding: 'utf-8' });
Utils.zeroBuf(buf); // secure wipe
Utils.compare(a, b, { harden: true }); // constant-time
// Randomness
const entropy = await Utils.hardenRNG(32, isHardenRNG, conf);
// Try/catch sugar
const result = await Utils.wrapTry(async () => { ... });// Base codecs
const b58 = Utils.codec('base58').encode(data);
const decoded = Utils.codec('base58').decode(b58);
Utils.codec('bech32').encode(...);
Utils.codec('base64url').encode(...);
// Wallet Import Format
const wif = Utils.wif.encode(privateKey, { compressed: true });
const { privateKey: pk } = Utils.wif.decode(wif);// GIF (native, no canvas)
const gif = Utils.qr.toImage('https://example.com', { scale: 6 });
// SVG
const svg = Utils.qr.toSVG(data);
// Terminal
console.log(Utils.qr.toTerminal(data));const key = await Utils.hardenRNG(32);
const msg = Utils.buff('top secret');
// 1. Unified Noble Access (extra: true)
// Works for AES-GCM, XChaCha20, XSalsa20, etc.
const iv = await Utils.hardenRNG(24); // 24 bytes for X-variants
const cipher = Utils.getCipher('xchacha20-poly1305', {
key, iv, extra: true, e: true, buffer: true
});
const encrypted = Buffer.concat([cipher.update(msg), cipher.final()]);
// 2. Node.js Native Access (extra: false)
const iv2 = await Utils.hardenRNG(16);
const cipher2 = Utils.getCipher('aes-256-ctr', {
key, iv: iv2, e: true
});
const encrypted2 = Buffer.concat([cipher2.update(msg), cipher2.final()]);const hash = Utils.getHash('sha3-512', { extra: true })
.update(data)
.digest();
const hmac = Utils.getHmac('sha256', { key });const xof = Utils.getXof('shake256', { extra: true, o: { dkLen: 64 } });
const kmac = Utils.getKmac('kmac256', { key });// ML-KEM (Key Encapsulation)
const kem = Utils.mlkem('ml-kem-1024', { seed });
// ML-DSA (Signatures)
const dsa = Utils.mldsa('ml-dsa-87', { seed });
// SLH-DSA
const sphincs = Utils.slhdsa('slh-dsa-sha2-256f', { seed });
// Falcon
const falcon = Utils.falcon('falcon1024', {
seed
clear: true, // Clear the input seed
});All PQC functions are deterministic when given the same seed. See @noble/post-quantum for full documentations and usage.
const mnemonic = Utils.bip39.generate(256, { lang: 'english' });
const seed = Utils.bip39.toSeed(mnemonic, { password: 'optional' });
const valid = Utils.bip39.validate(mnemonic);// Generate 256-bit iKey (17 words including checksum)
const ikey = await Utils.ikey.generate(256, { isHardenRNG: true });
// Validate
const isValid = Utils.ikey.validate(ikey);
// Conversion
const bytes = Utils.ikey.toBytes(phrase);
const words = Utils.ikey.toWords(buffer);- All Noble ciphers are wrapped to support the standard
.update(data)and.final()pattern, regardless of whether the underlying algorithm is a one-shot function or a stateful class. - All sensitive buffers are zeroed after use when
clear: trueis passed. compare()usestimingSafeEqual(or hardened double-hash mode).hardenRNGintegrates ths-csprng wrapper for temporal hardening.- Checksums are generated and verified on every build verify.sh.
- Prefer
extra: truefor Noble implementations in cross-platform code.
Always use the library's memory management helpers when handling secrets.
Instead of maintaining static lists, you can query the engine directly for all supported primitives.
// Get everything: PQC, Noble (extra), and Native (crypto)
const registry = Utils.names;
console.log(registry.pqc); // All Noble Post-Quantum algorithms
console.log(registry.extra); // All Noble (Extra) algorithms
console.log(registry.crypto); // All secure-filtered native algorithmsUtils.codec(name)
| Category | Supported Names |
|---|---|
| Standard Bases | base16, base32, base58, base64 |
| Flavors | base58xmr, base58xrp, base64url, base32hex, base32crockford, base58check |
| Bitcoin / Lightning | bech32, bech32m |
Utils.argon2(name = 'argon2id')
| Variant | Name |
|---|---|
| Default | argon2id |
| Alternatives | argon2i, argon2d |
| Function | Supported Names |
|---|---|
Utils.mlkem() |
ml-kem-512, ml_kem512, ml-kem-768, ml_kem768, ml-kem-1024, ml_kem1024 |
Utils.mldsa() |
ml-dsa-44, ml_dsa44, ml-dsa-65, ml_dsa65, ml-dsa-87, ml_dsa87 |
Utils.slhdsa() |
slh-dsa-sha2-128f, slh-dsa-sha2-128s, slh-dsa-sha2-192f, slh-dsa-sha2-192s,slh-dsa-sha2-256f, slh-dsa-sha2-256s,slh-dsa-shake-128f, slh-dsa-shake-128s, slh-dsa-shake-192f, slh-dsa-shake-192s,slh-dsa-shake-256f, slh-dsa-shake-256s |
Utils.falcon() |
falcon512, falcon1024 |
Utils.noble(name)
| Category | Names |
|---|---|
| Ciphers | aes, chacha, salsa |
| Hashes / HMAC / XOFs | noble_hmac, sha2, sha3, sha3_addons, blake3_mod, blake2, legacy |
| PQC: ML-KEM | ml_kem512, ml_kem_512, ml_kem768, ml_kem_768, ml_kem1024, ml_kem_1024 |
| PQC: ML-DSA | ml_dsa44, ml_dsa_44, ml_dsa65, ml_dsa_65, ml_dsa87, ml_dsa_87 |
| PQC: Signature / Other | slh_dsa, falcon512, falcon1024 |
| Function | Supported Algorithms |
|---|---|
Utils.getCipher() |
aes-256-gcm, aes-256-ctr, aes-256-cfb, aes-256-cfb1, aes-256-cfb8, aes-256-ocb, aes-256-ofb, aes-256-xts, chacha20-poly1305, chacha20 |
Utils.getHmac() |
sha224, sha256, sha384, sha512, sha512-224, sha512-256, ripemd, ripemd160, rmd160, sha1, md5, md5-sha1 |
Utils.getHash() |
sha224, sha256, sha384, sha512, sha512-224, sha512-256, sha3-224, sha3-256, sha3-384, sha3-512, blake2b512, blake2s256, ripemd, ripemd160, rmd160, sha1, md5, md5-sha1 |
Utils.getXof() |
shake128, shake256 |
Ciphers
| Category | Supported Names |
|---|---|
| AES | aes-256-gcm, aes-256-ctr, aes-256-cfb, aes-256-siv |
| ChaCha20 | chacha20-poly1305, xchacha20-poly1305, chacha20, xchacha20 |
| Salsa20 | xsalsa20-poly1305, salsa20, xsalsa20 |
HMAC, Hash & XOF
| Function | Supported Names |
|---|---|
Utils.getHmac() |
sha224, sha256, sha384, sha512, sha512-224, sha512-256, ripemd160, sha1, md5 |
Utils.getHash() |
sha224, sha256, sha384, sha512, sha512-224, sha512-256,sha3-224, sha3-256, sha3-384, sha3-512,keccak-224, keccak-256, keccak-384, keccak-512,blake2s256, blake2b512, blake3, ripemd160, sha1, md5 |
Utils.getXof() |
shake128, shake256, cshake128, cshake256, turboshake128, turboshake256, k12, kt128, kt256 |
Keyed XOF
| Function | Supported Names |
|---|---|
Utils.getKmac() |
kmac128, kmac256 |
Tip
Consistency & Compatibility: Use extra: true to prioritize Noble implementations for maximum cross-platform consistency and browser support.
Flexible Naming: The library supports both kebab-case (ml-kem-512) and snake_case (ml_kem_512) for all algorithms (Noble, PQC, Cipher, Hash, HMAC, and XOF). As long as the name is lowercase and valid, the primitive will be resolved correctly.
npm run check # test + verify checksums
npm run build # minify + generate docs + checksums
npm testThe project uses:
terserfor minification- SHA-256 checksums for all built files
- Strict mode + comprehensive test suite
Licensed under the Apache License, Version 2.0; a robust, permissive license that includes an explicit grant of patent rights and provides protection against contributor liability.
Copyright © 2026 Aries Harbinger. See the LICENSE file for full details.
- Github Repository
- npm Package
- Full AI Context llms-full.txt (for contributors / LLM assistants)
Made with security, auditability, and developer experience in mind.