internal static byte[] InitKey(int mNumCyclesPower, byte[] salt, byte[] pass) { if (mNumCyclesPower == 0x3F) { var key = new byte[32]; int pos; for (pos = 0; pos < salt.Length; pos++) { key[pos] = salt[pos]; } for (int i = 0; i < pass.Length && pos < 32; i++) { key[pos++] = pass[i]; } return(key); } else { #if BUILD_PORTABLE var stream = new KeyDataStream(); var task = Task.Run(delegate { using (var sha = System.Security.Cryptography.SHA256.Create()) return(sha.ComputeHash(stream)); }); byte[] counter = new byte[8]; long numRounds = 1L << mNumCyclesPower; for (long round = 0; round < numRounds; round++) { stream.ProvideData(salt, 0, salt.Length); stream.ProvideData(pass, 0, pass.Length); stream.ProvideData(counter, 0, 8); // This mirrors the counter so we don't have to convert long to byte[] each round. // (It also ensures the counter is little endian, which BitConverter does not.) for (int i = 0; i < 8; i++) { if (++counter[i] != 0) { break; } } } stream.Complete(); return(task.GetAwaiter().GetResult()); #else using (var sha = System.Security.Cryptography.SHA256.Create()) { byte[] counter = new byte[8]; long numRounds = 1L << mNumCyclesPower; for (long round = 0; round < numRounds; round++) { sha.TransformBlock(salt, 0, salt.Length, null, 0); sha.TransformBlock(pass, 0, pass.Length, null, 0); sha.TransformBlock(counter, 0, 8, null, 0); // This mirrors the counter so we don't have to convert long to byte[] each round. // (It also ensures the counter is little endian, which BitConverter does not.) for (int i = 0; i < 8; i++) { if (++counter[i] != 0) { break; } } } sha.TransformFinalBlock(counter, 0, 0); return(sha.Hash); } #endif } }
internal static byte[] InitKey(int mNumCyclesPower, byte[] salt, byte[] pass) { if (mNumCyclesPower == 0x3F) { var key = new byte[32]; int pos; for (pos = 0; pos < salt.Length; pos++) key[pos] = salt[pos]; for (int i = 0; i < pass.Length && pos < 32; i++) key[pos++] = pass[i]; return key; } else { #if BUILD_PORTABLE var stream = new KeyDataStream(); var task = Task.Run(delegate { using (var sha = System.Security.Cryptography.SHA256.Create()) return sha.ComputeHash(stream); }); byte[] counter = new byte[8]; long numRounds = 1L << mNumCyclesPower; for (long round = 0; round < numRounds; round++) { stream.ProvideData(salt, 0, salt.Length); stream.ProvideData(pass, 0, pass.Length); stream.ProvideData(counter, 0, 8); // This mirrors the counter so we don't have to convert long to byte[] each round. // (It also ensures the counter is little endian, which BitConverter does not.) for (int i = 0; i < 8; i++) if (++counter[i] != 0) break; } stream.Complete(); return task.GetAwaiter().GetResult(); #else using (var sha = System.Security.Cryptography.SHA256.Create()) { byte[] counter = new byte[8]; long numRounds = 1L << mNumCyclesPower; for (long round = 0; round < numRounds; round++) { sha.TransformBlock(salt, 0, salt.Length, null, 0); sha.TransformBlock(pass, 0, pass.Length, null, 0); sha.TransformBlock(counter, 0, 8, null, 0); // This mirrors the counter so we don't have to convert long to byte[] each round. // (It also ensures the counter is little endian, which BitConverter does not.) for (int i = 0; i < 8; i++) if (++counter[i] != 0) break; } sha.TransformFinalBlock(counter, 0, 0); return sha.Hash; } #endif } }