| File: System\Security\Cryptography\SHA512.cs | Web Access |
| Project: src\runtime\src\libraries\System.Security.Cryptography\src\System.Security.Cryptography.csproj (System.Security.Cryptography) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Threading; using System.Threading.Tasks; using Internal.Cryptography; namespace System.Security.Cryptography { // // If you change anything in this class, you must make the same change in the other *Provider classes. This is a pain but given that the // preexisting contract from the .NET Framework locks all of these into deriving directly from the abstract HashAlgorithm class, // it can't be helped. // public abstract class SHA512 : HashAlgorithm { private sealed class HashTrait : IHashStatic { static int IHashStatic.HashSizeInBytes => HashSizeInBytes; static string IHashStatic.HashAlgorithmName => HashAlgorithmNames.SHA512; static bool IHashStatic.IsSupported => true; } /// <summary> /// The hash size produced by the SHA512 algorithm, in bits. /// </summary> public const int HashSizeInBits = 512; /// <summary> /// The hash size produced by the SHA512 algorithm, in bytes. /// </summary> public const int HashSizeInBytes = HashSizeInBits / 8; protected SHA512() { HashSizeValue = HashSizeInBits; } public static new SHA512 Create() => new Implementation(); [Obsolete(Obsoletions.CryptoStringFactoryMessage, DiagnosticId = Obsoletions.CryptoStringFactoryDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [RequiresUnreferencedCode(CryptoConfig.CreateFromNameUnreferencedCodeMessage)] public static new SHA512? Create(string hashName) => (SHA512?)CryptoConfig.CreateFromName(hashName); /// <summary> /// Computes the hash of data using the SHA512 algorithm. /// </summary> /// <param name="source">The data to hash.</param> /// <returns>The hash of the data.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="source" /> is <see langword="null" />. /// </exception> public static byte[] HashData(byte[] source) => HashStatic<HashTrait>.HashData(source); /// <summary> /// Computes the hash of data using the SHA512 algorithm. /// </summary> /// <param name="source">The data to hash.</param> /// <returns>The hash of the data.</returns> public static byte[] HashData(ReadOnlySpan<byte> source) => HashStatic<HashTrait>.HashData(source); /// <summary> /// Computes the hash of data using the SHA512 algorithm. /// </summary> /// <param name="source">The data to hash.</param> /// <param name="destination">The buffer to receive the hash value.</param> /// <returns>The total number of bytes written to <paramref name="destination" />.</returns> /// <exception cref="ArgumentException"> /// The buffer in <paramref name="destination"/> is too small to hold the calculated hash /// size. The SHA1 algorithm always produces a 512-bit hash, or 64 bytes. /// </exception> public static int HashData(ReadOnlySpan<byte> source, Span<byte> destination) { return HashStatic<HashTrait>.HashData(source, destination); } /// <summary> /// Attempts to compute the hash of data using the SHA512 algorithm. /// </summary> /// <param name="source">The data to hash.</param> /// <param name="destination">The buffer to receive the hash value.</param> /// <param name="bytesWritten"> /// When this method returns, the total number of bytes written into <paramref name="destination"/>. /// </param> /// <returns> /// <see langword="false"/> if <paramref name="destination"/> is too small to hold the /// calculated hash, <see langword="true"/> otherwise. /// </returns> public static bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten) { return HashStatic<HashTrait>.TryHashData(source, destination, out bytesWritten); } /// <summary> /// Computes the hash of a stream using the SHA512 algorithm. /// </summary> /// <param name="source">The stream to hash.</param> /// <param name="destination">The buffer to receive the hash value.</param> /// <returns>The total number of bytes written to <paramref name="destination" />.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="source" /> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentException"> /// <p> /// The buffer in <paramref name="destination"/> is too small to hold the calculated hash /// size. The SHA512 algorithm always produces a 512-bit hash, or 64 bytes. /// </p> /// <p>-or-</p> /// <p> /// <paramref name="source" /> does not support reading. /// </p> /// </exception> public static int HashData(Stream source, Span<byte> destination) { return HashStatic<HashTrait>.HashData(source, destination); } /// <summary> /// Computes the hash of a stream using the SHA512 algorithm. /// </summary> /// <param name="source">The stream to hash.</param> /// <returns>The hash of the data.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="source" /> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="source" /> does not support reading. /// </exception> public static byte[] HashData(Stream source) => HashStatic<HashTrait>.HashData(source); /// <summary> /// Asynchronously computes the hash of a stream using the SHA512 algorithm. /// </summary> /// <param name="source">The stream to hash.</param> /// <param name="cancellationToken"> /// The token to monitor for cancellation requests. /// The default value is <see cref="System.Threading.CancellationToken.None" />. /// </param> /// <returns>The hash of the data.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="source" /> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="source" /> does not support reading. /// </exception> public static ValueTask<byte[]> HashDataAsync(Stream source, CancellationToken cancellationToken = default) { return HashStatic<HashTrait>.HashDataAsync(source, cancellationToken); } /// <summary> /// Asynchronously computes the hash of a stream using the SHA512 algorithm. /// </summary> /// <param name="source">The stream to hash.</param> /// <param name="destination">The buffer to receive the hash value.</param> /// <param name="cancellationToken"> /// The token to monitor for cancellation requests. /// The default value is <see cref="System.Threading.CancellationToken.None" />. /// </param> /// <returns>The total number of bytes written to <paramref name="destination" />.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="source" /> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentException"> /// <p> /// The buffer in <paramref name="destination"/> is too small to hold the calculated hash /// size. The SHA512 algorithm always produces a 512-bit hash, or 64 bytes. /// </p> /// <p>-or-</p> /// <p> /// <paramref name="source" /> does not support reading. /// </p> /// </exception> public static ValueTask<int> HashDataAsync( Stream source, Memory<byte> destination, CancellationToken cancellationToken = default) { return HashStatic<HashTrait>.HashDataAsync(source, destination, cancellationToken); } private sealed class Implementation : SHA512 { private readonly HashProvider _hashProvider; public Implementation() { _hashProvider = HashProviderDispenser.CreateHashProvider(HashAlgorithmNames.SHA512); HashSizeValue = _hashProvider.HashSizeInBytes * 8; } protected sealed override void HashCore(byte[] array, int ibStart, int cbSize) => _hashProvider.AppendHashData(array, ibStart, cbSize); protected sealed override void HashCore(ReadOnlySpan<byte> source) => _hashProvider.AppendHashData(source); protected sealed override byte[] HashFinal() => _hashProvider.FinalizeHashAndReset(); protected sealed override bool TryHashFinal(Span<byte> destination, out int bytesWritten) => _hashProvider.TryFinalizeHashAndReset(destination, out bytesWritten); public sealed override void Initialize() => _hashProvider.Reset(); protected sealed override void Dispose(bool disposing) { _hashProvider.Dispose(disposing); base.Dispose(disposing); } } } }