Skip to content

Latest commit

History

27 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Blake2Fast

These RFC 7693-compliant BLAKE2 implementations have been tuned for high speed and low memory usage. The .NET Core 2.1 and 3.0 builds support the new X86 SIMD Intrinsics for even greater speed. Span<byte> is used throughout for lower memory overhead compared to byte[] based APIs.

Sample benchmark results comparing with built-in .NET algorithms, 10MiB input, .NET Core x64 and x86 runtimes:

BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134
Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.0.100-preview-010184
[Host] : .NET Core 2.1.7 (CoreCLR 4.6.27129.04, CoreFX 4.6.27129.04), 64bit RyuJIT
netcoreapp1.1 : .NET Core 1.1.8 (CoreCLR 4.6.26328.01, CoreFX 4.6.24705.01), 64bit RyuJIT
netcoreapp2.1 : .NET Core 2.1.7 (CoreCLR 4.6.27129.04, CoreFX 4.6.27129.04), 64bit RyuJIT
netcoreapp3.0 : .NET Core 3.0.0-preview-27324-5 (CoreCLR 4.6.27322.0, CoreFX 4.7.19.7311), 64bit RyuJIT
Jit=RyuJit Toolchain=Default
MethodJobPlatformMeanErrorStdDevAllocated
Blake2bFastnetcoreapp1.1X6410.753 ms0.0502 ms0.0445 ms0 B
Blake2sFastnetcoreapp1.1X6417.066 ms0.1528 ms0.1355 ms0 B
Blake2bFastnetcoreapp2.1X6410.230 ms0.0708 ms0.0662 ms0 B
Blake2sFastnetcoreapp2.1X6413.678 ms0.0258 ms0.0216 ms0 B
Blake2bFastnetcoreapp3.0X648.792 ms0.0305 ms0.0254 ms0 B
Blake2sFastnetcoreapp3.0X6413.687 ms0.0463 ms0.0433 ms0 B
MD5netcoreapp3.0X6417.894 ms0.0632 ms0.0561 ms0 B
SHA256netcoreapp3.0X6438.607 ms0.2877 ms0.2691 ms0 B
SHA512netcoreapp3.0X6423.498 ms0.1493 ms0.1397 ms304 B
MethodJobPlatformMeanErrorStdDevAllocated
Blake2bFastnetcoreapp1.1X8668.925 ms0.1575 ms0.1315 ms0 B
Blake2sFastnetcoreapp1.1X8667.513 ms0.5069 ms0.4742 ms0 B
Blake2bFastnetcoreapp2.1X8614.208 ms0.0876 ms0.0819 ms0 B
Blake2sFastnetcoreapp2.1X8613.628 ms0.0399 ms0.0333 ms0 B
Blake2bFastnetcoreapp3.0X868.965 ms0.0483 ms0.0452 ms0 B
Blake2sFastnetcoreapp3.0X8613.636 ms0.0474 ms0.0443 ms0 B
MD5netcoreapp3.0X8616.966 ms0.1235 ms0.1155 ms0 B
SHA256netcoreapp3.0X8644.138 ms0.1181 ms0.0986 ms0 B
SHA512netcoreapp3.0X8637.384 ms0.3196 ms0.2989 ms0 B

Duplicate results have been removed from the above tables for the sake of brevity.

Note that the built-in cryptographic hash algorithms in .NET forward to platform-native libraries for their implementations. On Windows, this means the implementations are provided by Windows CNG. Their performance is therefore identical across all .NET Core versions.

On .NET Framework and .NET Core 1.1, only scalar implementations are available for both BLAKE2 algorithms. The scalar implementations outperform the built-in .NET algorithms on x64 platforms, but they are significantly slower on x86.

On .NET Core 2.1, Blake2Fast uses an SSE4.1 SIMD-accelerated implementation for both BLAKE2b and BLAKE2s. On .NET Core 3.0, an AVX2 implementation of BLAKE2b is available (with SSE4.1 fallback for older processors), while BLAKE2s uses the same SSE4.1 implementation. These are faster than the .NET built-in algorithms on either processor architecture.

You can find more detailed comparisons between Blake2Fast and other .NET BLAKE2 implementations starting here. The short version is that Blake2Fast is the fastest and lowest-memory version of RFC-compliant BLAKE2 available for .NET.

Installation

Blake2Fast is available on NuGet

PM> Install-Package SauceControl.Blake2Fast

Usage

All-at-Once Hashing

The simplest and lightest-weight way to calculate a hash is the all-at-once ComputeHash method.

varhash=Blake2b.ComputeHash(data);

BLAKE2 supports variable digest lengths from 1 to 32 bytes for BLAKE2s or 1 to 64 bytes for BLAKE2b.

varhash=Blake2b.ComputeHash(42,data);

BLAKE2 also natively supports keyed hashing.

varhash=Blake2b.ComputeHash(key,data);

Incremental Hashing

BLAKE2 hashes can be incrementally updated if you do not have the data available all at once.

asyncTask<byte[]>ComputeHashAsync(Streamdata){varincHash=Blake2b.CreateIncrementalHasher();varbuffer=newbyte[4096];intbytesRead;while((bytesRead=awaitdata.ReadAsync(buffer,0,buffer.Length))>0)incHash.Update(newSpan<byte>(buffer,0,bytesRead));returnincHash.Finish();}

Allocation-Free Hashing

The output hash digest can be written to an existing buffer to avoid allocating a new array each time. This is especially useful when performing an iterative hash, as might be used in a key derivation function.

byte[]DeriveBytes(stringpassword,byte[]salt){// Create key from password, then hash the salt using the keyvarpwkey=Blake2b.ComputeHash(Encoding.UTF8.GetBytes(password));varhbuff=Blake2b.ComputeHash(pwkey,salt);// Hash the hash lots of times, re-using the same bufferfor(inti=0;i<999_999;i++)Blake2b.ComputeAndWriteHash(pwkey,hbuff,hbuff);returnhbuff;}

System.Security.Cryptography Interop

For interoperating with code that uses System.Security.Cryptography primitives, Blake2Fast can create a HashAlgorithm wrapper. The wrapper inherits from HMAC in case keyed hashing is required.

HashAlgorithm is less efficient than the above methods, so use it only when necessary for compatibility.

byte[]WriteDataAndCalculateHash(byte[]data){using(varhashAlg=Blake2b.CreateHashAlgorithm())using(varfileStream=newFileStream(@"c:\data\output.bin",FileMode.Create))using(varcryptoStream=newCryptoStream(fileStream,hashAlg,CryptoStreamMode.Write)){cryptoStream.Write(data,0,data.Length);cryptoStream.FlushFinalBlock();returnhashAlg.Hash;}}

SIMD Intrinsics Warning

The X86 SIMD Intrinsics used in the .NET Core 2.1 build are not officially supported by Microsoft. Although the specific SSE Intrinsics used by Blake2Fast have been well-tested, the JIT support for the X86 Intrinsics in general is experimental in .NET Core 2.1.

If you are uncomfortable using unsupported functionality, you can make a custom build of Blake2Fast by removing the USE_INTRINSICS define constant in the project file.

This warning applies only to .NET Core 2.1; the older build targets use only the scalar code, and SIMD intrinsics will be fully supported on .NET Core 3.0+.

About

Optimized BLAKE2 hashing implementations in C#

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages