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

5.0 KiB

argon2id

(no submodules)

Purpose

Provides Argon2id password hashing as specified in RFC 9106. Argon2id is the current winner of the Password Hashing Competition and is recommended by OWASP for new applications. It is resistant to both GPU-based brute force (via high memory cost) and time-memory trade-off attacks (via the hybrid id variant). This module enforces non-pathological lower bounds on all four tuning parameters and produces a structured HashError with per-field context when they are violated, making it safe for frameworks to call without a separate validation layer.

Features

  • argon2id(password, options) — Argon2id key derivation
  • Exported constants: ARGON2ID_MIN_MEMORY_COST_KIB, ARGON2ID_MIN_TIME_COST, ARGON2ID_MIN_PARALLELISM
  • Validates each parameter individually; error context includes { field, value, minimum }
  • Throws HashError("HASH.KDF.INVALID_PARAMS") for any out-of-range parameter
  • Deterministic: same inputs always produce the same hash output

Usage: Basic Example

import { argon2id, ARGON2ID_MIN_MEMORY_COST_KIB } from "@suaveplan/crypto-hash/kdf";

const encoder  = new TextEncoder();
const password = encoder.encode("hunter2");
const salt     = new Uint8Array(16); // use crypto.getRandomValues in production

const hash = argon2id(password, {
    salt,
    timeCost: 3,
    memoryCost: ARGON2ID_MIN_MEMORY_COST_KIB * 1024, // 8 MiB in KiB
    parallelism: 1,
    length: 32,
});
console.log(hash.length); // 32

Usage: Advanced Example

import {
    argon2id,
    ARGON2ID_MIN_MEMORY_COST_KIB,
    ARGON2ID_MIN_TIME_COST,
    ARGON2ID_MIN_PARALLELISM,
} from "@suaveplan/crypto-hash/kdf";
import { toHex } from "@suaveplan/crypto-hash/encoding";
import { HashError } from "@suaveplan/crypto-hash/errors";

interface PasswordHashConfig {
    timeCost: number;
    memoryCostKib: number;
    parallelism: number;
    outputBytes: number;
}

function hashPassword(password: string, salt: Uint8Array, cfg: PasswordHashConfig): string {
    try {
        const raw = argon2id(new TextEncoder().encode(password), {
            salt,
            timeCost: cfg.timeCost,
            memoryCost: cfg.memoryCostKib,
            parallelism: cfg.parallelism,
            length: cfg.outputBytes,
        });
        return toHex(raw);
    } catch (err) {
        if (err instanceof HashError && err.context?.field) {
            throw new RangeError(
                `Argon2id parameter out of range: ${err.context.field} = ${err.context.value} ` +
                `(minimum: ${err.context.minimum})`
            );
        }
        throw err;
    }
}

const salt = new Uint8Array(16);
const hex = hashPassword("secure-password", salt, {
    timeCost: ARGON2ID_MIN_TIME_COST,
    memoryCostKib: ARGON2ID_MIN_MEMORY_COST_KIB,
    parallelism: ARGON2ID_MIN_PARALLELISM,
    outputBytes: 32,
});
console.log(hex.length); // 64 hex chars = 32 bytes

API Reference

argon2id(password: Uint8Array, options: Argon2idOptions): Uint8Array

Derives options.length bytes from password using Argon2id.

Parameter Type Description
password Uint8Array User-supplied password bytes
options.salt Uint8Array Per-credential random salt (≥ 16 bytes recommended)
options.timeCost number Integer ≥ ARGON2ID_MIN_TIME_COST (number of iterations)
options.memoryCost number Integer ≥ ARGON2ID_MIN_MEMORY_COST_KIB (in KiB)
options.parallelism number Integer ≥ ARGON2ID_MIN_PARALLELISM (lane count)
options.length number Positive integer byte count for derived output

Returns: Uint8Array of options.length bytes.

Throws: HashError("HASH.KDF.INVALID_PARAMS") for any validation failure. Error context contains { field: string, value: number, minimum: number }.


ARGON2ID_MIN_MEMORY_COST_KIB = 8

Minimum memory cost in KiB. Based on RFC 9106 §4 minimum recommendation.

ARGON2ID_MIN_TIME_COST = 1

Minimum number of Argon2id iterations. Lower values are pathological.

ARGON2ID_MIN_PARALLELISM = 1

Minimum lane count. Lower values are rejected as invalid.


Argon2idOptions

interface Argon2idOptions {
    readonly salt: Uint8Array;
    readonly timeCost: number;
    readonly memoryCost: number;
    readonly parallelism: number;
    readonly length: number;
}

Implementation Notes

Parameters are validated in order: timeCost, memoryCost, parallelism, length. The first failing field short-circuits and throws with that field's context — no partial execution occurs. The implementation delegates to @noble/hashes/argon2 which is a pure-JavaScript Argon2id implementation reviewed by the cryptographic community. Argon2id does not use the HashAlgorithm dispatch pattern used by hmac, hkdf, and pbkdf2 — Argon2id's internal structure is fixed and parameterised by t, m, and p rather than a hash constructor. For this reason, argon2id.ts does not import from mac/hmac.ts.