Password Hashing

PasswordHasher is the safe entry point for creating and verifying password records. It requires sensitive password input and normally requires an application key.

Storage Values and Verification

PasswordHash is an immutable, strictly parsed storage value. PasswordVerification reports an explicit accepted or rejected state and can carry a replacement record after a successful migration. See Storing and Verifying Passwords for the complete workflow.

Policies and Keys

PasswordHashPolicy provides reviewed Argon2id and scrypt presets. PasswordHashKey holds the application pepper and can carry a public identifier for rotation. See Supported Password Hashing Algorithms for construction details, parameters, and migration policy.

Interface

class PasswordHash

An immutable canonical password-hash record suitable for database or configuration storage.

The default value is an invalid sentinel and is safe to use for malformed records and unknown users.

See: Password Hashing

Public Functions

inline bool isValid() const noexcept

Test whether this value contains a valid parsed record.

bool isKeyed() const noexcept

Test whether the record uses an application key.

PasswordHashAlgorithm algorithm() const

Get the stored algorithm.

Throws:

err::LogicError – If this is the invalid sentinel.

std::optional<text::String> keyIdentifier() const noexcept

Get the public key identifier, if the keyed record has one.

text::String toString() const

Return the canonical storage representation, or an empty string for the invalid sentinel.

Public Static Functions

static PasswordHash fromString(const text::String &text) noexcept

Parse a strict canonical record, returning the invalid sentinel on any error.

Parameters:

text – The storage record.

Returns:

The parsed record, or the invalid sentinel.

static PasswordHash fromStringOrThrow(const text::String &text)

Parse a strict canonical record.

Parameters:

text – The storage record.

Throws:

err::ParseError – If the record is malformed, noncanonical, unsupported, or exceeds resource limits.

Returns:

The parsed record.

class PasswordHashAlgorithm

A password hashing algorithm supported by PasswordHasher.

See: Password Hashing

Public Types

enum Value

The raw password-hashing algorithm value.

Values:

enumerator Argon2id

Argon2id version 1.3.

enumerator Scrypt

scrypt as specified in RFC 7914.

Public Functions

constexpr PasswordHashAlgorithm() noexcept = default

Create the default Argon2id algorithm.

inline constexpr PasswordHashAlgorithm(const Value value) noexcept

Create an algorithm from its raw value.

Parameters:

value – The raw algorithm value.

inline constexpr Value toRawValue() const noexcept

Get the raw algorithm value.

text::String toString() const

Convert the algorithm to its stable lowercase identifier.

Public Static Functions

static std::optional<PasswordHashAlgorithm> fromString(const text::String &text) noexcept

Parse an exact lowercase algorithm identifier.

Parameters:

text – The identifier to parse.

Returns:

The matching algorithm, or no value for unsupported text.

class PasswordHasher

The safe password hashing and verification API.

Normal construction requires an application key. Mark password strings as sensitive whenever practical.

See: Password Hashing

Public Functions

explicit PasswordHasher(PasswordHashKey key, PasswordHashPolicy policy = PasswordHashPolicy::recommended())

Create a keyed password hasher.

Parameters:
  • key – The active application key.

  • policy – The password-hashing policy.

explicit PasswordHasher(unsafe::UnsafeNoPasswordHashKey acknowledgement, PasswordHashPolicy policy = PasswordHashPolicy::recommended())

Create an explicitly unkeyed password hasher.

Parameters:
  • acknowledgement – The explicit acknowledgement of reduced protection.

  • policy – The password-hashing policy.

PasswordHash hash(const text::String &password) const

Hash a password with a fresh 16-byte salt from application().secureRandom().

Empty passwords are accepted. Inputs larger than 1 MiB are rejected.

Parameters:

password – The UTF-8 password. Sensitive marking is recommended but not required.

Throws:

err::ParameterError – If the password exceeds 1 MiB of UTF-8 data.

Returns:

The canonical password-hash record.

PasswordVerification verify(const text::String &password, const PasswordHash &storedHash) const

Verify a password and report an optional replacement hash.

Malformed/invalid records and unavailable keys run a dummy current-policy derivation before rejection.

Parameters:
  • password – The UTF-8 password. Sensitive marking is recommended but not required.

  • storedHash – The stored canonical password-hash record.

Returns:

The explicit accepted or rejected result.

inline const PasswordHashPolicy &policy() const noexcept

Get the active password-hashing policy.

Public Static Functions

static auto withKeyRotation(PasswordHashKey activeKey, util::List<PasswordHashKey> fallbackKeys, PasswordHashPolicy policy = PasswordHashPolicy::recommended()) -> PasswordHasher

Create a keyed hasher with fallback keys for rotation.

The active key must be identified. Fallback identifiers must be unique; at most one fallback may be unnamed.

Parameters:
  • activeKey – The identified key used for new records.

  • fallbackKeys – The legacy keys accepted during verification.

  • policy – The password-hashing policy.

