Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Commit a56851d

Browse files
authored
Support for Blake3
Adding native support for Blake3 through https://github.com/xoofx/Blake3.NET
1 parent dbca392 commit a56851d

16 files changed

Lines changed: 706 additions & 0 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
4+
namespace OpenSource.Data.HashFunction.Blake3
5+
{
6+
/// <summary>
7+
/// Defines a configuration for a Blake2B hash function implementation.
8+
/// </summary>
9+
public class Blake3Config
10+
: IBlake3Config
11+
{
12+
/// <summary>
13+
/// The default hash size, in bits.
14+
/// </summary>
15+
public const int DefaultHashSizeInBits = 32;
16+
17+
/// <summary>
18+
/// Gets the desired hash size, in bits.
19+
/// </summary>
20+
/// <value>
21+
/// The desired hash size, in bits.
22+
/// </value>
23+
/// <remarks>
24+
/// Defaults to <c>32</c>.
25+
/// </remarks>
26+
public int HashSizeInBits { get; set; } = DefaultHashSizeInBits;
27+
28+
/// <summary>
29+
/// Makes a deep clone of current instance.
30+
/// </summary>
31+
/// <returns>A deep clone of the current instance.</returns>
32+
public IBlake3Config Clone() =>
33+
new Blake3Config() {
34+
HashSizeInBits = HashSizeInBits
35+
};
36+
}
37+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace OpenSource.Data.HashFunction.Blake3
6+
{
7+
/// <summary>
8+
/// Provides instances of implementations of <see cref="IBlake3"/>.
9+
/// </summary>
10+
public sealed class Blake3Factory
11+
: IBlake3Factory
12+
{
13+
/// <summary>
14+
/// Gets the singleton instance of this factory.
15+
/// </summary>
16+
public static IBlake3Factory Instance { get; } = new Blake3Factory();
17+
18+
19+
private Blake3Factory()
20+
{
21+
22+
}
23+
24+
/// <summary>
25+
/// Creates a new <see cref="IBlake3" /> instance with the default configuration.
26+
/// </summary>
27+
/// <returns>
28+
/// A <see cref="IBlake3" /> instance.
29+
/// </returns>
30+
public IBlake3 Create()
31+
{
32+
return Create(new Blake3Config());
33+
}
34+
35+
/// <summary>
36+
/// Creates a new <see cref="IBlake3" /> instance with given configuration.
37+
/// </summary>
38+
/// <param name="config">The configuration to use.</param>
39+
/// <returns>
40+
/// A <see cref="IBlake3" /> instance.
41+
/// </returns>
42+
/// <exception cref="ArgumentNullException"><paramref name="config"/></exception>
43+
public IBlake3 Create(IBlake3Config config)
44+
{
45+
if (config == null)
46+
throw new ArgumentNullException(nameof(config));
47+
48+
return new Blake3_Implementation(config);
49+
}
50+
}
51+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using OpenSource.Data.HashFunction.Core;
2+
using OpenSource.Data.HashFunction.Core.Utilities;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Runtime.InteropServices;
7+
using System.Security.Cryptography;
8+
using System.Threading;
9+
10+
namespace OpenSource.Data.HashFunction.Blake3
11+
{
12+
internal partial class Blake3_Implementation
13+
: HashFunctionBase,
14+
IBlake3
15+
{
16+
private readonly IBlake3Config _config;
17+
public IBlake3Config Config => _config.Clone();
18+
19+
public const int MinHashSizeInBits = 8;
20+
public const int MaxHashSizeInBits = 4096;
21+
22+
public Blake3_Implementation(IBlake3Config config)
23+
{
24+
if (config == null)
25+
throw new ArgumentNullException(nameof(config));
26+
27+
_config = config.Clone();
28+
29+
if (_config.HashSizeInBits < MinHashSizeInBits || _config.HashSizeInBits > MaxHashSizeInBits)
30+
throw new ArgumentOutOfRangeException($"{nameof(config)}.{nameof(config.HashSizeInBits)}", _config.HashSizeInBits, $"Expected: {MinHashSizeInBits} >= {nameof(config)}.{nameof(config.HashSizeInBits)} <= {MaxHashSizeInBits}");
31+
32+
if (_config.HashSizeInBits % 8 != 0)
33+
throw new ArgumentOutOfRangeException($"{nameof(config)}.{nameof(config.HashSizeInBits)}", _config.HashSizeInBits, $"{nameof(config)}.{nameof(config.HashSizeInBits)} must be a multiple of 8.");
34+
}
35+
36+
public override int HashSizeInBits => _config.HashSizeInBits;
37+
38+
protected override IHashValue ComputeHashInternal(ArraySegment<byte> data, CancellationToken cancellationToken)
39+
{
40+
byte[] outputBuffer = new byte[Config.HashSizeInBits];
41+
42+
Span<byte> output = new Span<byte>(outputBuffer);
43+
Hasher.Hash(data.AsSpan(), output);
44+
45+
return new HashValue(outputBuffer, Config.HashSizeInBits);
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)