Files
skills/docs/security-stack/crypto/crypto-hash/src/primitives/hkdf/hkdf.select/hkdf.select.md
2026-05-29 08:20:56 +01:00

3.6 KiB
Raw Blame History

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

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

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

type HkdfAlgorithm = "SHA-256" | "SHA-384" | "SHA-512";

HkdfOptions

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").