public static uint Verify_Simple_Sha2_256(ReadOnlySpan <byte> key, ReadOnlySpan <byte> value) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (key.Length != 32) { throw new ArgumentOutOfRangeException(nameof(key)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } if (value.Length != 32) { throw new ArgumentOutOfRangeException(nameof(value)); } Span <byte> buffer = stackalloc byte[64]; byte[] hash; { BytesOperations.Copy(key, buffer, key.Length); BytesOperations.Copy(value, buffer.Slice(key.Length), value.Length); hash = Sha2_256.ComputeHash(buffer); } uint count = 0; for (int i = 0; i < 32; i++) { for (int j = 0; j < 8; j++) { if (((hash[i] << j) & 0x80) == 0) { count++; } else { goto End; } } } End: return(count); }
public static bool TryComputeHash(ReadOnlySequence <byte> sequence, ReadOnlySpan <byte> key, Span <byte> destination) { if (destination.Length < 32) { throw new ArgumentOutOfRangeException(nameof(destination)); } Span <byte> extendedKey = stackalloc byte[_blockLength]; if (key.Length > _blockLength) { Sha2_256.TryComputeHash(key, extendedKey); } else { BytesOperations.Copy(key, extendedKey, Math.Min(key.Length, extendedKey.Length)); } Span <byte> ixor = stackalloc byte[_blockLength]; BytesOperations.Xor(_ipad, extendedKey, ixor); Span <byte> oxor = stackalloc byte[_blockLength]; BytesOperations.Xor(_opad, extendedKey, oxor); Span <byte> ihash = stackalloc byte[32]; using (var incrementalHash = IncrementalHash.CreateHash(HashAlgorithmName.SHA256)) { incrementalHash.AppendData(ixor); foreach (var segment in sequence) { incrementalHash.AppendData(segment.Span); } incrementalHash.TryGetHashAndReset(ihash, out _); } using (var incrementalHash = IncrementalHash.CreateHash(HashAlgorithmName.SHA256)) { incrementalHash.AppendData(oxor); incrementalHash.AppendData(ihash); return(incrementalHash.TryGetHashAndReset(destination, out _)); } }