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);
        }
        private void ExtractMasks(PermutationNetwork even, PermutationNetwork odd, ulong inputMask, ulong outputMask)
        {
            List <ulong> masksEven = even.Masks;
            List <ulong> masksOdd  = odd.Masks;

            Masks.Add(inputMask);
            for (int i = 0; i < masksEven.Count; i++)
            {
                Masks.Add(masksEven[i] | masksOdd[i]);
            }
            Masks.Add(outputMask);
        }