Argon2 0.1.2-preview

This is a prerelease version of Argon2.
dotnet add package Argon2 --version 0.1.2-preview
                    
NuGet\Install-Package Argon2 -Version 0.1.2-preview
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Argon2" Version="0.1.2-preview" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Argon2" Version="0.1.2-preview" />
                    
Directory.Packages.props
<PackageReference Include="Argon2" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Argon2 --version 0.1.2-preview
                    
#r "nuget: Argon2, 0.1.2-preview"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Argon2@0.1.2-preview
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Argon2&version=0.1.2-preview&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Argon2&version=0.1.2-preview&prerelease
                    
Install as a Cake Tool

Argon2

A from-scratch C# implementation of the Argon2 password-hashing function (RFC 9106, version 1.3). All three variants are supported: Argon2d, Argon2i, and Argon2id.

Overview

Argon2 is the winner of the 2015 Password Hashing Competition and is the recommended password hashing scheme by OWASP. This library implements Argon2 directly from RFC 9106 without wrapping a native binary.

  • Managed C# only. No P/Invoke, no unmanaged DLLs.
  • Targets net10.0.
  • Cross-validated against Konscious, Isopoh, and RustCrypto.
  • PHC-string output compatible with other Argon2 implementations.

Status

Pre-release (0.1.0-preview). The implementation is a port of the audited RustCrypto argon2 crate. It passes the RFC 9106 §5 test vectors and more than 450 cross-validation samples drawn from three independent Argon2 libraries (Konscious, Isopoh, RustCrypto). See SECURITY.md and the Security Disclaimers section below.

Installation

dotnet add package Authaz.Argon2 --prerelease

All public types live in the flat Authaz.Argon2 namespace; a single using Authaz.Argon2; brings the whole API into scope.

Quick Start

Argon2Phc picks OWASP-recommended parameters (Argon2id, m=64 MiB, t=3, p=4, 32-byte tag) and generates a fresh 16-byte salt via RandomNumberGenerator. The returned string is in PHC format and contains everything Verify needs.

using Authaz.Argon2;

string phc = Argon2Phc.HashToString("hunter2"u8);
// phc looks like: "$argon2id$v=19$m=65536,t=3,p=4$<salt>$<hash>"

bool ok = Argon2Phc.Verify("hunter2"u8, phc);

Verify uses CryptographicOperations.FixedTimeEquals for the final tag comparison.

Raw bytes (custom parameters / custom salt)

For direct control over parameters, salt, and output length, use Argon2Context directly:

using Authaz.Argon2;

var parameters = new Argon2Parameters(
    memoryCost: 65536,   // 64 MiB (in KiB)
    timeCost: 3,
    parallelism: 4,
    outputLength: 32);

var ctx = new Argon2Context(Argon2Variant.Argon2id, parameters);

Span<byte> hash = stackalloc byte[32];
ctx.HashPasswordInto("hunter2"u8, "sixteen_byte_sal"u8, hash);

A secret key (sometimes called a "pepper") and associated data can also be supplied:

byte[] pepper = Convert.FromHexString("aabbccddeeff11223344556677889900");
byte[] ad     = "tenant-a"u8.ToArray();

var parameters = new Argon2Parameters(
    memoryCost: 65536, timeCost: 3, parallelism: 4, outputLength: 32,
    associatedData: ad);

var ctx = new Argon2Context(Argon2Variant.Argon2id, parameters, secret: pepper);

API Reference

All public types live in the Authaz.Argon2 namespace. A single using Authaz.Argon2; brings the whole API into scope.

