< Summary

Information
Class: Renci.SshNet.Security.Chaos.NaCl.Sha512
Assembly: Renci.SshNet
File(s): \home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\Chaos.NaCl\Sha512.cs
Line coverage
73%
Covered lines: 69
Uncovered lines: 25
Coverable lines: 94
Total lines: 132
Line coverage: 73.4%
Branch coverage
57%
Covered branches: 15
Total branches: 26
Branch coverage: 57.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.cctor()100%1100%
.ctor()100%1100%
Init()100%1100%
Update(...)0%20%
Update(...)66.66%1872.5%
Finish(...)50%676.92%
Finish()100%1100%
Hash(...)100%10%
Hash(...)100%1100%

File(s)

\home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\Chaos.NaCl\Sha512.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using Renci.SshNet.Security.Chaos.NaCl.Internal;
 4
 5namespace Renci.SshNet.Security.Chaos.NaCl
 6{
 7    internal class Sha512
 8    {
 9        private Array8<UInt64> _state;
 10        private readonly byte[] _buffer;
 11        private ulong _totalBytes;
 12        public const int BlockSize = 128;
 413        private static readonly byte[] _padding = new byte[] { 0x80 };
 14
 1115        public Sha512()
 1116        {
 1117            _buffer = new byte[BlockSize];//todo: remove allocation
 1118            Init();
 1119        }
 20
 21        public void Init()
 1322        {
 1323            Sha512Internal.Sha512Init(out _state);
 1324            _totalBytes = 0;
 1325        }
 26
 27        public void Update(ArraySegment<byte> data)
 028        {
 029            if (data.Array == null)
 030                throw new ArgumentNullException("data.Array");
 031            Update(data.Array, data.Offset, data.Count);
 032        }
 33
 34        public void Update(byte[] data, int offset, int count)
 3535        {
 3536            if (data == null)
 037                throw new ArgumentNullException("data");
 3538            if (offset < 0)
 039                throw new ArgumentOutOfRangeException("offset");
 3540            if (count < 0)
 041                throw new ArgumentOutOfRangeException("count");
 3542            if (data.Length - offset < count)
 043                throw new ArgumentException("Requires offset + count <= data.Length");
 44
 45            Array16<ulong> block;
 3546            int bytesInBuffer = (int)_totalBytes & (BlockSize - 1);
 3547            _totalBytes += (uint)count;
 48
 3549            if (_totalBytes >= ulong.MaxValue / 8)
 050                throw new InvalidOperationException("Too much data");
 51            // Fill existing buffer
 3552            if (bytesInBuffer != 0)
 2253            {
 2254                var toCopy = Math.Min(BlockSize - bytesInBuffer, count);
 2255                Buffer.BlockCopy(data, offset, _buffer, bytesInBuffer, toCopy);
 2256                offset += toCopy;
 2257                count -= toCopy;
 2258                bytesInBuffer += toCopy;
 2259                if (bytesInBuffer == BlockSize)
 260                {
 261                    ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer, 0);
 262                    Sha512Internal.Core(out _state, ref _state, ref block);
 263                    CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length);
 264                    bytesInBuffer = 0;
 265                }
 2266            }
 67            // Hash complete blocks without copying
 3568            while (count >= BlockSize)
 069            {
 070                ByteIntegerConverter.Array16LoadBigEndian64(out block, data, offset);
 071                Sha512Internal.Core(out _state, ref _state, ref block);
 072                offset += BlockSize;
 073                count -= BlockSize;
 074            }
 75            // Copy remainder into buffer
 3576            if (count > 0)
 1577            {
 1578                Buffer.BlockCopy(data, offset, _buffer, bytesInBuffer, count);
 1579            }
 3580        }
 81
 82        public void Finish(ArraySegment<byte> output)
 1383        {
 1384            if (output.Array == null)
 085                throw new ArgumentNullException("output.Array");
 1386            if (output.Count != 64)
 087                throw new ArgumentException("output.Count must be 64");
 88
 1389            Update(_padding, 0, _padding.Length);
 90            Array16<ulong> block;
 1391            ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer, 0);
 1392            CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length);
 1393            int bytesInBuffer = (int)_totalBytes & (BlockSize - 1);
 1394            if (bytesInBuffer > BlockSize - 16)
 095            {
 096                Sha512Internal.Core(out _state, ref _state, ref block);
 097                block = default(Array16<ulong>);
 098            }
 1399            block.x15 = (_totalBytes - 1) * 8;
 13100            Sha512Internal.Core(out _state, ref _state, ref block);
 101
 13102            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 0, _state.x0);
 13103            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 8, _state.x1);
 13104            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 16, _state.x2);
 13105            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 24, _state.x3);
 13106            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 32, _state.x4);
 13107            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 40, _state.x5);
 13108            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 48, _state.x6);
 13109            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 56, _state.x7);
 13110            _state = default(Array8<ulong>);
 13111        }
 112
 113        public byte[] Finish()
 13114        {
 13115            var result = new byte[64];
 13116            Finish(new ArraySegment<byte>(result));
 13117            return result;
 13118        }
 119
 120        internal static byte[] Hash(byte[] data)
 0121        {
 0122            return Hash(data, 0, data.Length);
 0123        }
 124
 125        internal static byte[] Hash(byte[] data, int offset, int count)
 7126        {
 7127            var hasher = new Sha512();
 7128            hasher.Update(data, offset, count);
 7129            return hasher.Finish();
 7130        }
 131    }
 132}