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); }