Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions ArgonBenchmarks/ArgonBenchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,19 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netstandard2.0;net462;net6.0</TargetFrameworks>
<TargetFrameworks>net6.0</TargetFrameworks>
<DebugType>embedded</DebugType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.13.1" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Konscious.Security.Cryptography.Argon2\Konscious.Security.Cryptography.Argon2.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net46'">
<PackageReference Include="BenchmarkDotNet">
<Version>0.13.*</Version>
</PackageReference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="BenchmarkDotNet">
<Version>0.13.*</Version>
</PackageReference>
</ItemGroup>

</Project>
40 changes: 30 additions & 10 deletions ArgonBenchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
using BenchmarkDotNet.Diagnosers;
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Diagnostics.Windows.Configs;
using System.Runtime.InteropServices;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Environments;

namespace ArgonBenchmarks
{
Expand All @@ -21,10 +22,29 @@ public static void Main()
}
}

public class Config : ManualConfig
{
public Config()
{
//Run with intrinsics disabled
AddJob(
Job.Default
.WithEnvironmentVariable(new EnvironmentVariable("COMPlus_EnableSSE2", "0"))
.WithRuntime(CoreRuntime.Core60)
.AsBaseline());

// Run with intrinsics
AddJob(
Job.Default.WithRuntime(CoreRuntime.Core60));

//AddJob(
// Job.Default.WithRuntime(CoreRuntime.Core50));
}
}

[Config(typeof(Config))]
[MemoryDiagnoser]
[SimpleJob(RuntimeMoniker.Net462)]
[SimpleJob(RuntimeMoniker.Net60)]
[JsonExporterAttribute.BriefCompressed, CsvExporter(BenchmarkDotNet.Exporters.Csv.CsvSeparator.CurrentCulture)]
[JsonExporterAttribute.BriefCompressed, CsvExporter(BenchmarkDotNet.Exporters.Csv.CsvSeparator.CurrentCulture), HtmlExporter]
public class ArgonBenchmarks
{
private readonly string _toHash = "iamapasswordthatneedshashing";
Expand Down Expand Up @@ -55,19 +75,19 @@ public void IterationSetup()
public int RamKilobytes { get; set; }

//CN - Full
public IEnumerable<int> RamKilobytesValues => Enumerable.Range(0, 16)
.Select(x => x * 1024 * 4 + 65536)
.Concat(new[] { 1048576, 4 * 1048576 });
//public IEnumerable<int> RamKilobytesValues => Enumerable.Range(0, 16)
// .Select(x => x * 1024 * 4 + 65536)
// .Concat(new[] { 1048576, 4 * 1048576 });

//CN -- Quick
//public IEnumerable<int> RamKilobytesValues => Enumerable.Range(0, 4).Select(x => x * 1024 * 8 + 65536);
public IEnumerable<int> RamKilobytesValues => Enumerable.Range(0, 4).Select(x => x * 1024 * 8 + 65536);


//CN -- Full
public IEnumerable<int> IterationValues => Enumerable.Range(1, 5).Select(x => 2*x - 1);
//public IEnumerable<int> IterationValues => Enumerable.Range(1, 5).Select(x => 2*x - 1);

//CN -- Quick
//public IEnumerable<int> IterationValues => Enumerable.Range(1, 2).Select(x => x + (x - 1) * 4);
public IEnumerable<int> IterationValues => Enumerable.Range(1, 2).Select(x => x + (x - 1) * 4);
}

[MemoryDiagnoser, ThreadingDiagnoser]
Expand Down
16 changes: 16 additions & 0 deletions Blake2Benchmarks/Blake2Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net6.0</TargetFrameworks>
<DebugType>embedded</DebugType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Konscious.Security.Cryptography.Blake2\Konscious.Security.Cryptography.Blake2.csproj" />
</ItemGroup>
</Project>
42 changes: 42 additions & 0 deletions Blake2Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using Konscious.Security.Cryptography;
using System;

