# hmac.select _(no submodules)_ ## Purpose `hmac.select.ts` is the build-time primitive selector for the HMAC implementation within `@suaveplan/crypto-hash`. It re-exports exactly one concrete backend — either `hmac.noble.ts` (backed by `@noble/hashes`) or `hmac.native.ts` — according to the `hmac` entry in `crypto.config.ts`. HMAC (Hash-based Message Authentication Code, RFC 2104) is the standard construction for producing a keyed digest from an arbitrary hash function. This selector exposes a single `hmac` function and the `HmacAlgorithm` type, providing a consistent interface regardless of which backend is active. ## Features - Single-symbol re-export of `hmac(algo, key, data)` and `HmacAlgorithm`. - Generated by `bun scripts/gen-crypto-selects.ts` — never hand-edited. - Controlled by `crypto.config.ts`: set `hmac` to `'noble'` or `'native'`. - Supports `"SHA-256"`, `"SHA-384"`, and `"SHA-512"` hash algorithms. - Maintains a stable public API across backend switches. ## Usage: Basic Example ```ts import { hmac } from "@suaveplan/crypto-hash/primitives/hmac/hmac"; const key = new Uint8Array(32).fill(0xab); const data = new TextEncoder().encode("authenticate me"); const tag = hmac("SHA-256", key, data); console.log(tag.length); // 32 ``` ## Usage: Advanced Example ```ts import { hmac, type HmacAlgorithm } from "@suaveplan/crypto-hash/primitives/hmac/hmac"; // Verify a webhook signature from an untrusted header. function verifyWebhookSignature( algo: HmacAlgorithm, secret: Uint8Array, body: Uint8Array, expected: Uint8Array ): boolean { const computed = hmac(algo, secret, body); // Constant-time comparison avoids timing side-channels. if (computed.length !== expected.length) return false; let diff = 0; for (let i = 0; i < computed.length; i++) diff |= computed[i] ^ expected[i]; return diff === 0; } ``` ## API Reference Re-exports the following from the active implementation: ### `hmac(algo: HmacAlgorithm, key: Uint8Array, data: Uint8Array): Uint8Array` Computes HMAC over `data` with `key` using the specified hash algorithm. | Parameter | Type | Description | |-----------|------|-------------| | `algo` | `HmacAlgorithm` | `"SHA-256"`, `"SHA-384"`, or `"SHA-512"`. | | `key` | `Uint8Array` | Secret key bytes (any length). | | `data` | `Uint8Array` | Message to authenticate. | **Returns:** HMAC tag — 32 bytes for SHA-256, 48 for SHA-384, 64 for SHA-512. ### `HmacAlgorithm` ```ts type HmacAlgorithm = "SHA-256" | "SHA-384" | "SHA-512"; ``` ## Implementation Notes HMAC is defined as `H(K XOR opad || H(K XOR ipad || message))`. The Noble backend calls `@noble/hashes/hmac` directly, which implements this construction on top of the same audited SHA-2 primitives used by the standalone hash functions. Key padding and the inner/outer hash passes are handled internally. RFC 2202 (SHA-256) and RFC 4231 (SHA-384/512) test vectors pass in the test suite. The native stub throws `PrimitiveNotImplemented("hmac")` and will be activated in Phase 3 after per-primitive audit.