From 8d2a2cd5de40e2b94ef5007c32832ed9a063dc40 Mon Sep 17 00:00:00 2001 From: chai <215380520@qq.com> Date: Thu, 12 Oct 2023 22:09:49 +0800 Subject: +hazel-networking --- .../Hazel-Networking/Hazel/Crypto/Sha256Stream.cs | 86 ++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 Tools/Hazel-Networking/Hazel/Crypto/Sha256Stream.cs (limited to 'Tools/Hazel-Networking/Hazel/Crypto/Sha256Stream.cs') diff --git a/Tools/Hazel-Networking/Hazel/Crypto/Sha256Stream.cs b/Tools/Hazel-Networking/Hazel/Crypto/Sha256Stream.cs new file mode 100644 index 0000000..1903693 --- /dev/null +++ b/Tools/Hazel-Networking/Hazel/Crypto/Sha256Stream.cs @@ -0,0 +1,86 @@ +using System; +using System.Security.Cryptography; + +namespace Hazel.Crypto +{ + /// + /// Streams data into a SHA256 digest + /// + public class Sha256Stream : IDisposable + { + /// + /// Size of the SHA256 digest in bytes + /// + public const int DigestSize = 32; + + private SHA256 hash = SHA256.Create(); + private bool isHashFinished = false; + + struct EmptyArray + { + public static readonly byte[] Value = new byte[0]; + } + + /// + /// Create a new instance of a SHA256 stream + /// + public Sha256Stream() + { + } + + /// + /// Release resources associated with the stream + /// + public void Dispose() + { + this.hash?.Dispose(); + this.hash = null; + + GC.SuppressFinalize(this); + } + + /// + /// Reset the stream to its initial state + /// + public void Reset() + { + this.hash?.Dispose(); + this.hash = SHA256.Create(); + this.isHashFinished = false; + } + + /// + /// Add data to the stream + /// + public void AddData(ByteSpan data) + { + while (data.Length > 0) + { + int offset = this.hash.TransformBlock(data.GetUnderlyingArray(), data.Offset, data.Length, null, 0); + data = data.Slice(offset); + } + } + + /// + /// Calculate the final hash of the stream data + /// + /// + /// Target span to which the hash will be written + /// + public void CopyOrCalculateFinalHash(ByteSpan output) + { + if (output.Length != DigestSize) + { + throw new ArgumentException($"Expected a span of {DigestSize} bytes. Got a span of {output.Length} bytes", nameof(output)); + } + + if (this.isHashFinished == false) + { + this.hash.TransformFinalBlock(EmptyArray.Value, 0, 0); + this.isHashFinished = true; + } + + new ByteSpan(this.hash.Hash).CopyTo(output); + } + } +} -- cgit v1.1-26-g67d0