public KdfResult DeriveKey(BitString salt, string password, int c, int keyLen) { // Could check keyLen, but the allowed max is larger than an int allows, so we just force positive... if (keyLen <= 0) { return(new KdfResult("KeyLen must be greater than 0")); } var passwordBytes = Encoding.ASCII.GetBytes(password); var iterationsNeeded = keyLen.CeilingDivide(_hmac.OutputLength); var saltBytes = salt.GetPaddedBytes(); var t = new byte[GetNextMultiple(keyLen, _hmac.OutputLength) / 8]; var u = new byte[_hmac.OutputLength / 8]; var t_i = new byte[_hmac.OutputLength / 8]; _hmac.Init(passwordBytes); for (var i = 1; i <= iterationsNeeded; i++) { var iterationCounter = new byte[4]; iterationCounter[0] = (byte)(i >> 24); iterationCounter[1] = (byte)(i >> 16); iterationCounter[2] = (byte)(i >> 8); iterationCounter[3] = (byte)i; //Array.Copy(saltBytes, u, saltBytes.Length); //Array.Copy(iterationCounter, 0, u, saltBytes.Length, 4); Array.Clear(t_i, 0, t_i.Length); for (var j = 1; j <= c; j++) { _hmac.FastInit(); if (j == 1) { _hmac.Update(saltBytes, salt.BitLength); _hmac.Update(iterationCounter, iterationCounter.Length * 8); } else { _hmac.Update(u, u.Length * 8); } _hmac.Final(ref u); for (var k = 0; k < u.Length; k++) { t_i[k] ^= u[k]; } } Array.Copy(t_i, 0, t, (i - 1) * t_i.Length, t_i.Length); } return(new KdfResult(new BitString(t).GetMostSignificantBits(keyLen))); }
public HashResult HashMessage(BitString message, int outLen = 0) { var digest = new byte[48]; Init(); Update(message.GetPaddedBytes(), message.BitLength); Final(digest); return(new HashResult(new BitString(digest))); }
public MacResult Generate(BitString key, BitString message, int macLength = 0) { Init(key.GetPaddedBytes()); Update(message.GetPaddedBytes(), message.BitLength); var result = new byte[_processingLen / 8]; Final(ref result, 0); if (macLength == 0 || macLength == OutputLength) { return(new MacResult(new BitString(result))); } return(new MacResult(new BitString(result).GetMostSignificantBits(macLength))); }
public HashResult HashMessage(BitString message, int outLen = 0) { if (outLen == 0) { outLen = _bitLength; } // If outputBitLength is not a multiple of 8, make it one var requestedBitLength = outLen; if (outLen % 8 != 0) { outLen += 8 - (outLen % 8); } var digest = new byte[outLen / 8]; Init(); Update(message.GetPaddedBytes(), message.BitLength); Final(digest, outLen); return(requestedBitLength == outLen ? new HashResult(new BitString(digest)) : new HashResult(LittleEndianSubstring(new BitString(digest), 0, requestedBitLength))); }