Halves Split56(ulong block) { Halves splitBlock = new Halves(); splitBlock.Left = block >> (64 - 28) << (64 - 28); splitBlock.Right = block << 28; return(splitBlock); }
Halves Split64(ulong block) { Halves splitBlock = new Halves(); splitBlock.Left = block >> 32 << 32; splitBlock.Right = block << 32; return(splitBlock); }
// Takes original key and generates all 16 keys. void GenerateKeys(ulong key) { ulong pc1Key = Permute(key, ref permChoice1Table); Halves keyHalves = Split56(pc1Key); for (int i = 0; i < 16; i++) { keyHalves.Left = LeftShift56(keyHalves.Left, LeftShifts[i]); keyHalves.Right = LeftShift56(keyHalves.Right, LeftShifts[i]); ulong newKey = Merge(keyHalves); keys[i] = Permute(newKey, ref permChoice2Table); } }
public override string Encrypt(string plainText, string key) { ulong plainBlock = Convert.ToUInt64(plainText, 16); // Convert Hex string to 64 bits number ulong plainKey = Convert.ToUInt64(key, 16); GenerateKeys(plainKey); ulong initialPermBlock = Permute(plainBlock, ref initialPermTable); Halves halves = Split64(initialPermBlock); for (int i = 0; i < 16; i++) { halves = Round(halves, keys[i]); } ulong swapped = halves.Right | (halves.Left >> 32); ulong final = Permute(swapped, ref inverseInitialPermTable); return("0x" + final.ToString("X").PadLeft(16, '0')); }
Halves Round(Halves block, ulong key) { ulong expandedRightHalf = Permute(block.Right, ref expansionTable); ulong nextRight = expandedRightHalf ^ key; byte[] sboxesInput = SplitIntoEight(nextRight); // split 48 bits into 8 groups of 6-bits ulong sBoxesRes = 0; for (int i = 0; i < 8; i++) { sBoxesRes <<= 4; sBoxesRes |= FromSBox(sboxesInput[i], i); } sBoxesRes <<= 32; nextRight = Permute(sBoxesRes, ref permutationTable); nextRight ^= block.Left; ulong nextLeft = block.Right; return(new Halves { Left = nextLeft, Right = nextRight }); }
ulong Merge(Halves halves) { return((halves.Left & 0xFFFFFFF000000000) | ((halves.Right & 0xFFFFFFF000000000) >> 28)); }