Table of Contents

Using Snefru

Snefru is a 1990 cryptographic hash by Ralph Merkle, named after the Egyptian pharaoh. It runs a block-mix function over the input and keeps the low half of the state as output. Bodu.Security.Cryptography ships both published widths:

Type Output Block size
Snefru128 128 bits 48 bytes
Snefru256 256 bits 32 bytes

Both derive from a shared Snefru base, which sits on BlockHashAlgorithm and, through it, on HashAlgorithm. Each input block runs through 8 rounds of S-box substitution and word-wise rotation; the low half of the 512-bit working buffer becomes the next chaining value, and the final chaining value is the digest.

Warning

Snefru is cryptographically broken - it satisfies none of the resistance properties a cryptographic hash is supposed to provide. Eli Biham published practical collisions against both the 2-pass and 4-pass variants. The implementation in this package is provided for interoperability with legacy systems and for research, not for protecting real data. An attacker who can choose part of the input can forge a colliding message at negligible cost, so Snefru must never sit on a security boundary - no password hashing, no signature input, no integrity check that an adversary can influence. For any new work where you need a cryptographic hash, use the BCL's System.Security.Cryptography.SHA256 / System.Security.Cryptography.SHA512, or Tiger if you need 192-bit output.

Pattern 1 - compute a digest

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

byte[] data = Encoding.UTF8.GetBytes("the quick brown fox");

using var snefru = new Snefru256();
byte[] digest   = snefru.ComputeHash(data);   // 32 bytes
string hex      = Convert.ToHexString(digest);

Swap Snefru256 for Snefru128 for a 16-byte digest.

Pattern 2 - streaming

Snefru inherits the standard BCL streaming shape:

using Bodu.Security.Cryptography;

using var snefru = new Snefru256();
using var stream = File.OpenRead("archive.bin");
byte[] digest = snefru.ComputeHash(stream);

You can also drive it block-by-block via TransformBlock / TransformFinalBlock.

Pattern 3 - the two widths

The two classes are completely independent - the block size differs (48 bytes for Snefru-128, 32 bytes for Snefru-256), and the outputs are not truncations of one another. Pick the width your interoperating system specifies.

using Bodu.Security.Cryptography;

using var snefru128 = new Snefru128();   // 128-bit output, 48-byte blocks
using var snefru256 = new Snefru256();   // 256-bit output, 32-byte blocks

When to use Snefru

  • Interoperability with a legacy system that already uses Snefru (rare - Snefru is mostly of historical interest).
  • Research into early hash-function design, or as a test case for cryptanalysis tooling.

For everything else, pick a modern digest. The hashing overview lists the options in this package; for brand-new work, the BCL's SHA-2 family is the right default.

Where to go next