Table of Contents

ASCON hashing - AsconHash256 and AsconHashA256

ASCON-HASH256 and ASCON-HASHA256 are the two fixed-output hash algorithms in the ASCON family, standardized in NIST SP 800-232. Both are sponge constructions built on a 320-bit internal state with an 8-byte (64-bit) absorption rate, and both produce a 256-bit (32-byte) digest. The family was designed for constrained hardware - but the same properties that make it attractive there (compact state, simple round function, well-studied security margin) make it a sound choice in software as well.

Bodu.Security.Cryptography ships two concrete types:

Type Algorithm name Absorption rounds Squeeze rounds Characteristics
AsconHash256 ASCON-HASH256 12 (Ascon-p12) 12 Maximum security margin - the conservative default.
AsconHashA256 ASCON-HASHA256 8 (Ascon-p8) 12 Higher throughput - reduced, but still substantial, absorption-phase margin.

Both derive from AsconHash, which sits on BlockHashAlgorithm and, through it, on HashAlgorithm, so they slot into any API that accepts a standard .NET hash algorithm.

Fixed parameters at a glance

Parameter Value Notes
State size 320 bits (40 bytes) Fixed by the ASCON specification.
Rate (absorption block) 64 bits (8 bytes) Bytes consumed per permutation call.
Output 256 bits (32 bytes) Fixed; no truncation variants.
Absorption rounds - AsconHash256 12 per block Conservative margin throughout.
Absorption rounds - AsconHashA256 8 per block Reduced absorption work; squeeze unchanged.

Pattern 1 - one-shot hash with ASCON-HASH256

AsconHash256 is the conservative choice. It uses 12 permutation rounds at every stage, giving the widest cryptanalytic margin in the family.

using System.Text;
using Bodu.Security.Cryptography;

byte[] data    = Encoding.UTF8.GetBytes("the quick brown fox");
using var hash = new AsconHash256();
byte[] digest  = hash.ComputeHash(data);    // 32 bytes
string hex     = Convert.ToHexString(digest);

CanReuseTransform is true on both types, so the same instance can hash multiple independent messages without being recreated - ComputeHash resets the state automatically.

Pattern 2 - ASCON-HASHA256 for throughput-sensitive paths

AsconHashA256 uses 8 permutation rounds per absorbed block instead of 12. The API is identical; only the round count (and therefore the throughput and absorption-phase margin) differs.

using System.Text;
using Bodu.Security.Cryptography;

byte[] data    = Encoding.UTF8.GetBytes("the quick brown fox");
using var hash = new AsconHashA256();
byte[] digest  = hash.ComputeHash(data);

AlgorithmName reports "ASCON-HASHA256" automatically, so logs and manifests carry the variant name without any extra bookkeeping.

Pattern 3 - choosing between the two variants

Both variants share the same state size, output width, padding rule, and API shape. The only difference is the number of Ascon-p rounds applied per absorbed 8-byte block.

using Bodu.Security.Cryptography;

// Conservative - 12 absorption rounds.
// Prefer for signatures, long-lived commitments, content-addressing,
// or wherever throughput is not the primary constraint.
using var conservative = new AsconHash256();

// Performance - 8 absorption rounds.
// Prefer when hashing many inputs in a hot path (deduplication,
// per-request cache-key generation) and the throughput difference matters.
using var performance = new AsconHashA256();

Console.WriteLine(conservative.AlgorithmName);    // "ASCON-HASH256"
Console.WriteLine(performance.AlgorithmName);     // "ASCON-HASHA256"

The 12-round variant applies 50 % more permutation work per absorbed block, giving deeper cryptanalytic margin. The 8-round variant reduces absorption work in exchange for higher throughput; the squeeze phase retains 12 rounds in both cases, so finalization is equally strong in both variants.

When in doubt, use AsconHash256. Switch to AsconHashA256 only when profiling shows the difference is measurable in your workload.

Pattern 4 - streaming a file

Both types inherit ComputeHash(Stream) from HashAlgorithm:

using Bodu.Security.Cryptography;

using var hash   = new AsconHash256();
using var stream = File.OpenRead("document.pdf");
byte[]    digest = hash.ComputeHash(stream);

For a block-by-block pipeline, drive the standard BCL TransformBlock / TransformFinalBlock contract directly:

using Bodu.Security.Cryptography;

using var hash   = new AsconHash256();
byte[]    buffer = new byte[8192];
int       read;

using (var stream = File.OpenRead("document.pdf"))
{
    while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
        hash.TransformBlock(buffer, 0, read, null, 0);
}

hash.TransformFinalBlock([], 0, 0);
byte[] digest = hash.Hash!;

CanReuseTransform being true means the instance resets automatically at the next ComputeHash call, or you can call Initialize() explicitly between messages.

Pattern 5 - hashing multiple messages with one instance

Because CanReuseTransform is true, a single instance can be reused across a batch:

using Bodu.Security.Cryptography;

byte[][] messages = GetMessageBatch();
byte[][] digests  = new byte[messages.Length][];

using var hash = new AsconHash256();
for (int i = 0; i < messages.Length; i++)
    digests[i] = hash.ComputeHash(messages[i]);

Each ComputeHash call resets the internal state before processing the next message.

Pattern 6 - verifying a digest in constant time

Always compare digests in constant time. Use the BCL's CryptographicOperations.FixedTimeEquals directly, or the VerifyHash extension method from Bodu.Security.Cryptography.Extensions:

using System.Security.Cryptography;
using Bodu.Security.Cryptography;

byte[] expected = LoadExpectedDigest();
byte[] computed;

using var hash = new AsconHash256();
computed = hash.ComputeHash(fileBytes);

bool ok = CryptographicOperations.FixedTimeEquals(computed, expected);

A plain SequenceEqual or == comparison leaks timing information and is unsafe whenever the comparison result drives an authentication or integrity decision.

Pattern 7 - reading the algorithm name at runtime

Both types report their canonical NIST algorithm identifier through the AlgorithmName property:

using Bodu.Security.Cryptography;

using var h256  = new AsconHash256();
using var ha256 = new AsconHashA256();

Console.WriteLine(h256.AlgorithmName);     // "ASCON-HASH256"
Console.WriteLine(ha256.AlgorithmName);    // "ASCON-HASHA256"

This is useful for constructing audit log entries, manifest files, or HTTP response headers that need to identify the algorithm used.

When to use ASCON hashing

Scenario Recommendation
Standards-backed 256-bit digest AsconHash256 - NIST SP 800-232 approved
Content addressing or deduplication Either; 256-bit output gives strong collision resistance
Constrained hardware, no SHA-2 acceleration AsconHashA256 - efficient software permutation
High-throughput pipeline on x86-64 with SHA extensions Prefer SHA256 (BCL, hardware-accelerated); fall back to AsconHashA256 if ASCON is required
Long-lived commitment (signatures, audit trails) AsconHash256 - 12-round margin throughout

Where to go next