@wovin/crypto
v0.1.20
Published
A secure, isomorphic TypeScript library providing cryptographic primitives (AES, ECDH, Ed25519) and mnemonic-based key derivation. Implements PBKDF2-HMAC-SHA512 for key stretching and supports multiple key derivation paths (ECDH, EdDSA, HKDF).
Readme
@wovin/crypto - Cryptographic Primitives & Mnemonic Key Derivation
A secure, isomorphic TypeScript library providing cryptographic primitives (AES, ECDH, Ed25519) and mnemonic-based key derivation. Implements PBKDF2-HMAC-SHA512 for key stretching and supports multiple key derivation paths (ECDH, EdDSA, HKDF).
Features
- AES Encryption - AES-CTR, AES-CBC, AES-GCM via Web Crypto API
- ECDH - Elliptic-curve Diffie-Hellman key agreement (P-256/P-384/P-521)
- Ed25519 - EdDSA signing and verification
- HKDF - Key derivation with SHA-256
- BIP39 Mnemonics - Secure mnemonic generation with PBKDF2-HMAC-SHA512
- Isomorphic - Works in Node.js and browsers
Installation
npm install @wovin/crypto
# or
pnpm add @wovin/cryptoSubpath Exports
import { ... } from '@wovin/crypto' // everything
import { ... } from '@wovin/crypto/aes' // AES encryption/decryption
import { ... } from '@wovin/crypto/ecdh' // ECDH key agreement
import { ... } from '@wovin/crypto/ed25519' // Ed25519 signing
import { ... } from '@wovin/crypto/keys' // key utilities
import { ... } from '@wovin/crypto/mnemonic' // mnemonic-crypto wrappersQuick Start
Generate a New Mnemonic
import { createMnemonic } from '@wovin/crypto'
// Generate a secure 24-word mnemonic
const mnemonic = createMnemonic(24)
console.log(mnemonic.join(' '))Hash a Mnemonic
import { hashMnemonic } from '@wovin/crypto'
const mnemonic = ['abandon', 'ability', 'able', /* ... 21 more words ... */]
// Default: full 128 hex characters (64 bytes)
const hash = hashMnemonic(mnemonic)
// With optional passphrase for extra security
const hashWithPassphrase = hashMnemonic(mnemonic, 'my-secret-passphrase')
// Extract subset: first 32 characters
const shortHash = hashMnemonic(mnemonic, '', 32, 0)
// Extract from offset: skip first 32, take 32 more
const offsetHash = hashMnemonic(mnemonic, '', 32, 32)Derive Cryptographic Keys
import {
getEdDSAkeypairFromHashArray,
getECDHkeypairFromHashArray,
encHashedMnemonic
} from '@wovin/crypto'
const mnemonic = ['abandon', 'ability', /* ... */]
// 1. Hash the mnemonic
const hashedMnem = encHashedMnemonic(mnemonic)
// 2. Derive EdDSA keypair (for DIDs and signing)
const eddsaKeypair = await getEdDSAkeypairFromHashArray(hashedMnem)
// 3. Derive ECDH keypair (for encryption)
const ecdhKeypair = await getECDHkeypairFromHashArray(hashedMnem)API Reference
createMnemonic(length: number): string[]
Generates a cryptographically secure random mnemonic.
Parameters:
length- Word count: 12, 15, 18, 21, or 24
Returns: Array of English BIP39 words
hashMnemonic(mnu, salt?, length?, offset?, SALT_PREFIX?): string
Hashes a mnemonic using PBKDF2-HMAC-SHA512.
Parameters:
mnu- Array of mnemonic words (minimum 24 words)salt- Optional passphrase added to salt (default:'')length- Optional: number of hex characters to returnoffset- Starting position in hex output (default:0)SALT_PREFIX- Prefix prepended to salt (default:'wovin_mnemkey')
Returns: Hex string of specified length/offset
Algorithm:
PBKDF2-HMAC-SHA512(
password = NFKD(mnemonic_words_joined_with_spaces),
salt = SALT_PREFIX + optional_passphrase,
rounds = 2048,
dklen = 64 bytes (output as 128 hex characters)
)encHashedMnemonic(mnemonic: string[]): Uint8Array
Hashes mnemonic and returns as UTF-8 encoded bytes.
getEdDSAkeypairFromHashArray(hashArray: Uint8Array): Promise<EdDSASigner>
Derives EdDSA keypair (Ed25519) from hashed mnemonic.
getECDHkeypairFromHashArray(hashArray, keyAlgo?): Promise<CryptoKeyPair>
Derives ECDH keypair from hashed mnemonic.
Supported Curves:
import { keyAlgos } from '@wovin/crypto'
keyAlgos.ecdh.p256 // NIST P-256 (default)
keyAlgos.ecdh.p384 // NIST P-384
keyAlgos.ecdh.p521 // NIST P-521getHKDFkeyFromHashArray(hashArray, info?, salt?, extractable?): Promise<CryptoKey>
Derives HKDF key from hashed mnemonic for key derivation.
Parameters:
hashArray- Output fromencHashedMnemonic()info- Context/info string (default:'note3-hkdf')salt- HKDF salt (default:'note3-hkdf')extractable- Whether key is extractable (default:false)
Security Considerations
Mnemonic Storage
- Store mnemonics securely (encrypted at rest, not in plain text)
- Never log or expose mnemonics
- Use environment variables or secure vaults for production
Salt/Passphrase
- Optional passphrase adds extra security layer
- Use strong, unique passphrases
- Remember passphrase - it's required to re-derive keys
Key Derivation
- Different info/salt values produce different keys
- Use consistent parameters for reproducibility
Hash Output
- Default 128 hex characters (64 bytes) is secure
- Subsetting with
length/offsetis safe for non-cryptographic purposes - For cryptographic operations, use the full hash
Breaking Changes
Version RC28+: PBKDF2-HMAC-SHA512 replaces SHA-256
If upgrading from an earlier version, see MIGRATION.md for details on:
- Hash output changes (64 bytes -> 128 hex characters)
- DID regeneration required
- Key re-derivation process
Browser Support
Works in all modern browsers with Web Crypto API:
- Chrome 37+
- Firefox 34+
- Safari 11+
- Edge 79+
- Node.js 15+
Testing
pnpm test