//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Initializes the permutation network. </summary> /// /// <remarks> /// This is where the real work is done. The permutation network is an abstraction of a set of /// incoming wires and outgoing wires. The permutation is given in terms of those wires, but /// each indivicual wire represents a particular bit in the input. The bits represented by /// adjacent wires are separated by a value delta which is equal to 64 / (the size of the /// permutation). The first wire represents the bit indexed by phase. Thus the bit corresponding /// to wire i is phase + i * delta. Since size can be calculated by the size of the permutation /// the only thing we need to make this mapping are the phase and the permutation. Key point is /// that the permutation references wire numbers running consecutively from 0 to (size - 1), not /// actual bit positions. Darrellp, 12/7/2011. /// </remarks> /// /// <param name="permutation"> The permutation we will use to permute the bits. </param> /// <param name="phase"> The index of the first bit to be permuted. </param> //////////////////////////////////////////////////////////////////////////////////////////////////// private void Initialize(byte[] permutation, int phase) { PermutationNetwork permutationNetworkEven; PermutationNetwork permutationNetworkOdd; int size = permutation.Length; int delta = 64 / size; ulong inputMask; ulong outputMask; // Get the wiring needed for our two inner networks byte[][] permutationsInner = GetInnerPermutations(permutation, delta, phase, out inputMask, out outputMask); // Recursively create those two inner networks if (size == 4) { // The recursion ends here by creating two swappers rather than normal permutation networks permutationNetworkEven = new Swapper(permutationsInner[0], phase); permutationNetworkOdd = new Swapper(permutationsInner[1], phase + delta); } else { // For larger sizes, the inner networks are standard permutation networks permutationNetworkEven = new PermutationNetwork(permutationsInner[0], phase); permutationNetworkOdd = new PermutationNetwork(permutationsInner[1], phase + delta); } // Extract the masks from our inner permutation networks into our list of masks ExtractMasks(permutationNetworkEven, permutationNetworkOdd, inputMask, outputMask); }