# hkdf.select _(no submodules)_ ## Purpose `hkdf.select.ts` is the build-time primitive selector for the HKDF implementation in `@suaveplan/crypto-hash`. It re-exports exactly one concrete backend — either `hkdf.noble.ts` (backed by `@noble/hashes`) or `hkdf.native.ts` — depending on the `hkdf` field in `crypto.config.ts`. HKDF (HMAC-based Extract-and-Expand Key Derivation Function, RFC 5869) is the standard KDF for deriving multiple independent keys from a single input keying material (IKM) such as a Diffie-Hellman shared secret or a session master secret. This selector exposes the `hkdf` function, `HkdfAlgorithm`, and `HkdfOptions` through a stable interface. ## Features - Re-exports `hkdf(algo, ikm, options)`, `HkdfAlgorithm`, and `HkdfOptions`. - Generated by `bun scripts/gen-crypto-selects.ts` — never hand-edited. - Controlled by `crypto.config.ts`: set `hkdf` to `'noble'` or `'native'`. - Supports SHA-256, SHA-384, and SHA-512 as the underlying PRF. - `HkdfOptions` carries `salt`, `info`, and `length` for Extract and Expand phases. ## Usage: Basic Example ```ts import { hkdf } from "@suaveplan/crypto-hash/primitives/hkdf/hkdf"; const ikm = new Uint8Array(32).fill(0xff); const key = hkdf("SHA-256", ikm, { salt: new Uint8Array(32), info: new TextEncoder().encode("session-key"), length: 32, }); console.log(key.length); // 32 ``` ## Usage: Advanced Example ```ts import { hkdf, type HkdfAlgorithm } from "@suaveplan/crypto-hash/primitives/hkdf/hkdf"; // Derive two independent sub-keys from one shared secret (X25519 output). function deriveKeys(sharedSecret: Uint8Array, salt: Uint8Array): { encKey: Uint8Array; authKey: Uint8Array; } { const enc = new TextEncoder(); return { encKey: hkdf("SHA-256", sharedSecret, { salt, info: enc.encode("enc-key"), length: 32, }), authKey: hkdf("SHA-256", sharedSecret, { salt, info: enc.encode("auth-key"), length: 32, }), }; } ``` ## API Reference Re-exports the following from the active implementation: ### `hkdf(algo: HkdfAlgorithm, ikm: Uint8Array, options: HkdfOptions): Uint8Array` Runs HKDF Extract followed by HKDF Expand. | Parameter | Type | Description | |-----------|------|-------------| | `algo` | `HkdfAlgorithm` | Hash algorithm for the internal HMAC. | | `ikm` | `Uint8Array` | Input keying material. | | `options.salt` | `Uint8Array` | Optional but strongly recommended random salt. | | `options.info` | `Uint8Array` | Context/application-specific binding string. | | `options.length` | `number` | Output length in bytes (max 255 × hash output length). | **Returns:** Derived key material of `options.length` bytes. ### `HkdfAlgorithm` ```ts type HkdfAlgorithm = "SHA-256" | "SHA-384" | "SHA-512"; ``` ### `HkdfOptions` ```ts interface HkdfOptions { readonly salt: Uint8Array; readonly info: Uint8Array; readonly length: number; } ``` ## Implementation Notes HKDF is a two-step process. Extract collapses potentially non-uniform IKM into a pseudorandom key (PRK) using HMAC with the salt. Expand stretches PRK into the requested number of output bytes by iterating HMAC with the info string. Noble's `hkdf` function implements RFC 5869 §2 exactly, including the `0x01`, `0x02`, … counter suffixes in the Expand loop. The `length` maximum per RFC 5869 is `255 * HashLen`; violations will cause Noble to throw, which propagates up without wrapping here — validation at the public KDF façade should guard against this before reaching the primitive. The native stub throws `PrimitiveNotImplemented("hkdf")`.