private byte[] GetHash(byte[] message)
        {
            var h = new byte[BlockSize];

            _n     = new byte[BlockSize];
            _sigma = new byte[BlockSize];
            Array.Copy(_iv, h, BlockSize);

            byte[] n0 = new byte[BlockSize];

            IEnumerable <IEnumerable <byte> > blocks = message.Batch(BlockSize).ToArray();

            blocks.Where(block => block.Count() >= BlockSize).Reverse().ForEach(block =>
            {
                h      = G_n(_n, h, block);
                _n     = _n.AddModulo64(BitConverter.GetBytes((long)64).Reverse().ToArray());
                _sigma = _sigma.AddModulo64(block.ToArray());
            });

            var lastBlockSize = blocks.Last().Count();

            byte[] pad = MoreEnumerable
                         .Append(new byte[lastBlockSize < BlockSize ? BlockSize - 1 - lastBlockSize : BlockSize - 1], (byte)1).ToArray();

            byte[] m = pad
                       .Concat(blocks.Where(block => block.Count() < BlockSize).DefaultIfEmpty(new byte[0]).First()).ToArray();

            h = G_n(_n, h, m);

            var msgLen = BitConverter.GetBytes((long)(message.Length * 8)).Reverse();

            _n = _n.AddModulo64(msgLen.ToArray());

            _sigma = _sigma.AddModulo64(m);

            h = G_n(n0, h, _n);
            h = G_n(n0, h, _sigma);

            return(h);
        }