Throws:

err::ParameterError – If the rotation set is ambiguous.

Returns:

The configured password hasher.

class PasswordHashKey

A system/application key used as a password-hash pepper.

Key material must contain at least 32 bytes. Keep it outside the password database, preferably in a secret manager or operating-system protected key store.

See: Password Hashing

Public Functions

explicit PasswordHashKey(mem::ByteBlock key)

Create the normal unnamed application key.

The key’s shared allocation is marked as sensitive by this constructor.

Parameters:

key – The application-key material.

Throws:

err::ParameterError – If the key contains fewer than 32 bytes.

inline bool isIdentified() const noexcept

Test whether this key has a public rotation identifier.

inline const std::optional<text::String> &identifier() const noexcept

Get the public rotation identifier, if present.

Public Static Functions

static PasswordHashKey identified(text::String identifier, mem::ByteBlock key)

Create an identified key for rotation.

Identifiers contain 1-32 characters from ASCII letters, digits, ., _, and -.

Parameters:
  • identifier – The public rotation identifier.

  • key – The application-key material, marked as sensitive by the resulting key.

Throws:

err::ParameterError – If the key or identifier is invalid.

Returns:

The identified key.

class PasswordHashPolicy

A reviewed password-hashing policy.

Safe presets always use a 16-byte salt and a 32-byte raw output.

See: Password Hashing

Public Functions

PasswordHashPolicy() noexcept

Create the recommended Argon2id policy.

explicit PasswordHashPolicy(const unsafe::UnsafeCustomPasswordHashParameters &parameters) noexcept

Create a checked custom policy through the explicitly unsafe parameter API.

Parameters:

parameters – The checked algorithm-specific costs.

bool isEqualTo(const PasswordHashPolicy &other) const noexcept

Test whether all algorithm and cost parameters match another policy.

inline PasswordHashAlgorithm algorithm() const noexcept

Get the password-hashing algorithm.

inline unit::ByteLength saltLength() const noexcept

Get the salt length.

inline unit::ByteLength outputLength() const noexcept

Get the derived-output length.

inline uint32_t memoryKiB() const noexcept

Get the Argon2id memory cost in kibibytes.

inline uint32_t passes() const noexcept

Get the Argon2id pass count.

inline uint32_t lanes() const noexcept

Get the Argon2id lane count.

inline uint64_t scryptCost() const noexcept

Get the scrypt CPU/memory cost parameter.

inline uint32_t scryptBlockSize() const noexcept

Get the scrypt block-size parameter.

inline uint32_t scryptParallelization() const noexcept

Get the scrypt parallelization parameter.

Public Static Functions

static PasswordHashPolicy recommended() noexcept

Argon2id with 64 MiB, three passes, and four lanes.

static PasswordHashPolicy lowMemory() noexcept

Argon2id with 19 MiB, two passes, and one lane.

static PasswordHashPolicy scrypt() noexcept

scrypt with N=2^17, r=8, and p=1.

class PasswordVerification

The explicit result of password verification.

This type deliberately has no boolean conversion, so callers must name the accepted/rejected state. An accepted result can carry a replacement hash that must be persisted after a successful migration.

See: Password Hashing

Public Functions

inline bool isAccepted() const noexcept

Test whether the password was accepted.

inline bool isRejected() const noexcept

Test whether the password was rejected.

inline const std::optional<PasswordHash> &replacementHash() const noexcept

Get the replacement hash required after an accepted migration.

class UnsafeCustomPasswordHashParameters

Explicit access to custom password-hashing costs.

Prefer the reviewed PasswordHashPolicy presets. Custom values are checked against hard safety limits, but can still be too cheap for a real deployment.

See: Password Hashing

Public Static Functions

static UnsafeCustomPasswordHashParameters argon2id(uint32_t memoryKiB, uint32_t passes, uint32_t lanes)

Create checked custom Argon2id parameters.

Parameters:
  • memoryKiB – The memory cost in kibibytes.

  • passes – The pass count.

  • lanes – The parallel lane count.

Throws:

err::ParameterError – If a value is outside the implementation’s safety limits.

Returns:

The validated custom parameters.

static UnsafeCustomPasswordHashParameters scrypt(uint64_t cost, uint32_t blockSize, uint32_t parallelization)

Create checked custom scrypt parameters.

Parameters:
  • cost – The CPU/memory cost parameter, which must be a power of two.

  • blockSize – The block-size parameter.

  • parallelization – The parallelization parameter.

Throws:

err::ParameterError – If a value is outside the implementation’s safety limits.

Returns:

The validated custom parameters.

class UnsafeNoPasswordHashKey

An explicit acknowledgement that password hashes will be stored without an application pepper.

See: Password Hashing

Public Static Functions

static inline constexpr UnsafeNoPasswordHashKey acknowledgeRisk() noexcept

Explicitly acknowledge the reduced protection.