public BitString MixKeys(TDESKeys keys, List <BitString> lastThreeOpResults) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } if (lastThreeOpResults == null || lastThreeOpResults.Count < 3) { throw new ArgumentException("Need three cipherText entries to mix keys", nameof(lastThreeOpResults)); } var newKey1 = keys.KeysAsBitStrings[0].XOR(lastThreeOpResults[0]); var newKey2 = keys.KeysAsBitStrings[1].XOR(lastThreeOpResults[0]); var newKey3 = keys.KeysAsBitStrings[2].XOR(lastThreeOpResults[0]); if (keys.KeyOption == KeyOptionValues.ThreeKey) { newKey2 = keys.KeysAsBitStrings[1].XOR(lastThreeOpResults[1]); newKey3 = keys.KeysAsBitStrings[2].XOR(lastThreeOpResults[2]); } if (keys.KeyOption == KeyOptionValues.TwoKey) { newKey2 = keys.KeysAsBitStrings[1].XOR(lastThreeOpResults[1]); } byte[] outputArray = new byte[24]; Array.Copy(newKey1.ToBytes(), outputArray, 8); Array.Copy(newKey2.ToBytes(), 0, outputArray, 8, 8); Array.Copy(newKey3.ToBytes(), 0, outputArray, 16, 8); return(new BitString(outputArray)); }
public TDESContext(TDESKeys keys, BlockCipherDirections function) { Schedule = new List <KeySchedule>(); Function = function; for (int keyIdx = 0; keyIdx < keys.Keys.Count; keyIdx++) { var workingFunction = GetWorkingFunction(keyIdx); var keySched = new KeySchedule(keys.Keys[keyIdx], workingFunction, true); Schedule.Add(keySched); } }
public BitString MixKeys(TDESKeys keys, List <BitString> previousOutputs) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } if (previousOutputs == null || (previousOutputs.Count * previousOutputs[0].BitLength) < 192) { throw new ArgumentException("Need 192 bits of previous outputs", nameof(previousOutputs)); } var outputBitString = new BitString(192); previousOutputs.Reverse(); foreach (var previousOutput in previousOutputs) { outputBitString = outputBitString.ConcatenateBits(previousOutput); } var newKey1 = keys.KeysAsBitStrings[0].XOR(outputBitString.Substring(0, 64)); var newKey2 = keys.KeysAsBitStrings[1].XOR(outputBitString.Substring(0, 64)); var newKey3 = keys.KeysAsBitStrings[2].XOR(outputBitString.Substring(0, 64)); if (keys.KeyOption == KeyOptionValues.ThreeKey) { newKey2 = keys.KeysAsBitStrings[1].XOR(outputBitString.Substring(64, 64)); newKey3 = keys.KeysAsBitStrings[2].XOR(outputBitString.Substring(128, 64)); } if (keys.KeyOption == KeyOptionValues.TwoKey) { newKey2 = keys.KeysAsBitStrings[1].XOR(outputBitString.Substring(64, 64)); } byte[] outputArray = new byte[24]; Array.Copy(newKey1.ToBytes(), outputArray, 8); Array.Copy(newKey2.ToBytes(), 0, outputArray, 8, 8); Array.Copy(newKey3.ToBytes(), 0, outputArray, 16, 8); return(new BitString(outputArray)); }
private void PopulateKeySchedule() { var contextDirection = BlockCipherDirections.Encrypt; switch (_direction) { case BlockCipherDirections.Encrypt: contextDirection = !_useInverseCipher ? BlockCipherDirections.Encrypt : BlockCipherDirections.Decrypt; break; case BlockCipherDirections.Decrypt: contextDirection = !_useInverseCipher ? BlockCipherDirections.Decrypt : BlockCipherDirections.Encrypt; break; default: throw new ArgumentException(nameof(_direction)); } var keys = new TDESKeys(new BitString(_key)); _context = new TDESContext(keys, contextDirection); }