Skip to content

Commit 38b458d

Browse files
committed
refactor: Crc32C
1 parent b76c863 commit 38b458d

File tree

5 files changed

+29
-67
lines changed

5 files changed

+29
-67
lines changed

src/CryptoBase/Digests/CRC32C/Crc32CX86.cs renamed to src/CryptoBase/Digests/CRC32C/Crc32C.cs

Lines changed: 22 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
1+
using System.Numerics;
2+
13
namespace CryptoBase.Digests.CRC32C;
24

3-
/// <summary>
4-
/// Same as <see cref="Crc32X86" /> , but different constants.
5-
/// </summary>
6-
public class Crc32CX86 : IHash
5+
public class Crc32C : IHash
76
{
87
public string Name => @"CRC-32C";
98

109
public int Length => HashConstants.Crc32Length;
1110

1211
public int BlockSize => HashConstants.Crc32BlockSize;
1312

14-
public static bool IsSupport => Sse42.IsSupported || Sse2.IsSupported && Pclmulqdq.IsSupported;
15-
1613
private uint _state;
1714

18-
public Crc32CX86()
15+
public Crc32C()
1916
{
2017
Reset();
2118
}
@@ -28,20 +25,19 @@ public void UpdateFinal(ReadOnlySpan<byte> origin, Span<byte> destination)
2825

2926
public void Update(ReadOnlySpan<byte> source)
3027
{
28+
if (Sse42.X64.IsSupported || Crc32.Arm64.IsSupported)
29+
{
30+
UpdateDefault(source);
31+
return;
32+
}
33+
3134
if (Sse2.IsSupported && Pclmulqdq.IsSupported && source.Length >= 64)
3235
{
3336
_state = Update(source, _state);
3437
source = source.Slice(source.Length - source.Length % 0x10);
3538
}
3639

37-
if (Sse42.IsSupported)
38-
{
39-
UpdateSse42(source);
40-
}
41-
else
42-
{
43-
_state = ~Crc32Table.Crc32C.Append(~_state, source);
44-
}
40+
UpdateDefault(source);
4541
}
4642

4743
public void GetHash(Span<byte> destination)
@@ -151,53 +147,42 @@ private static uint Update(ReadOnlySpan<byte> buffer, uint crc)
151147
}
152148

153149
[MethodImpl(MethodImplOptions.AggressiveInlining)]
154-
private void UpdateSse42(ReadOnlySpan<byte> source)
150+
private void UpdateDefault(ReadOnlySpan<byte> source)
155151
{
156152
int length = source.Length;
157153
int offset = 0;
158154
ref byte sourceRef = ref source.GetReference();
159-
ref uint state = ref _state;
160155

161-
if (Sse42.X64.IsSupported)
156+
if (Sse42.X64.IsSupported || Crc32.Arm64.IsSupported)
162157
{
163158
while (length >= 8)
164159
{
165160
ref ulong data = ref Unsafe.As<byte, ulong>(ref Unsafe.Add(ref sourceRef, offset));
166-
state = (uint)Sse42.X64.Crc32(state, data);
161+
_state = BitOperations.Crc32C(_state, data);
167162
offset += 8;
168163
length -= 8;
169164
}
170-
171-
if (length >= 4)
172-
{
173-
ref uint data = ref Unsafe.As<byte, uint>(ref Unsafe.Add(ref sourceRef, offset));
174-
state = Sse42.Crc32(state, data);
175-
offset += 4;
176-
length -= 4;
177-
}
178165
}
179-
else
166+
167+
while (length >= 4)
180168
{
181-
while (length >= 4)
182-
{
183-
ref uint data = ref Unsafe.As<byte, uint>(ref Unsafe.Add(ref sourceRef, offset));
184-
state = Sse42.Crc32(state, data);
185-
offset += 4;
186-
length -= 4;
187-
}
169+
ref uint data = ref Unsafe.As<byte, uint>(ref Unsafe.Add(ref sourceRef, offset));
170+
_state = BitOperations.Crc32C(_state, data);
171+
offset += 4;
172+
length -= 4;
188173
}
189174

190175
if (length >= 2)
191176
{
192177
ref ushort data = ref Unsafe.As<byte, ushort>(ref Unsafe.Add(ref sourceRef, offset));
193-
state = Sse42.Crc32(state, data);
178+
_state = BitOperations.Crc32C(_state, data);
194179
offset += 2;
195180
length -= 2;
196181
}
197182

198183
if (length > 0)
199184
{
200-
state = Sse42.Crc32(state, Unsafe.Add(ref sourceRef, offset));
185+
_state = BitOperations.Crc32C(_state, Unsafe.Add(ref sourceRef, offset));
201186
}
202187
}
203188

