Table of Contents

Argon2 Class

Definition

Namespace
Bodu.Security.Cryptography
Assembly
Bodu.Security.Cryptography.dll
Package
Bodu.Security.Cryptography 1.2.0
Source
Argon2.cs

Provides the shared base for the Argon2 password-hashing and key-derivation functions defined by RFC 9106. The concrete variants are Argon2d, Argon2i, and Argon2id.

public abstract class Argon2
Inheritance
Argon2
Derived
Inherited Members
Extension Methods

Remarks

Argon2 is a memory-hard function designed to make password cracking expensive on parallel hardware. An instance binds a set of cost Argon2Parameters (memory, iterations, parallelism, and tag length) once, then derives keys or password hashes from a password and salt. Cross-variant verification of a PHC encoded string is available through the static Verify(string, ReadOnlySpan<byte>) method, which dispatches to the variant named in the string.

A derivation fills its lanes on several threads when that pays: up to Parallelism threads, bounded by the processor count, once each lane's share of a pass is large enough to be worth dividing (from 768 KiB). The calling thread always takes part, so a derivation never waits on an idle thread pool, and the tag never depends on the threads used. MaxDegreeOfParallelism bounds a derivation's threads for callers that already run many derivations at once.

The memory matrix is held in native memory and reused across derivations, so a derivation neither allocates it on the collected heap nor waits for it to be zeroed. Up to one matrix per processor stays reserved - cleared - for up to thirty seconds after the last derivation; the Bodu.Security.Cryptography.Argon2.DisableMatrixReuse AppContext switch releases each matrix as soon as its derivation ends instead. Every block of the matrix and every buffer holding a password-derived value is cleared before it is released; values the JIT keeps in registers or its own stack slots are beyond the library's reach.

This implementation is not independently audited and offers best-effort, not guaranteed, side-channel resistance.

Constructors

Argon2(Argon2Parameters)

Initializes a new instance of the Argon2 class with the specified cost parameters.

protected Argon2(Argon2Parameters parameters)

Parameters

parameters Argon2Parameters

The cost and auxiliary parameters governing the derivation.

Exceptions

ArgumentNullException

parameters is null.

ArgumentOutOfRangeException

A cost parameter in parameters falls outside the range permitted by RFC 9106.

ArgumentException

The version code in parameters is neither 0x10 nor 0x13.

Properties

MaxDegreeOfParallelism

Gets the greatest number of threads one derivation by this instance may use, the calling thread included.

public int MaxDegreeOfParallelism { get; }

Property Value

int

-1, the default, when the library chooses: up to Parallelism threads, bounded by the processor count, when the lanes are large enough to be worth dividing. 1 confines every derivation to the calling thread; a larger value bounds the threads. A derivation never uses more threads than it has lanes, and the tag never depends on this value.

Parameters

Gets the cost and auxiliary parameters bound to this instance.

public Argon2Parameters Parameters { get; }

Property Value

Argon2Parameters

The Argon2Parameters supplied at construction.

Methods

DeriveKey(ReadOnlySpan<byte>, ReadOnlySpan<byte>, Span<byte>)

Derives a tag into the supplied destination buffer.

public void DeriveKey(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, Span<byte> destination)

Parameters

password ReadOnlySpan<byte>

The password / message to derive from.

salt ReadOnlySpan<byte>

The salt; must be at least 8 bytes.

destination Span<byte>

The buffer to receive the tag; its length must equal the configured tag length.

Exceptions

ArgumentException

salt is shorter than 8 bytes, or destination does not have the configured tag length.

GetBytes(ReadOnlySpan<byte>, ReadOnlySpan<byte>)

Derives a tag of the configured TagLength from the supplied password and salt.

public byte[] GetBytes(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt)

Parameters

password ReadOnlySpan<byte>

The password / message to derive from.

salt ReadOnlySpan<byte>

The salt; must be at least 8 bytes.

Returns

byte[]

The derived tag.

Exceptions

ArgumentException

salt is shorter than 8 bytes.

Hash(ReadOnlySpan<byte>)

Derives a tag from the password and a freshly generated random 16-byte salt and returns the result as a PHC encoded-hash string.

public string Hash(ReadOnlySpan<byte> password)

Parameters

password ReadOnlySpan<byte>

The password to hash.

Returns

string

The PHC encoded-hash string, including the generated salt.

Hash(ReadOnlySpan<byte>, ReadOnlySpan<byte>)

Derives a tag from the password and the supplied salt and returns the result as a PHC encoded-hash string.

public string Hash(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt)

Parameters

password ReadOnlySpan<byte>

The password to hash.

salt ReadOnlySpan<byte>

The salt to embed in the encoded string; must be at least 8 bytes.

Returns

string

The PHC encoded-hash string.

Exceptions

ArgumentException

salt is shorter than 8 bytes.

Verify(string, ReadOnlySpan<byte>)

Verifies a password against an Argon2 PHC encoded-hash string, dispatching to the variant named in the string.

public static bool Verify(string encoded, ReadOnlySpan<byte> password)

Parameters

encoded string

The PHC encoded-hash string produced by an Argon2 variant.

password ReadOnlySpan<byte>

The password to verify.

Returns

bool

true if the password matches the encoded hash; otherwise, false.

Remarks

This overload supplies no secret key. Hashes produced with an Secret must be verified through Verify(string, ReadOnlySpan<byte>, ReadOnlySpan<byte>).

Exceptions

ArgumentNullException

encoded is null.

FormatException

encoded is not a well-formed Argon2 PHC string.

Verify(string, ReadOnlySpan<byte>, ReadOnlySpan<byte>)

Verifies a password against an Argon2 PHC encoded-hash string using the supplied secret key.

public static bool Verify(string encoded, ReadOnlySpan<byte> password, ReadOnlySpan<byte> secret)

Parameters

encoded string

The PHC encoded-hash string produced by an Argon2 variant.

password ReadOnlySpan<byte>

The password to verify.

secret ReadOnlySpan<byte>

The secret key (pepper) used when the hash was produced; empty when none was used.

Returns

bool

true if the password matches the encoded hash; otherwise, false.

Exceptions

ArgumentNullException

encoded is null.

FormatException

encoded is not a well-formed Argon2 PHC string.

Verify(string, ReadOnlySpan<byte>, ReadOnlySpan<byte>, int)

Verifies a password against an Argon2 PHC encoded-hash string using the supplied secret key, with a bound on the threads the derivation may use.

public static bool Verify(string encoded, ReadOnlySpan<byte> password, ReadOnlySpan<byte> secret, int maxDegreeOfParallelism)

Parameters

encoded string

The PHC encoded-hash string produced by an Argon2 variant.

password ReadOnlySpan<byte>

The password to verify.

secret ReadOnlySpan<byte>

The secret key (pepper) used when the hash was produced; empty when none was used.

maxDegreeOfParallelism int

The greatest number of threads the derivation may use, the calling thread included; -1 lets the library choose.

Returns

bool

true if the password matches the encoded hash; otherwise, false.

Remarks

The bound serves a service that verifies many passwords at once and gains nothing when each derivation spreads across every core. The result never depends on it.

Exceptions

ArgumentNullException

encoded is null.

ArgumentOutOfRangeException

maxDegreeOfParallelism is zero or less than -1.

FormatException

encoded is not a well-formed Argon2 PHC string.

Applies to

ProductVersions
.NET8, 10