aboutsummaryrefslogtreecommitdiff
path: root/Tools/Hazel-Networking/Hazel/Crypto/Sha256Stream.cs
diff options
context:
space:
mode:
authorchai <215380520@qq.com>2023-10-12 22:09:49 +0800
committerchai <215380520@qq.com>2023-10-12 22:09:49 +0800
commit8d2a2cd5de40e2b94ef5007c32832ed9a063dc40 (patch)
treea63dfbe815855925c9fb8f2804bd6ccfeffbd2eb /Tools/Hazel-Networking/Hazel/Crypto/Sha256Stream.cs
parentdd0c5d50e377d9be1e728463670908a6c9d2c14f (diff)
+hazel-networking
Diffstat (limited to 'Tools/Hazel-Networking/Hazel/Crypto/Sha256Stream.cs')
-rw-r--r--Tools/Hazel-Networking/Hazel/Crypto/Sha256Stream.cs86
1 files changed, 86 insertions, 0 deletions
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
+{
+ /// <summary>
+ /// Streams data into a SHA256 digest
+ /// </summary>
+ public class Sha256Stream : IDisposable
+ {
+ /// <summary>
+ /// Size of the SHA256 digest in bytes
+ /// </summary>
+ public const int DigestSize = 32;
+
+ private SHA256 hash = SHA256.Create();
+ private bool isHashFinished = false;
+
+ struct EmptyArray
+ {
+ public static readonly byte[] Value = new byte[0];
+ }
+
+ /// <summary>
+ /// Create a new instance of a SHA256 stream
+ /// </summary>
+ public Sha256Stream()
+ {
+ }
+
+ /// <summary>
+ /// Release resources associated with the stream
+ /// </summary>
+ public void Dispose()
+ {
+ this.hash?.Dispose();
+ this.hash = null;
+
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Reset the stream to its initial state
+ /// </summary>
+ public void Reset()
+ {
+ this.hash?.Dispose();
+ this.hash = SHA256.Create();
+ this.isHashFinished = false;
+ }
+
+ /// <summary>
+ /// Add data to the stream
+ /// </summary>
+ 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);
+ }
+ }
+
+ /// <summary>
+ /// Calculate the final hash of the stream data
+ /// </summary>
+ /// <param name="output">
+ /// Target span to which the hash will be written
+ /// </param>
+ 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);
+ }
+ }
+}