Skip to content

Commit 230d291

Browse files
committed
add HashAlgorithm shim, tidy up API, add docs
1 parent 7eb3020 commit 230d291

14 files changed

Lines changed: 765 additions & 263 deletions

src/Blake2Fast/Blake2Fast.csproj

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<RootNamespace>SauceControl.Blake2Fast</RootNamespace>
55
<AssemblyName>SauceControl.Blake2Fast</AssemblyName>
66
<AssemblyTitle>Blake2Fast</AssemblyTitle>
7-
<TargetFrameworks>netstandard1.3;netcoreapp2.1</TargetFrameworks>
7+
<TargetFrameworks>netstandard1.0;netstandard1.3;netstandard2.0;netcoreapp2.0;netcoreapp2.1;net45</TargetFrameworks>
88
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
99
<DebugType>pdbonly</DebugType>
1010
<DebugSymbols>true</DebugSymbols>
@@ -24,10 +24,18 @@
2424
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
2525
</PropertyGroup>
2626

27+
<PropertyGroup Condition="'$(TargetFramework)'=='netcoreapp2.1' Or '$(TargetFramework)'=='netcoreapp2.1'">
28+
<DefineConstants>$(DefineConstants);IMPLICIT_BYTESPAN</DefineConstants>
29+
</PropertyGroup>
30+
2731
<PropertyGroup Condition="'$(TargetFramework)'=='netcoreapp2.1'">
2832
<DefineConstants>$(DefineConstants);FAST_SPAN;USE_INTRINSICS</DefineConstants>
2933
</PropertyGroup>
3034

35+
<PropertyGroup Condition="'$(Configuration)'=='Release'">
36+
<DocumentationFile>bin\$(Configuration)\$(TargetFrameWork)\SauceControl.Blake2Fast.xml</DocumentationFile>
37+
</PropertyGroup>
38+
3139
<ItemGroup Condition="$(DefineConstants.Contains('USE_INTRINSICS'))">
3240
<PackageReference Include="System.Runtime.Intrinsics.Experimental" Version="4.5.0-rc1" />
3341
</ItemGroup>
@@ -46,6 +54,11 @@
4654
<DesignTime>True</DesignTime>
4755
<AutoGen>True</AutoGen>
4856
</Compile>
57+
<Compile Update="Blake2bContext.cs">
58+
<DependentUpon>Blake2bContext.tt</DependentUpon>
59+
<DesignTime>True</DesignTime>
60+
<AutoGen>True</AutoGen>
61+
</Compile>
4962
<Compile Update="Blake2bScalar.cs">
5063
<DependentUpon>Blake2bScalar.tt</DependentUpon>
5164
<DesignTime>True</DesignTime>
@@ -61,6 +74,11 @@
6174
<DesignTime>True</DesignTime>
6275
<AutoGen>True</AutoGen>
6376
</Compile>
77+
<Compile Update="Blake2sContext.cs">
78+
<DependentUpon>Blake2sContext.tt</DependentUpon>
79+
<DesignTime>True</DesignTime>
80+
<AutoGen>True</AutoGen>
81+
</Compile>
6482
<Compile Update="Blake2sScalar.cs">
6583
<DependentUpon>Blake2sScalar.tt</DependentUpon>
6684
<DesignTime>True</DesignTime>
@@ -78,6 +96,10 @@
7896
<LastGenOutput>Blake2b.cs</LastGenOutput>
7997
<Generator>TextTemplatingFileGenerator</Generator>
8098
</None>
99+
<None Update="Blake2bContext.tt">
100+
<LastGenOutput>Blake2bContext.cs</LastGenOutput>
101+
<Generator>TextTemplatingFileGenerator</Generator>
102+
</None>
81103
<None Update="Blake2bScalar.tt">
82104
<LastGenOutput>Blake2bScalar.cs</LastGenOutput>
83105
<Generator>TextTemplatingFileGenerator</Generator>
@@ -90,6 +112,10 @@
90112
<LastGenOutput>Blake2s.cs</LastGenOutput>
91113
<Generator>TextTemplatingFileGenerator</Generator>
92114
</None>
115+
<None Update="Blake2sContext.tt">
116+
<LastGenOutput>Blake2sContext.cs</LastGenOutput>
117+
<Generator>TextTemplatingFileGenerator</Generator>
118+
</None>
93119
<None Update="Blake2sScalar.tt">
94120
<LastGenOutput>Blake2sScalar.cs</LastGenOutput>
95121
<Generator>TextTemplatingFileGenerator</Generator>

