private static ulong ShiftKey(ulong key, int iteration) { var constants = new FeistelConstants(); ulong L = key >> 28; ulong R = key << 36 >> 28; L = L << constants.shifts[iteration] | L >> (28 - constants.shifts[iteration]); R = R << constants.shifts[iteration] | R >> (28 - constants.shifts[iteration]); key = L << 28 | R; key = Permutate(key, false, constants.roundKeyIndexes); return(key); }
private static ulong Shrink(ulong block) { var constants = new FeistelConstants(); ulong result = 0; result |= constants.SBox1[block << 58 >> 58]; result |= constants.SBox2[block << 52 >> 58] << 4; result |= constants.SBox3[block << 46 >> 58] << 8; result |= constants.SBox4[block << 40 >> 58] << 12; result |= constants.SBox5[block << 34 >> 58] << 16; result |= constants.SBox6[block << 28 >> 58] << 20; result |= constants.SBox7[block << 22 >> 58] << 24; result |= constants.SBox8[block << 16 >> 58] << 28; return(result); }
public static byte[] Decrypt(byte[] _message, byte[] _key) { var constants = new FeistelConstants(); ulong key = BitConverter.ToUInt64(_key, 0); ulong[] binary = ToBinary(_message); key = Permutate(key, false, constants.keyIndexes); for (int j = 0; j < binary.Length; j++) { binary[j] = Permutate(binary[j], false, IPIndexes); for (int i = 15; i >= 0; i--) { binary[j] = Round(binary[j], key, i); } binary[j] = (binary[j] << 32 >> 32) << 32 | (binary[j] >> 32); binary[j] = Permutate(binary[j], true, IPIndexes); } return(ToBytes(binary)); }
private static ulong Round(ulong block, ulong key, int iteration) { var constants = new FeistelConstants(); ulong L = block >> 32; ulong R = block << 32 >> 32; key = ShiftKey(key, iteration); ulong extendedR = Extend(R); extendedR = extendedR ^ key; ulong newR = Shrink(extendedR); newR = Permutate(newR, false, constants.roundIndexes); ulong result = R << 32; result |= newR ^ L; return(result); }