# hkdf _(no submodules)_ ## Purpose Provides HKDF (HMAC-based Key Derivation Function, RFC 5869) over SHA-256, SHA-384, and SHA-512. HKDF is the standard mechanism for stretching or diversifying key material — for instance, turning a Diffie-Hellman shared secret into one or more symmetric encryption keys. This module wraps the audited `@noble/hashes` HKDF implementation and constrains the algorithm surface to the `HashAlgorithm` union shared across `@suaveplan/crypto-hash`. ## Features - `hkdf(algo, ikm, options)` — HKDF-Extract-and-Expand in one call - Supports SHA-256, SHA-384, SHA-512 via `HashAlgorithm` - Configurable output length (in bytes) - Accepts arbitrary `salt` and `info` context bytes - Deterministic: same inputs always produce the same key material ## Usage: Basic Example ```ts import { hkdf } from "@suaveplan/crypto-hash/kdf"; const ikm = new Uint8Array(32).fill(0x01); // input key material const salt = new Uint8Array(16); // random salt (often public) const info = new TextEncoder().encode("suaveplan-session-key-v1"); const sessionKey = hkdf("SHA-256", ikm, { salt, info, length: 32 }); console.log(sessionKey.length); // 32 ``` ## Usage: Advanced Example ```ts import { hkdf } from "@suaveplan/crypto-hash/kdf"; import { toHex } from "@suaveplan/crypto-hash/encoding"; // Derive separate encryption and MAC keys from a single DH shared secret function deriveKeyPair(sharedSecret: Uint8Array, context: string): { encKey: Uint8Array; macKey: Uint8Array; } { const encoder = new TextEncoder(); const salt = new Uint8Array(32); // zero salt; real usage uses random const encKey = hkdf("SHA-256", sharedSecret, { salt, info: encoder.encode(`${context}:enc`), length: 32, }); const macKey = hkdf("SHA-256", sharedSecret, { salt, info: encoder.encode(`${context}:mac`), length: 32, }); return { encKey, macKey }; } const { encKey, macKey } = deriveKeyPair(new Uint8Array(32), "chat-session"); console.log(toHex(encKey)); console.log(toHex(macKey)); ``` ## API Reference ### `hkdf(algo: HashAlgorithm, ikm: Uint8Array, options: HkdfOptions): Uint8Array` Derives `options.length` bytes of key material from the input keying material `ikm` using the two-step HKDF-Extract-and-Expand procedure. | Parameter | Type | Description | |-----------|------|-------------| | `algo` | `HashAlgorithm` | Underlying hash: `"SHA-256"`, `"SHA-384"`, or `"SHA-512"` | | `ikm` | `Uint8Array` | Input keying material (e.g., DH shared secret) | | `options.salt` | `Uint8Array` | Optional salt bytes (use a random or domain-specific value) | | `options.info` | `Uint8Array` | Context and application-specific information | | `options.length` | `number` | Number of output bytes to derive | **Returns:** `Uint8Array` of `options.length` bytes. --- ### `HkdfOptions` ```ts interface HkdfOptions { readonly salt: Uint8Array; readonly info: Uint8Array; readonly length: number; } ``` ## Implementation Notes HKDF is defined in RFC 5869. The Extract step computes `PRK = HMAC(salt, ikm)`; the Expand step iterates `HMAC(PRK, info || counter)` until `length` bytes are produced. Both steps are performed by `@noble/hashes/hkdf` — no hand-rolled HMAC is involved here. The internal `hasherFor` helper is a private module function mapping `HashAlgorithm` strings to hash constructors; it is not exported. The maximum derivable length is `255 × hashLen`, which for SHA-256 is 8160 bytes — well within any practical keying requirement.