// This function is defined as follows: // Func (S, i) = HMAC(S || i) ^ HMAC2(S || i) ^ ... ^ HMAC(iterations) (S || i) // where i is the block number. private byte[] Func() { byte[] temp = new byte[_salt.Length + sizeof(uint)]; Buffer.BlockCopy(_salt, 0, temp, 0, _salt.Length); Helpers.WriteInt(_block, temp, _salt.Length); byte[] ui = ArrayPool <byte> .Shared.Rent(_blockSize); try { Span <byte> uiSpan = new Span <byte>(ui, 0, _blockSize); if (!_hmac.TryComputeHash(temp, uiSpan, out int bytesWritten) || bytesWritten != _blockSize) { throw new CryptographicException(); } byte[] ret = new byte[_blockSize]; uiSpan.CopyTo(ret); for (int i = 2; i <= _iterations; i++) { if (!_hmac.TryComputeHash(uiSpan, uiSpan, out bytesWritten) || bytesWritten != _blockSize) { throw new CryptographicException(); } for (int j = 0; j < _blockSize; j++) { ret[j] ^= ui[j]; } } // increment the block count. _block++; return(ret); } finally { Array.Clear(ui, 0, _blockSize); ArrayPool <byte> .Shared.Return(ui); } }
// This function is defined as follows: // Func (S, i) = HMAC(S || i) | HMAC2(S || i) | ... | HMAC(iterations) (S || i) // where i is the block number. private byte[] Func() { byte[] temp = new byte[_salt.Length + sizeof(uint)]; Buffer.BlockCopy(_salt, 0, temp, 0, _salt.Length); Helpers.WriteInt(_block, temp, _salt.Length); temp = _hmacSha1.ComputeHash(temp); byte[] ret = temp; for (int i = 2; i <= _iterations; i++) { temp = _hmacSha1.ComputeHash(temp); for (int j = 0; j < BlockSize; j++) { ret[j] ^= temp[j]; } } // increment the block count. _block++; return(ret); }
// This function is defined as follows: // Func (S, i) = HMAC(S || i) ^ HMAC2(S || i) ^ ... ^ HMAC(iterations) (S || i) // where i is the block number. private void Func() { Helpers.WriteInt(_block, _salt, _salt.Length - sizeof(uint)); Debug.Assert(_blockSize == _buffer.Length); // The biggest _blockSize we have is from SHA512, which is 64 bytes. // Since we have a closed set of supported hash algorithms (OpenHmac()) // we can know this always fits. // Span <byte> uiSpan = stackalloc byte[64]; uiSpan = uiSpan.Slice(0, _blockSize); if (!_hmac.TryComputeHash(_salt, uiSpan, out int bytesWritten) || bytesWritten != _blockSize) { throw new CryptographicException(); } uiSpan.CopyTo(_buffer); for (int i = 2; i <= _iterations; i++) { if (!_hmac.TryComputeHash(uiSpan, uiSpan, out bytesWritten) || bytesWritten != _blockSize) { throw new CryptographicException(); } for (int j = _buffer.Length - 1; j >= 0; j--) { _buffer[j] ^= uiSpan[j]; } } // increment the block count. _block++; }