src/Blake2Fast/Blake2b.cs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#if !NETSTANDARD1_0
2+
using System.Security.Cryptography;
3+
#endif
4+
5+
#if FAST_SPAN
6+
using ByteSpan = System.ReadOnlySpan<byte>;
7+
#else
8+
using ByteSpan = System.ArraySegment<byte>;
9+
#endif
10+
11+
namespace SauceControl.Blake2Fast
12+
{
13+
/// <summary>Static helper methods for Blake2b hashing.</summary>
14+
public static class Blake2b
15+
{
16+
/// <inheritdoc cref="ComputeHash(int, ByteSpan, ByteSpan)"/>
17+
public static byte[] ComputeHash(ByteSpan input) => ComputeHash(Blake2bContext.HashBytes, default, input);
18+
19+
/// <inheritdoc cref="ComputeHash(int, ByteSpan, ByteSpan)"/>
20+
public static byte[] ComputeHash(int digestLength, ByteSpan input) => ComputeHash(digestLength, default, input);
21+
22+
/// <inheritdoc cref="ComputeHash(int, ByteSpan, ByteSpan)"/>
23+
public static byte[] ComputeHash(ByteSpan key, ByteSpan input) => ComputeHash(Blake2bContext.HashBytes, key, input);
24+
25+
/// <summary>Perform an all-at-once Blake2b hash computation.</summary>
26+
/// <remarks>If you have all the input available at once, this is the most efficient way to calculate the hash.</remarks>
27+
/// <param name="digestLength">The hash digest length in bytes. Valid values are 1 to 64.</param>
28+
/// <param name="key">0 to 64 bytes of input for initializing a keyed hash.</param>
29+
/// <param name="input">The message bytes to hash.</param>
30+
/// <returns>The computed hash digest from the message bytes in <paramref name="input" />.</returns>
31+
public static byte[] ComputeHash(int digestLength, ByteSpan key, ByteSpan input)
32+
{
33+
var ctx = default(Blake2bContext);
34+
ctx.Init(digestLength, key);
35+
ctx.Update(input);
36+
return ctx.Finish();
37+
}
38+
39+
/// <inheritdoc cref="CreateIncrementalHasher(int, ByteSpan)" />
40+
public static IBlake2Incremental CreateIncrementalHasher() => CreateIncrementalHasher(Blake2bContext.HashBytes, default(ByteSpan));
41+
42+
/// <inheritdoc cref="CreateIncrementalHasher(int, ByteSpan)" />
43+
public static IBlake2Incremental CreateIncrementalHasher(int digestLength) => CreateIncrementalHasher(digestLength, default(ByteSpan));
44+
45+
/// <inheritdoc cref="CreateIncrementalHasher(int, ByteSpan)" />
46+
public static IBlake2Incremental CreateIncrementalHasher(ByteSpan key) => CreateIncrementalHasher(Blake2bContext.HashBytes, key);
47+
48+
/// <summary>Create and initialize an incremental Blake2b hash computation.</summary>
49+
/// <remarks>If you will recieve the input in segments rather than all at once, this is the most efficient way to calculate the hash.</remarks>
50+
/// <param name="digestLength">The hash digest length in bytes. Valid values are 1 to 64.</param>
51+
/// <param name="key">0 to 64 bytes of input for initializing a keyed hash.</param>
52+
/// <returns>An <see cref="IBlake2Incremental" /> interface for updating and finalizing the hash.</returns>
53+
public static IBlake2Incremental CreateIncrementalHasher(int digestLength, ByteSpan key)
54+
{
55+
var ctx = default(Blake2bContext);
56+
ctx.Init(digestLength, key);
57+
return ctx;
58+
}
59+
60+
#if !IMPLICIT_BYTESPAN
61+
/// <inheritdoc cref="ComputeHash(int, ByteSpan, ByteSpan)"/>
62+
public static byte[] ComputeHash(byte[] input) => ComputeHash(input.AsByteSpan());
63+
64+
/// <inheritdoc cref="ComputeHash(int, ByteSpan, ByteSpan)"/>
65+
public static byte[] ComputeHash(int digestLength, byte[] input) => ComputeHash(digestLength, input.AsByteSpan());
66+
67+
/// <inheritdoc cref="ComputeHash(int, ByteSpan, ByteSpan)"/>
68+
public static byte[] ComputeHash(byte[] key, byte[] input) => ComputeHash(key.AsByteSpan(), input.AsByteSpan());
69+
70+
/// <inheritdoc cref="ComputeHash(int, ByteSpan, ByteSpan)"/>
71+
public static byte[] ComputeHash(int digestLength, byte[] key, byte[] input) => ComputeHash(digestLength, key.AsByteSpan(), input.AsByteSpan());
72+
73+
/// <inheritdoc cref="ComputeHash(int, ByteSpan, ByteSpan)"/>
74+
public static IBlake2Incremental CreateIncrementalHasher(byte[] key) => CreateIncrementalHasher(key.AsByteSpan());
75+
76+
/// <inheritdoc cref="ComputeHash(int, ByteSpan, ByteSpan)"/>
77+
public static IBlake2Incremental CreateIncrementalHasher(int digestLength, byte[] key) => CreateIncrementalHasher(digestLength, key.AsByteSpan());
78+
#endif
79+
80+
#if !NETSTANDARD1_0
81+
/// <inheritdoc cref="CreateHashAlgorithm(int)" />
82+
public static HashAlgorithm CreateHashAlgorithm() => CreateHashAlgorithm(Blake2bContext.HashBytes);
83+
84+
/// <summary>Creates and initializes a <see cref="HashAlgorithm" /> instance that implements Blake2b hashing.</summary>
85+
/// <remarks>Use this only if you require an implementation of <see cref="HashAlgorithm" />. It is less efficient than the direct methods.</remarks>
86+
/// <param name="digestLength">The hash digest length in bytes. Valid values are 1 to 64.</param>
87+
/// <returns>A <see cref="HashAlgorithm" /> instance.</returns>
88+
public static HashAlgorithm CreateHashAlgorithm(int digestLength) => new Blake2HMAC(Blake2Algorithm.Blake2b, digestLength, default);
89+
90+
/// <inheritdoc cref="CreateHMAC(int, ByteSpan)" />
91+
public static HMAC CreateHMAC(ByteSpan key) => CreateHMAC(Blake2bContext.HashBytes, key);
92+
93+
/// <summary>Creates and initializes an <see cref="HMAC" /> instance that implements Blake2b keyed hashing.</summary>
94+
/// <remarks>Use this only if you require an implementation of <see cref="HMAC" />. It is less efficient than the direct methods.</remarks>
95+
/// <param name="digestLength">The hash digest length in bytes. Valid values are 1 to 64.</param>
96+
/// <param name="key">0 to 64 bytes of input for initializing the keyed hash.</param>
97+
/// <returns>An <see cref="HMAC" /> instance.</returns>
98+
public static HMAC CreateHMAC(int digestLength, ByteSpan key) => new Blake2HMAC(Blake2Algorithm.Blake2b, digestLength, key);
99+
100+
#if !IMPLICIT_BYTESPAN
101+
/// <inheritdoc cref="CreateHMAC(int, ByteSpan)" />
102+
public static HMAC CreateHMAC(byte[] key) => CreateHMAC(key.AsByteSpan());
103+
104+
/// <inheritdoc cref="CreateHMAC(int, ByteSpan)" />
105+
public static HMAC CreateHMAC(int digestLength, byte[] key) => CreateHMAC(digestLength, key.AsByteSpan());
106+
#endif
107+
#endif
108+
}
109+
}

src/Blake2Fast/Blake2b.tt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<#@ template language="C#" debug="false" hostspecific="false" #>
2+
<#@ output extension=".cs" #>
3+
<# var alg = b2b; #>
4+
<#@ include file="_Blake2Api.ttinclude" #><#@ include file="_Blake2Alg.ttinclude" #>

0 commit comments

Comments
 (0)