Skip to content

Commit

Permalink
src: Use IncrementalBLAKE2b for streams.
Browse files Browse the repository at this point in the history
  • Loading branch information
samuel-lucas6 committed Sep 1, 2022
1 parent 1590986 commit b275a33
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 24 deletions.
6 changes: 6 additions & 0 deletions src/Geralt.Tests/BLAKE2bTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public void ComputeHashStream_ValidInputs()
using var memoryStream = new MemoryStream(Message, writable: false);
hash = blake2b.ComputeHash(memoryStream);
Assert.IsTrue(hash.SequenceEqual(Hash));
memoryStream.Position = 0;
hash = blake2b.ComputeHash(memoryStream);
Assert.IsTrue(hash.SequenceEqual(Hash));
}

[TestMethod]
Expand Down Expand Up @@ -134,6 +137,9 @@ public void ComputeTagStream_ValidInputs()
using var memoryStream = new MemoryStream(Message, writable: false);
tag = blake2b.ComputeHash(memoryStream);
Assert.IsTrue(tag.SequenceEqual(Tag));
memoryStream.Position = 0;
tag = blake2b.ComputeHash(memoryStream);
Assert.IsTrue(tag.SequenceEqual(Tag));
}

[TestMethod]
Expand Down
33 changes: 9 additions & 24 deletions src/Geralt/Crypto/BLAKE2bHashAlgorithm.cs
Original file line number Diff line number Diff line change
@@ -1,62 +1,47 @@
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using static Interop.Libsodium;

namespace Geralt;

public sealed class BLAKE2bHashAlgorithm : HashAlgorithm
{
private crypto_generichash_blake2b_state _state;
private IncrementalBLAKE2b _blake2b;
private readonly byte[]? _key;
private readonly int _hashSize;
private GCHandle _handle;

public BLAKE2bHashAlgorithm(int hashSize, ReadOnlySpan<byte> key = default)
{
Validation.SizeBetween(nameof(hashSize), hashSize, BLAKE2b.MinHashSize, BLAKE2b.MaxHashSize);
if (key != default) { Validation.SizeBetween(nameof(key), key.Length, BLAKE2b.MinKeySize, BLAKE2b.MaxKeySize); }
Sodium.Initialise();
_blake2b = new IncrementalBLAKE2b(hashSize, key);
_key = key == default ? null : key.ToArray();
_handle = GCHandle.Alloc(_key, GCHandleType.Pinned);
_hashSize = hashSize;
Initialize();
}

public override unsafe void Initialize()
public override void Initialize()
{
fixed (byte* k = _key)
{
int ret = crypto_generichash_init(ref _state, k, _key == null ? 0 : (nuint)_key.Length, (nuint)_hashSize);
if (ret != 0) { throw new CryptographicException("Error initialising hash."); }
}
_blake2b = new IncrementalBLAKE2b(_hashSize, _key);
}

protected override unsafe void HashCore(byte[] message, int offset, int size)
protected override void HashCore(byte[] message, int offset, int size)
{
var buffer = new byte[size];
Array.Copy(message, offset, buffer, destinationIndex: 0, buffer.Length);
fixed (byte* b = buffer)
{
int ret = crypto_generichash_update(ref _state, b, (ulong)buffer.Length);
if (ret != 0) { throw new CryptographicException("Error updating hash."); }
}
_blake2b.Update(buffer);
}

protected override unsafe byte[] HashFinal()
protected override byte[] HashFinal()
{
var hash = new byte[_hashSize];
fixed (byte* h = hash)
{
int ret = crypto_generichash_final(ref _state, h, (nuint)hash.Length);
if (ret != 0) { throw new CryptographicException("Error finalising hash."); }
}
_blake2b.Finalize(hash);
return hash;
}

protected override void Dispose(bool disposing)
{
CryptographicOperations.ZeroMemory(_key);
_handle.Free();
_blake2b.Dispose();
base.Dispose(disposing);
}
}

0 comments on commit b275a33

Please sign in to comment.