1+ using System . Numerics ;
2+
13namespace 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
0 commit comments