# primitives/crypto-auth _(no submodules)_ ## Purpose `cryptoAuth` and `cryptoAuthVerify` expose libsodium's `crypto_auth` and `crypto_auth_verify`, which implement a BLAKE2b-based message authentication code (MAC). Unlike HMAC-SHA256, this MAC is built on BLAKE2b — a fast, parallel, modern hash function with a wider security margin than HMAC-MD5 or HMAC-SHA1, and comparable to HMAC-SHA256/512. MACs are used to verify that a message was produced by a party holding the shared key and has not been tampered with in transit. They differ from signatures in that both parties must hold the same secret key; there is no separate verification key. ## Features - BLAKE2b-based MAC via `crypto_auth` — 32-byte output, 32-byte key. - Constant-time verification via `crypto_auth_verify` — resistant to timing-based MAC forgery. - `cryptoAuthVerify` returns `false` (never throws) for invalid MACs. - Async — calls `sodiumReady()` internally. - Deterministic — same key + message always produces the same MAC. ## Usage: Basic Example ```ts import { cryptoAuth, cryptoAuthVerify } from "@suaveplan/crypto-sodium/primitives/auth"; const key = crypto.getRandomValues(new Uint8Array(32)); const message = new TextEncoder().encode("verify this"); const mac = await cryptoAuth(key, message); const valid = await cryptoAuthVerify(key, message, mac); console.log(valid); // true ``` ## Usage: Advanced Example Authenticating API request payloads with a shared secret: ```ts import { cryptoAuth, cryptoAuthVerify } from "@suaveplan/crypto-sodium/primitives/auth"; const sharedKey = crypto.getRandomValues(new Uint8Array(32)); async function signPayload(payload: Uint8Array): Promise<{ payload: Uint8Array; mac: Uint8Array }> { const mac = await cryptoAuth(sharedKey, payload); return { payload, mac }; } async function verifyPayload(payload: Uint8Array, mac: Uint8Array): Promise { return cryptoAuthVerify(sharedKey, payload, mac); } const data = new TextEncoder().encode('{"action":"transfer","amount":100}'); const signed = await signPayload(data); const ok = await verifyPayload(signed.payload, signed.mac); ``` ## API Reference ### `cryptoAuth(key: Uint8Array, message: Uint8Array): Promise` Computes a 32-byte BLAKE2b MAC over `message` with `key`. **Parameters:** - `key` — 32-byte authentication key. - `message` — Arbitrary-length message bytes. **Returns:** `Promise` — 32-byte MAC. ### `cryptoAuthVerify(key: Uint8Array, message: Uint8Array, mac: Uint8Array): Promise` Verifies a MAC in constant time. **Parameters:** - `key` — 32-byte authentication key. - `message` — The message that was authenticated. - `mac` — 32-byte MAC to verify. **Returns:** `Promise` — `true` if valid, `false` otherwise. Never throws. ## Implementation Notes `crypto_auth_verify` from libsodium uses constant-time comparison to prevent timing side channels that would otherwise allow an attacker to iteratively learn the correct MAC byte by byte. The `try/catch` in `cryptoAuthVerify` catches structurally malformed inputs (e.g., wrong-length MAC) and maps them to `false` for consistency. Both functions are async solely because they call `sodiumReady()` — the underlying sodium operations are synchronous once the WASM is initialised.