src/CryptoBase/Digests/CRC32C/Crc32CSF.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/CryptoBase/Digests/DigestUtils.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,7 @@ private static IHash CreateCrc32()
3434
[MethodImpl(MethodImplOptions.AggressiveInlining)]
3535
private static IHash CreateCrc32C()
3636
{
37-
if (Crc32CX86.IsSupport)
38-
{
39-
return new Crc32CX86();
40-
}
41-
42-
return new Crc32CSF();
37+
return new Crc32C();
4338
}
4439

4540
[MethodImpl(MethodImplOptions.AggressiveInlining)]

test/CryptoBase.Benchmark/CRC32Benchmark.cs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,25 @@ public void Setup()
2020
}
2121

2222
[Benchmark(Baseline = true)]
23-
public void Crc32SF()
24-
{
25-
using var hasher = new Crc32SF();
26-
Span<byte> hash = stackalloc byte[hasher.Length];
27-
hasher.UpdateFinal(_randombytes, hash);
28-
}
29-
30-
[Benchmark]
31-
public void Crc32X86()
23+
public void Crc32C()
3224
{
33-
using var hasher = new Crc32X86();
25+
using Crc32C hasher = new();
3426
Span<byte> hash = stackalloc byte[hasher.Length];
3527
hasher.UpdateFinal(_randombytes, hash);
3628
}
3729

3830
[Benchmark]
39-
public void Crc32CSF()
31+
public void Crc32SF()
4032
{
41-
using var hasher = new Crc32CSF();
33+
using Crc32SF hasher = new();
4234
Span<byte> hash = stackalloc byte[hasher.Length];
4335
hasher.UpdateFinal(_randombytes, hash);
4436
}
4537

4638
[Benchmark]
47-
public void Crc32CX86()
39+
public void Crc32X86()
4840
{
49-
using var hasher = new Crc32CX86();
41+
using Crc32X86 hasher = new();
5042
Span<byte> hash = stackalloc byte[hasher.Length];
5143
hasher.UpdateFinal(_randombytes, hash);
5244
}

test/CryptoBase.Tests/CRC32Test.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using CryptoBase.DataFormatExtensions;
33
using CryptoBase.Digests;
44
using CryptoBase.Digests.CRC32;
5-
using CryptoBase.Digests.CRC32C;
65
using System.Text;
76

87
namespace CryptoBase.Tests;
@@ -73,7 +72,6 @@ public void CRC32(string message, string expected)
7372
[InlineData(@"5c6f1913817f054beaa45c911b141120ad3822a5d1d27c38362b0b0498bc1e82d7806444f7d25b2ac8581626b6c4c37811c3e5a85e6007fc4dce60e9ab257349281db35eeef273ce326942deec8f9f046240e61072b32733e4be09e8753e53a2294b7bd7b3b1474fcd4bafa88ab0c8fc36ce4696ee093e4a3300064303430eff32d41657783a660fe72086f94db23b194b1d96f44283323a67e80e475c1afe08b910a1e2e5c242a5ed33c9a26135a66ecb766e514f20bd4a631d80f886408d7507238f5b505b2cc1df4092f4c400955de89dfc2136bad7e292ba6091c19c64d86cfa6870bb35af7930a730362b0c0deace27b46f48cdccd02231c1f22f8029", @"83c1318e")]
7473
public void CRC32C(string message, string expected)
7574
{
76-
TestC(new Crc32CSF(), message, expected);
7775
TestC(DigestUtils.Create(DigestType.Crc32C), message, expected);
7876
}
7977
}

0 commit comments

Comments
 (0)