BenchmarkRunner.Run<BlakeSimdBenchmark>();

var b = new BlakeSimdBenchmark() { Size = 32_000_000 };
b.Setup();
b.GetHash();

[MemoryDiagnoser]
[SimpleJob(RuntimeMoniker.Net60)]
[JsonExporterAttribute.BriefCompressed, CsvExporter(BenchmarkDotNet.Exporters.Csv.CsvSeparator.CurrentCulture), HtmlExporter]
public class BlakeSimdBenchmark
{
private readonly HMACBlake2B _blake2b = new HMACBlake2B(256/8);
private byte[] _data;

[GlobalSetup]
public void Setup()
{
Random rnd = new Random(42);
_data = new byte[Size];
rnd.NextBytes(_data);
}

[Params(
(int)3,
(int)1E+2, // 100 bytes
(int)1E+3, // 1 000 bytes = 1 KB
(int)1E+4 // 10 000 bytes = 10 KB
)]
public int Size { get; set; }

[Benchmark]
public byte[] GetHash()
{
return _blake2b.ComputeHash(_data);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<OutputType>Library</OutputType>
<PackageId>Konscious.Security.Cryptography.Argon2.Test</PackageId>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<TargetFrameworks>net5</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1;net6.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../Konscious.Security.Cryptography.Argon2/Konscious.Security.Cryptography.Argon2.csproj" />
Expand All @@ -19,8 +19,5 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.3">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
</ItemGroup>
</Project>
19 changes: 15 additions & 4 deletions Konscious.Security.Cryptography.Argon2/Argon2Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ namespace Konscious.Security.Cryptography
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;


#if NET6_0_OR_GREATER
using System.Runtime.Intrinsics.X86;
#endif

internal abstract class Argon2Core
{
Expand Down Expand Up @@ -89,6 +90,7 @@ private static void XorLanes(Argon2Lane[] lanes)

for (var b = 0; b < 128; ++b)
{
// TODO Is System.Buffers BinaryConverter faster? / SIMD
if (!BitConverter.IsLittleEndian)
{
block[b] = (block[b] >> 56) ^
Expand All @@ -115,13 +117,20 @@ private byte[] Finalize(Argon2Lane[] lanes)

ModifiedBlake2.Blake2Prime(lanes[0][1], ds, _tagLine);
var result = new byte[_tagLine];
var tmp = MemoryMarshal.Cast<ulong, byte>(lanes[0][1].Span).Slice(0,result.Length);
var tmp = MemoryMarshal.Cast<ulong, byte>(lanes[0][1].Span).Slice(0, result.Length);
tmp.CopyTo(result);
return result;
}

internal unsafe static void Compress(Span<ulong> dest, Span<ulong> refb, Span<ulong> prev)
internal static unsafe void Compress(Span<ulong> dest, ReadOnlySpan<ulong> refb, ReadOnlySpan<ulong> prev)
{
#if NET6_0_OR_GREATER
if (Avx2.IsSupported && BitConverter.IsLittleEndian)
{
Argon2CoreIntrinsics.Compress(dest, refb, prev);
return;
}
#endif
var tmpblock = stackalloc ulong[dest.Length];
for (var n = 0; n < 128; ++n)
{
Expand Down Expand Up @@ -248,6 +257,7 @@ private static int IndexAlpha(bool sameLane, uint pseudoRand, int laneLength, in
}

#if DEBUG

private static void DebugWrite(Span<ulong> data)
{
int offset = 0;
Expand All @@ -265,6 +275,7 @@ private static void DebugWrite(Span<ulong> data)
Console.WriteLine();
Console.WriteLine();
}

#endif

private readonly int _tagLine;
Expand Down
90 changes: 90 additions & 0 deletions Konscious.Security.Cryptography.Argon2/Argon2CoreIntrinsics.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#if NET6_0_OR_GREATER
namespace Konscious.Security.Cryptography;

using System;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.X86;
using System.Runtime.Intrinsics;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Buffers.Binary;

internal static class Argon2CoreIntrinsics
{
public static void XorLanes(ReadOnlySpan<Argon2Lane> lanes)
{
Debug.Assert(Avx2.IsSupported);

var data = lanes[0][lanes[0].BlockCount - 1].Span;
var dataVectors = MemoryMarshal.Cast<ulong, Vector256<ulong>>(data);

foreach (var lane in lanes[1..])
{
var block = lane[lane.BlockCount - 1].Span;

if (BitConverter.IsLittleEndian)
{
var blockVectors = MemoryMarshal.Cast<ulong, Vector256<ulong>>(block);
for (int i = 0; i < 32; i++)
{
Avx2.Xor(dataVectors[i], blockVectors[i]);
}
}
else
{
for (var b = 0; b < 128; ++b)
{
block[b] = BinaryPrimitives.ReverseEndianness(block[b]);

data[b] ^= block[b];
}
}
}
}

public static void Compress(Span<ulong> dest, ReadOnlySpan<ulong> refBlock, ReadOnlySpan<ulong> prevBlock)
{
Debug.Assert(Avx2.IsSupported);
Debug.Assert(dest.Length == 128);

Span<ulong> state = stackalloc ulong[dest.Length];
Span<Vector256<ulong>> stateVectors = MemoryMarshal.Cast<ulong, Vector256<ulong>>(state);
ref Vector256<ulong> refState = ref MemoryMarshal.GetReference(stateVectors);

ref Vector256<ulong> refB = ref Unsafe.As<ulong, Vector256<ulong>>(ref MemoryMarshal.GetReference(refBlock));
ref Vector256<ulong> refPrev = ref Unsafe.As<ulong,Vector256<ulong>>(ref MemoryMarshal.GetReference(prevBlock));
ref Vector256<ulong> refDest = ref Unsafe.As<ulong, Vector256<ulong>>(ref MemoryMarshal.GetReference(dest));

for (var n = 0; n < stateVectors.Length; ++n)
{
Unsafe.Add(ref refState, n) = Avx2.Xor(Unsafe.Add(ref refB, n), Unsafe.Add(ref refPrev, n));
Unsafe.Add(ref refDest, n) = Avx2.Xor(Unsafe.Add(ref refState, n), Unsafe.Add(ref refDest, n));
}

//ModifiedBlake2Intrinsics.DoRoundColumns(stateVectors[..16]);
//ModifiedBlake2Intrinsics.DoRoundColumns(stateVectors[16..]);

//ModifiedBlake2Intrinsics.DoRoundRows(stateVectors);
//ModifiedBlake2Intrinsics.DoRoundRows(stateVectors[8..]);

//ModifiedBlake2Intrinsics.ReOrder(stateVectors[..16]);
//ModifiedBlake2Intrinsics.ReOrder(stateVectors[16..]);

for (int i = 0; i < 4; i++)
{
ModifiedBlake2Intrinsics.BLAKE2_ROUND_1(ref stateVectors[8 * i + 0], ref stateVectors[8 * i + 4], ref stateVectors[8 * i + 1], ref stateVectors[8 * i + 5], ref stateVectors[8 * i + 2], ref stateVectors[8 * i + 6], ref stateVectors[8 * i + 3], ref stateVectors[8 * i + 7]);
}

for (int i = 0; i < 4; i++)
{
ModifiedBlake2Intrinsics.BLAKE2_ROUND_2(ref stateVectors[0 + i], ref stateVectors[4 + i], ref stateVectors[8 + i], ref stateVectors[12 + i], ref stateVectors[16 + i], ref stateVectors[20 + i], ref stateVectors[24 + i], ref stateVectors[28 + i]);
}

for (int i = 0; i < stateVectors.Length; i++)
{
Unsafe.Add(ref refDest, i) = Avx2.Xor(Unsafe.Add(ref refDest, i), Unsafe.Add(ref refState, i));
}
}
}

#endif
Loading