Make message digests implement HashAlgorithm

This commit is contained in:
Matt Nadareski
2025-01-02 13:58:36 -05:00
parent 434a10d3db
commit 80448302e8
17 changed files with 57 additions and 125 deletions

View File

@@ -45,9 +45,6 @@ namespace SabreTools.Hashing
case IChecksum ic:
return ic.Final();
case MessageDigest.MessageDigestBase mdb:
return mdb.GetHash();
#if NET462_OR_GREATER || NETCOREAPP
case XxHash3 xxh3:
return xxh3.GetCurrentHash();
@@ -370,10 +367,6 @@ namespace SabreTools.Hashing
ic.Update(icBlock);
break;
case MessageDigest.MessageDigestBase mdb:
mdb.TransformBlock(buffer, offset, size);
break;
#if NET462_OR_GREATER || NETCOREAPP
case NonCryptographicHashAlgorithm ncha:
var nchaBufferSpan = new ReadOnlySpan<byte>(buffer, offset, size);
@@ -413,10 +406,6 @@ namespace SabreTools.Hashing
case HashAlgorithm ha:
ha.TransformFinalBlock(emptyBuffer, 0, 0);
break;
case MessageDigest.MessageDigestBase mdb:
mdb.Terminate();
break;
}
}

View File

@@ -41,7 +41,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void TransformBlock(byte[] data, int offset, int length)
protected override void HashCore(byte[] data, int offset, int length)
{
// Figure out how much buffer is needed
int bufferLen = 16 - _byteCount;
@@ -116,7 +116,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void Terminate()
protected override byte[] HashFinal()
{
// Determine the pad length
byte padLength = (byte)(16 - _byteCount);
@@ -131,18 +131,14 @@ namespace SabreTools.Hashing.MessageDigest
#else
Array.Fill(padding, padLength);
#endif
TransformBlock(padding, 0, padLength);
TransformBlock(_checksum, 0, _checksum.Length);
}
/// <inheritdoc/>
public override byte[] GetHash()
{
// Pad the block
HashCore(padding, 0, padLength);
HashCore(_checksum, 0, _checksum.Length);
// Get the hash
var hash = new byte[16];
Array.Copy(_digest, hash, 16);
// Reset the state and return
Reset();
return hash;
}

View File

@@ -26,7 +26,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void TransformBlock(byte[] data, int offset, int length)
protected override void HashCore(byte[] data, int offset, int length)
{
// Figure out how much buffer is needed
int bufferLen = (int)(_totalBytes & 0x3f);
@@ -81,7 +81,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void Terminate()
protected override byte[] HashFinal()
{
// Determine the pad length
int padLength = 64 - (int)(_totalBytes & 0x3f);
@@ -104,12 +104,9 @@ namespace SabreTools.Hashing.MessageDigest
padding[padLength - 8] = (byte)((totalBitCount >> 0) & 0xff);
// Pad the block
TransformBlock(padding, 0, padding.Length);
}
HashCore(padding, 0, padding.Length);
/// <inheritdoc/>
public override byte[] GetHash()
{
// Get the hash
var hash = new byte[16];
int hashOffset = 0;
@@ -121,8 +118,6 @@ namespace SabreTools.Hashing.MessageDigest
hashOffset += 4;
}
// Reset the state and return
Reset();
return hash;
}

View File

@@ -2,7 +2,7 @@ using System;
namespace SabreTools.Hashing.MessageDigest
{
public abstract class MessageDigestBase
public abstract class MessageDigestBase : System.Security.Cryptography.HashAlgorithm
{
/// <summary>
/// Total number of bytes processed
@@ -19,29 +19,8 @@ namespace SabreTools.Hashing.MessageDigest
/// </summary>
protected abstract void ResetImpl();
/// <summary>
/// Hash a block of data and append it to the existing hash
/// </summary>
/// <param name="data">Byte array representing the data</param>
/// <param name="offset">Offset in the byte array to include</param>
/// <param name="length">Length of the data to hash</param>
public abstract void TransformBlock(byte[] data, int offset, int length);
/// <summary>
/// End the hashing process
/// </summary>
/// TODO: Combine this when the padding byte can be set by implementing classes
public abstract void Terminate();
/// <summary>
/// Get the current value of the hash
/// </summary>
/// <remarks>
/// If <see cref="Terminate"/> has not been run, this value
/// will not be accurate for the processed bytes so far.
/// </remarks>
/// TODO: Combine this when there's an easier way of passing the state
public abstract byte[] GetHash();
/// <inheritdoc/>
protected abstract override void HashCore(byte[] array, int ibStart, int cbSize);
}
public abstract class MessageDigestBase<T> : MessageDigestBase where T : struct
@@ -63,13 +42,11 @@ namespace SabreTools.Hashing.MessageDigest
else
throw new InvalidOperationException();
Reset();
Initialize();
}
/// <summary>
/// Reset the internal hashing state
/// </summary>
public void Reset()
/// <inheritdoc/>
public override void Initialize()
{
// Reset the seed values
ResetImpl();

View File

@@ -27,7 +27,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void TransformBlock(byte[] data, int offset, int length)
protected override void HashCore(byte[] data, int offset, int length)
{
// Figure out how much buffer is needed
int bufferLen = (int)(_totalBytes & 0x3f);
@@ -82,7 +82,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void Terminate()
protected override byte[] HashFinal()
{
// Determine the pad length
int padLength = 64 - (int)(_totalBytes & 0x3f);
@@ -105,12 +105,9 @@ namespace SabreTools.Hashing.MessageDigest
padding[padLength - 8] = (byte)((totalBitCount >> 0) & 0xff);
// Pad the block
TransformBlock(padding, 0, padding.Length);
}
HashCore(padding, 0, padding.Length);
/// <inheritdoc/>
public override byte[] GetHash()
{
// Get the hash
var hash = new byte[16];
int hashOffset = 0;
@@ -122,8 +119,6 @@ namespace SabreTools.Hashing.MessageDigest
hashOffset += 4;
}
// Reset the state and return
Reset();
return hash;
}

View File

@@ -28,7 +28,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void TransformBlock(byte[] data, int offset, int length)
protected override void HashCore(byte[] data, int offset, int length)
{
// Figure out how much buffer is needed
int bufferLen = (int)(_totalBytes & 0x3f);
@@ -83,7 +83,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void Terminate()
protected override byte[] HashFinal()
{
// Determine the pad length
int padLength = 64 - (int)(_totalBytes & 0x3f);
@@ -102,16 +102,13 @@ namespace SabreTools.Hashing.MessageDigest
padding[padLength - 4] = (byte)((totalBitCount >> 32) & 0xff);
padding[padLength - 5] = (byte)((totalBitCount >> 24) & 0xff);
padding[padLength - 6] = (byte)((totalBitCount >> 16) & 0xff);
padding[padLength - 7] = (byte)((totalBitCount >> 8 ) & 0xff);
padding[padLength - 8] = (byte)((totalBitCount >> 0 ) & 0xff);
padding[padLength - 7] = (byte)((totalBitCount >> 8) & 0xff);
padding[padLength - 8] = (byte)((totalBitCount >> 0) & 0xff);
// Pad the block
TransformBlock(padding, 0, padding.Length);
}
HashCore(padding, 0, padding.Length);
/// <inheritdoc/>
public override byte[] GetHash()
{
// Get the hash
var hash = new byte[20];
int hashOffset = 0;
@@ -123,8 +120,6 @@ namespace SabreTools.Hashing.MessageDigest
hashOffset += 4;
}
// Reset the state and return
Reset();
return hash;
}

View File

@@ -31,7 +31,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void TransformBlock(byte[] data, int offset, int length)
protected override void HashCore(byte[] data, int offset, int length)
{
// Figure out how much buffer is needed
int bufferLen = (int)(_totalBytes & 0x3f);
@@ -86,7 +86,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void Terminate()
protected override byte[] HashFinal()
{
// Determine the pad length
int padLength = 64 - (int)(_totalBytes & 0x3f);
@@ -109,12 +109,9 @@ namespace SabreTools.Hashing.MessageDigest
padding[padLength - 8] = (byte)((totalBitCount >> 0) & 0xff);
// Pad the block
TransformBlock(padding, 0, padding.Length);
}
HashCore(padding, 0, padding.Length);
/// <inheritdoc/>
public override byte[] GetHash()
{
// Get the hash
var hash = new byte[32];
int hashOffset = 0;
@@ -126,8 +123,6 @@ namespace SabreTools.Hashing.MessageDigest
hashOffset += 4;
}
// Reset the state and return
Reset();
return hash;
}

View File

@@ -33,7 +33,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void TransformBlock(byte[] data, int offset, int length)
protected override void HashCore(byte[] data, int offset, int length)
{
// Figure out how much buffer is needed
int bufferLen = (int)(_totalBytes & 0x3f);
@@ -88,7 +88,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void Terminate()
protected override byte[] HashFinal()
{
// Determine the pad length
int padLength = 64 - (int)(_totalBytes & 0x3f);
@@ -107,16 +107,13 @@ namespace SabreTools.Hashing.MessageDigest
padding[padLength - 4] = (byte)((totalBitCount >> 32) & 0xff);
padding[padLength - 5] = (byte)((totalBitCount >> 24) & 0xff);
padding[padLength - 6] = (byte)((totalBitCount >> 16) & 0xff);
padding[padLength - 7] = (byte)((totalBitCount >> 8 ) & 0xff);
padding[padLength - 8] = (byte)((totalBitCount >> 0 ) & 0xff);
padding[padLength - 7] = (byte)((totalBitCount >> 8) & 0xff);
padding[padLength - 8] = (byte)((totalBitCount >> 0) & 0xff);
// Pad the block
TransformBlock(padding, 0, padding.Length);
}
HashCore(padding, 0, padding.Length);
/// <inheritdoc/>
public override byte[] GetHash()
{
// Get the hash
var hash = new byte[40];
int hashOffset = 0;
@@ -128,8 +125,6 @@ namespace SabreTools.Hashing.MessageDigest
hashOffset += 4;
}
// Reset the state and return
Reset();
return hash;
}

View File

@@ -14,9 +14,9 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override byte[] GetHash()
protected override byte[] HashFinal()
{
byte[] hash = base.GetHash();
byte[] hash = base.HashFinal();
byte[] trimmedHash = new byte[16];
Array.Copy(hash, trimmedHash, 16);
return trimmedHash;

View File

@@ -14,9 +14,9 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override byte[] GetHash()
protected override byte[] HashFinal()
{
byte[] hash = base.GetHash();
byte[] hash = base.HashFinal();
byte[] trimmedHash = new byte[16];
Array.Copy(hash, trimmedHash, 16);
return trimmedHash;

View File

@@ -14,9 +14,9 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override byte[] GetHash()
protected override byte[] HashFinal()
{
byte[] hash = base.GetHash();
byte[] hash = base.HashFinal();
byte[] trimmedHash = new byte[20];
Array.Copy(hash, trimmedHash, 20);
return trimmedHash;

View File

@@ -14,9 +14,9 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override byte[] GetHash()
protected override byte[] HashFinal()
{
byte[] hash = base.GetHash();
byte[] hash = base.HashFinal();
byte[] trimmedHash = new byte[20];
Array.Copy(hash, trimmedHash, 20);
return trimmedHash;

View File

@@ -14,9 +14,9 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override byte[] GetHash()
protected override byte[] HashFinal()
{
byte[] hash = base.GetHash();
byte[] hash = base.HashFinal();
byte[] trimmedHash = new byte[16];
Array.Copy(hash, trimmedHash, 16);
return trimmedHash;

View File

@@ -14,9 +14,9 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override byte[] GetHash()
protected override byte[] HashFinal()
{
byte[] hash = base.GetHash();
byte[] hash = base.HashFinal();
byte[] trimmedHash = new byte[16];
Array.Copy(hash, trimmedHash, 16);
return trimmedHash;

View File

@@ -14,9 +14,9 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override byte[] GetHash()
protected override byte[] HashFinal()
{
byte[] hash = base.GetHash();
byte[] hash = base.HashFinal();
byte[] trimmedHash = new byte[20];
Array.Copy(hash, trimmedHash, 20);
return trimmedHash;

View File

@@ -14,9 +14,9 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override byte[] GetHash()
protected override byte[] HashFinal()
{
byte[] hash = base.GetHash();
byte[] hash = base.HashFinal();
byte[] trimmedHash = new byte[20];
Array.Copy(hash, trimmedHash, 20);
return trimmedHash;

View File

@@ -35,7 +35,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void TransformBlock(byte[] data, int offset, int length)
protected override void HashCore(byte[] data, int offset, int length)
{
// Figure out how much buffer is needed
int bufferLen = (int)(_totalBytes & 0x3f);
@@ -90,7 +90,7 @@ namespace SabreTools.Hashing.MessageDigest
}
/// <inheritdoc/>
public override void Terminate()
protected override byte[] HashFinal()
{
// Determine the pad length
int padLength = 64 - (int)(_totalBytes & 0x3f);
@@ -113,12 +113,9 @@ namespace SabreTools.Hashing.MessageDigest
padding[padLength - 8] = (byte)((totalBitCount >> 0) & 0xff);
// Pad the block
TransformBlock(padding, 0, padding.Length);
}
HashCore(padding, 0, padding.Length);
/// <inheritdoc/>
public override byte[] GetHash()
{
// Get the hash
var hash = new byte[24];
int hashOffset = 0;
@@ -130,8 +127,6 @@ namespace SabreTools.Hashing.MessageDigest
hashOffset += 8;
}
// Reset the state and return
Reset();
return hash;
}