Table of Contents

Snefru Class

Definition

Namespace
Bodu.Security.Cryptography
Assembly
Bodu.Security.Cryptography.dll
Package
Bodu.Security.Cryptography 1.2.0
Source
Snefru.SBoxConstants.cs

Base class for the Snefru family of unkeyed hash functions designed by Ralph Merkle, implementing the core compression routine using S-box substitutions and word rotations over 512-bit blocks.

public abstract class Snefru : BlockHashAlgorithm, ICryptoTransform, IDisposable
Inheritance
Snefru
Implements
Derived
Inherited Members
Extension Methods

Remarks

Snefru is one of the earliest cryptographic hash functions developed and is now considered broken: collision attacks against the two- and four-pass variants are known, and it should not be used for any new security-sensitive application. It remains implemented here for interoperability with legacy data and academic study.

This base class is extended by:

  • Snefru128 produces a 128-bit (16-byte) hash with a 4-word internal state.
  • Snefru256 produces a 256-bit (32-byte) hash with an 8-word internal state.

Each input block is processed by 8 rounds consisting of an S-box substitution step followed by a word-wise circular rotation. After all input has been absorbed, the internal state is serialized in big-endian byte order to produce the final digest.

When to choose Snefru. Academic study and legacy interop only - Snefru has practical collision attacks against both the 2-pass and 4-pass variants and is one of the earliest cryptographic hashes ever published. Pick Snefru128 for 128-bit output and Snefru256 for 256-bit output. For any new security-sensitive cryptographic hashing use SHA-2, SHA-3, or Blake2b; for non-cryptographic fingerprinting use a member of Bodu.IO.Hashing.

important

This algorithm is not considered secure by modern cryptographic standards and should not be used for password hashing, digital signatures, or integrity validation in security-sensitive applications.

This implementation is constant-time in its control flow, but the S-box lookup tables are read at message-dependent indices, so hashing secret data (for example inside a keyed construction) is not hardened against timing or cache-based side-channel attacks.

Constructors

Snefru(int)

Initializes a new instance of the Snefru class with the specified output hash size.

protected Snefru(int hashSize)

Parameters

hashSize int

The size of the output hash, in bits. Must be either 128 or 256.

Exceptions

ArgumentOutOfRangeException

Thrown if hashSize is not one of the supported values.

Properties

AlgorithmName

Gets the canonical, fully-qualified algorithm name for this instance, including any size or variant qualifiers (for example, "Tiger/192", "Skein-512-256", "BLAKE2b-512", "ASCON-HASH256", "SipHash-2-4-64").

public override string AlgorithmName { get; }

Property Value

string

A string identifying the algorithm and its current configuration.

Remarks

Derived classes implement this property to expose a stable, consumer-facing identifier suitable for logging, telemetry, registry keys, or interop with hash-name catalogues. Implementations should be pure and side-effect-free - the value may be queried before any input has been consumed and after disposal as part of error reporting.

CanReuseTransform

Gets a value indicating whether the current transform can be reused.

public override bool CanReuseTransform { get; }

Property Value

bool

Always true.

CanTransformMultipleBlocks

When overridden in a derived class, gets a value indicating whether multiple blocks can be transformed.

public override bool CanTransformMultipleBlocks { get; }

Property Value

bool

true if multiple blocks can be transformed; otherwise, false.

Methods

Dispose(bool)

Releases resources used by the algorithm and clears the internal state and working buffer.

protected override void Dispose(bool disposing)

Parameters

disposing bool

true to release both managed and unmanaged resources; false to release only unmanaged resources.

Initialize()

Resets the algorithm to its initial state by clearing the residual buffer and the running byte total. Derived classes override this method, call base.Initialize() first, and then reset their own algorithm-specific state (chaining variables, IV, key-derived schedule).

public override void Initialize()

Remarks

This method does not reset the State property explicitly on .NET 6+ targets — the framework manages that transition. On earlier targets, derived classes that need the already-finalized guard should reset their _finalized backing field from their own Initialize override.

Derived classes that need to validate state before the reset (for example, a keyed MAC that refuses to be re-initialized when no key has been set) should perform that validation before calling base.Initialize(). Once the base call returns, the residual buffer is empty, Bodu.Security.Cryptography.BufferedBlockHashAlgorithm._residualBytes is 0, and Bodu.Security.Cryptography.BufferedBlockHashAlgorithm._totalBytes is 0.

Exceptions

ObjectDisposedException

The instance has been disposed.

PadBlock(ReadOnlySpan<byte>, ulong, Span<byte>)

Pads the final input block for the Snefru hash algorithm by appending zeros and encoding the total message length.

protected override int PadBlock(ReadOnlySpan<byte> block, ulong messageLength, Span<byte> destination)

Parameters

block ReadOnlySpan<byte>

The final block of unprocessed input, typically containing fewer than BlockSize bytes.

messageLength ulong

The total number of bytes processed prior to this block (excluding the current partial block).

destination Span<byte>

The span receiving the padded block or blocks; at least two blocks long.

Returns

int

A padded byte array of exactly 2 × BlockSize bytes, containing the input block followed by zeros and an 8-byte big-endian length field. The result is aligned for final compression and ready for use by ProcessBlock(ReadOnlySpan<byte>).

Remarks

Snefru's final padding block is double the standard block size to support its dual-block internal buffer design. The method pads the input block with zeros and appends a 64-bit big-endian integer representing the total message length (in bits).

ProcessBlock(ReadOnlySpan<byte>)

Transforms a single 512-bit block using Snefru S-box and rotation rounds. Updates internal state via XOR with permuted buffer values.

protected override void ProcessBlock(ReadOnlySpan<byte> block)

Parameters

block ReadOnlySpan<byte>

The 64-byte input block to hash.

Remarks

The method performs 8 rounds, each consisting of 4 shifts and S-box applications, to mix input entropy into the state.

ProcessFinalBlock()

Finalizes the hash computation by serializing the internal state to a byte array in big-endian format.

protected override byte[] ProcessFinalBlock()

Returns

byte[]

The computed hash as a byte array.

Applies to

ProductVersions
.NET8, 10

See Also