Core types

  • Argon2VariantArgon2d, Argon2i, Argon2id.
  • Argon2VersionV1_3 (0x13). V1_0 is defined but rejected by Argon2Context.
  • Argon2Parameters(uint memoryCost, uint timeCost, uint parallelism, uint outputLength, ReadOnlyMemory<byte> associatedData = default) — validates that p >= 1, m >= 8*p, t >= 1, and tau >= 4. Exposes derived quantities ActualMemoryBlocks, LaneLength, and SegmentLength.
  • Argon2Context(Argon2Variant, Argon2Parameters, ReadOnlyMemory<byte> secret = default, Argon2Version version = V1_3) — throws NotSupportedException for anything other than version 1.3.
  • Argon2Context.HashPasswordInto(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, Span<byte> output) — writes exactly Parameters.OutputLength bytes. Salt must be at least 8 bytes (RFC 9106 §3.1).

PHC helpers

  • Argon2Phc.HashToString(ReadOnlySpan<byte> password) — uses OWASP defaults and a CSPRNG-generated salt.
  • Argon2Phc.HashToString(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, Argon2Variant variant, Argon2Parameters parameters) — explicit form.
  • Argon2Phc.Verify(ReadOnlySpan<byte> password, string phcString) — uses CryptographicOperations.FixedTimeEquals for the tag comparison. See Security Disclaimers for caveats.

Security Disclaimers

This library is a port of the audited RustCrypto argon2 crate, cross-validated against three independent implementations, but the C# port itself has not been independently audited. Please read these caveats carefully before using it for anything that matters.

  • Port, not an independent audit. The algorithm is a direct port of a reviewed implementation, and the output is byte-equal against Konscious, Isopoh, and RustCrypto across 450+ samples. That is strong correctness evidence — not a substitute for a professional review of the C# source and JIT-emitted code.
  • Constant-time best-effort only. We avoid obvious branches on secret data, but this implementation has not been audited for timing side-channels in the JIT's emitted code. RyuJIT may introduce data-dependent branches or variable-latency instructions that a pure-source review would not catch.
  • Memory zeroization is partial. We explicitly zero sensitive buffers (initial hash H0, intermediate tag buffers, and the memory matrix) using CryptographicOperations.ZeroMemory. However, the .NET GC can move managed arrays during compaction; copies left in old heap regions are not cleared. Threat models that require strict memory hygiene should not rely on C# for this.
  • No FIPS-140 claims. This library is not FIPS-validated.
  • Version 1.3 only. Argon2 v1.0 is intentionally rejected with NotSupportedException; do not use it anyway.

If you find a security issue, see SECURITY.md for how to report it.

Testing

The solution ships with two test projects:

dotnet test Argon2.sln

To collect merged coverage for the production assembly only (src/Authaz.Argon2), use the checked-in Coverlet settings and the local reportgenerator tool manifest:

dotnet tool restore
dotnet test Argon2.sln --settings coverage.runsettings --collect:"XPlat Code Coverage" --results-directory artifacts/coverage/raw
dotnet tool run reportgenerator "-reports:artifacts/coverage/raw/**/coverage.cobertura.xml" "-targetdir:artifacts/coverage/report" "-reporttypes:HtmlSummary;TextSummary"
cat artifacts/coverage/report/Summary.txt

coverage.runsettings limits collection to the Authaz.Argon2 production assembly so the final percentages are not diluted by test code or generated test-host code.

  • Authaz.Argon2.Tests — RFC 9106 §5.1/5.2/5.3 vectors, unit tests for BLAKE2b, H', indexing, Argon2i address generator, and fill, plus PHC string parse/format, PHC base64, and FsCheck property tests (determinism, avalanche, output length, variant distinctness, PHC round-trip).
  • Authaz.Argon2.CrossValidation.Tests — parity runs against Konscious (100 samples × 3 variants, variable tag length, secret, AD), Isopoh (50 samples × 3 variants + PHC-string round-trip), and 12 RustCrypto-extracted vectors.

171 tests total.

License

MIT. See LICENSE.

Acknowledgements

  • RFC 9106, Biryukov, Dinu, Khovratovich, and Josefsson.
  • The Konscious, Isopoh, and RustCrypto maintainers, whose implementations were used as oracles for cross-validation.
  • The PHC-format specification maintained at P-H-C/phc-string-format.
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.2-preview 131 4/17/2026