Exemple #1
0
        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>);
        }
Exemple #2
0
        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);
            }
        }
Exemple #3
0
        /// <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>);
        }
Exemple #4
0
        /// <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;
        }
Exemple #5
0
        /// <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);
            }
        }
Exemple #6
0
        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;
        }
Exemple #7
0
        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));
            }
        }