public void Finish(ArraySegment <byte> output) { if (output.Array == null) { throw new ArgumentNullException("output.Array"); } if (output.Count != 64) { throw new ArgumentException("output.Count must be 64"); } Update(_padding, 0, _padding.Length); ByteIntegerConverter.Array16LoadBigEndian64(out Array16 <ulong> block, _buffer, 0); CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length); var bytesInBuffer = (int)_totalBytes & (BlockSize - 1); if (bytesInBuffer > BlockSize - 16) { Sha512Internal.Core(out _state, ref _state, ref block); block = default(Array16 <ulong>); } block.x15 = (_totalBytes - 1) * 8; Sha512Internal.Core(out _state, ref _state, ref block); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 0, _state.x0); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 8, _state.x1); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 16, _state.x2); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 24, _state.x3); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 32, _state.x4); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 40, _state.x5); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 48, _state.x6); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 56, _state.x7); _state = default(Array8 <ulong>); }
public void Update(byte[] data, int offset, int count) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (offset < 0) { throw new ArgumentOutOfRangeException(nameof(offset)); } if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count)); } if (data.Length - offset < count) { throw new ArgumentException("Requires offset + count <= data.Length"); } Array16 <ulong> block; var bytesInBuffer = (int)_totalBytes & (BlockSize - 1); _totalBytes += (uint)count; if (_totalBytes >= ulong.MaxValue / 8) { throw new InvalidOperationException("Too much data"); } // Fill existing buffer if (bytesInBuffer != 0) { var toCopy = Math.Min(BlockSize - bytesInBuffer, count); Buffer.BlockCopy(data, offset, _buffer, bytesInBuffer, toCopy); offset += toCopy; count -= toCopy; bytesInBuffer += toCopy; if (bytesInBuffer == BlockSize) { ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer, 0); Sha512Internal.Core(out _state, ref _state, ref block); CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length); bytesInBuffer = 0; } } // Hash complete blocks without copying while (count >= BlockSize) { ByteIntegerConverter.Array16LoadBigEndian64(out block, data, offset); Sha512Internal.Core(out _state, ref _state, ref block); offset += BlockSize; count -= BlockSize; } // Copy remainder into buffer if (count > 0) { Buffer.BlockCopy(data, offset, _buffer, bytesInBuffer, count); } }
/// <summary> /// Finalizes SHA-512 hashing /// </summary> /// <param name="output">Output buffer</param> public void Finalize(ArraySegment <byte> output) { Contract.Requires <ArgumentNullException>(output.Array != null); Contract.Requires <ArgumentException>(output.Count == 64); Update(_padding, 0, _padding.Length); Array16 <ulong> block; ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer, 0); CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length); int bytesInBuffer = (int)_totalBytes & (BlockSize - 1); if (bytesInBuffer > BlockSize - 16) { Sha512Internal.Core(out _state, ref _state, ref block); block = default(Array16 <ulong>); } block.x15 = (_totalBytes - 1) * 8; Sha512Internal.Core(out _state, ref _state, ref block); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 0, _state.x0); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 8, _state.x1); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 16, _state.x2); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 24, _state.x3); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 32, _state.x4); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 40, _state.x5); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 48, _state.x6); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 56, _state.x7); _state = default(Array8 <ulong>); }
/// <summary> /// Finalizes SHA-512 hashing /// </summary> /// <param name="output"> /// Output buffer /// </param> public void Finalize(ArraySegment <byte> output) { Update(Padding, 0, Padding.Length); Array16 <ulong> block; ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer, 0); CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length); var bytesInBuffer = (int)_totalBytes & (BlockSize - 1); if (bytesInBuffer > BlockSize - 16) { Sha512Internal.Core(out _state, ref _state, ref block); block = default; } block.X15 = (_totalBytes - 1) * 8; Sha512Internal.Core(out _state, ref _state, ref block); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 0, _state.X0); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 8, _state.X1); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 16, _state.X2); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 24, _state.X3); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 32, _state.X4); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 40, _state.X5); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 48, _state.X6); ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 56, _state.X7); _state = default; }
/// <summary> /// Updates internal state with data from the provided array. /// </summary> /// <param name="data">Array of bytes</param> /// <param name="index">Offset of byte sequence</param> /// <param name="length">Sequence length</param> public void Update(byte[] data, int index, int length) { // Contract.Requires<ArgumentNullException>(data != null); if (data == null) { throw new ArgumentNullException(); } // Contract.Requires<ArgumentOutOfRangeException>(index >=0 && length >= 0); if (index < 0 || length < 0) { throw new ArgumentOutOfRangeException(); } // Contract.Requires<ArgumentException>((index + length) <= data.Length); if ((index + length) > data.Length) { throw new ArgumentException(); } Array16 <ulong> block; int bytesInBuffer = (int)_totalBytes & (BlockSize - 1); _totalBytes += (uint)length; if (_totalBytes >= ulong.MaxValue / 8) { throw new InvalidOperationException("Too much data"); } // Fill existing buffer if (bytesInBuffer != 0) { var toCopy = Math.Min(BlockSize - bytesInBuffer, length); Buffer.BlockCopy(data, index, _buffer, bytesInBuffer, toCopy); index += toCopy; length -= toCopy; bytesInBuffer += toCopy; if (bytesInBuffer == BlockSize) { ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer, 0); Sha512Internal.Core(out _state, ref _state, ref block); CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length); bytesInBuffer = 0; } } // Hash complete blocks without copying while (length >= BlockSize) { ByteIntegerConverter.Array16LoadBigEndian64(out block, data, index); Sha512Internal.Core(out _state, ref _state, ref block); index += BlockSize; length -= BlockSize; } // Copy remainder into buffer if (length > 0) { Buffer.BlockCopy(data, index, _buffer, bytesInBuffer, length); } }
public void Finish(Span <byte> output) { if (output.Length != 64) { throw new ArgumentException("output.Count must be 64"); } Update(_padding); Array16 <ulong> block; ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer); CryptoBytes.Wipe(_buffer, 0, _buffer.Length); int bytesInBuffer = (int)_totalBytes & (BlockSize - 1); if (bytesInBuffer > BlockSize - 16) { Sha512Internal.Core(out _state, in _state, in block); block = default; } block = new Array16 <ulong>( block.x0, block.x1, block.x2, block.x3, block.x4, block.x5, block.x6, block.x7, block.x8, block.x9, block.x10, block.x11, block.x12, block.x13, block.x14, (_totalBytes - 1) * 8); Sha512Internal.Core(out _state, in _state, in block); BinaryPrimitives.WriteUInt64BigEndian(output.Slice(0), _state.x0); BinaryPrimitives.WriteUInt64BigEndian(output.Slice(8), _state.x1); BinaryPrimitives.WriteUInt64BigEndian(output.Slice(16), _state.x2); BinaryPrimitives.WriteUInt64BigEndian(output.Slice(24), _state.x3); BinaryPrimitives.WriteUInt64BigEndian(output.Slice(32), _state.x4); BinaryPrimitives.WriteUInt64BigEndian(output.Slice(40), _state.x5); BinaryPrimitives.WriteUInt64BigEndian(output.Slice(48), _state.x6); BinaryPrimitives.WriteUInt64BigEndian(output.Slice(56), _state.x7); _state = default; }
public void Update(ReadOnlySpan <byte> data) { Array16 <ulong> block; int bytesInBuffer = (int)_totalBytes & (BlockSize - 1); _totalBytes += (uint)data.Length; var bufferSpan = _buffer.AsSpan(); if (_totalBytes >= ulong.MaxValue / 8) { throw new InvalidOperationException("Too much data"); } // Fill existing buffer if (bytesInBuffer != 0) { var toCopy = Math.Min(BlockSize - bytesInBuffer, data.Length); data.Slice(0, toCopy).CopyTo(bufferSpan.Slice(bytesInBuffer)); data = data.Slice(toCopy); bytesInBuffer += toCopy; if (bytesInBuffer == BlockSize) { ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer); Sha512Internal.Core(out _state, in _state, in block); CryptoBytes.Wipe(_buffer, 0, _buffer.Length); bytesInBuffer = 0; } } // Hash complete blocks without copying while (data.Length >= BlockSize) { ByteIntegerConverter.Array16LoadBigEndian64(out block, data); Sha512Internal.Core(out _state, in _state, in block); data = data.Slice(BlockSize); } // Copy remainder into buffer if (data.Length > 0) { data.CopyTo(bufferSpan.Slice(bytesInBuffer)); } }