Exemple #1
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <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);
        }
        public void TestPermutationNetwork()
        {
            byte[] permutation = new byte[64];

            // Identity permutation
            for (byte i = 0; i < 64; i++)
            {
                Identity[i] = i;
            }

            for (int i1 = 0; i1 < 62; i1++)
            {
                for (int i2 = i1 + 1; i2 < 64; i2++)
                {
                    TestTwoCycle(i1, i2, permutation);
                }
            }

            Array.Copy(Identity, permutation, 64);

            PermutationNetwork pnwk = new PermutationNetwork(permutation);
            Assert.AreEqual(56ul, pnwk.Permute(56));

            // Swap unit and two's bits
            permutation[0] = 1;
            permutation[1] = 0;
            pnwk = new PermutationNetwork(permutation);
            Assert.AreEqual(1ul, pnwk.Permute(2));
            Assert.AreEqual(2ul, pnwk.Permute(1));
            Assert.AreEqual(3ul, pnwk.Permute(3));
            Assert.AreEqual(5ul, pnwk.Permute(6));
            Assert.AreEqual(6ul, pnwk.Permute(5));

            // Cycle the bottom four bits
            permutation[0] = 1;
            permutation[1] = 2;
            permutation[2] = 3;
            permutation[3] = 0;
            pnwk = new PermutationNetwork(permutation);
            Assert.AreEqual(2ul, pnwk.Permute(1));
            Assert.AreEqual(4ul, pnwk.Permute(2));
            Assert.AreEqual(8ul, pnwk.Permute(4));
            Assert.AreEqual(1ul, pnwk.Permute(8));
            Assert.AreEqual(3ul, pnwk.Permute(9));

            // Random permutation
            Random rnd = new Random(0);
            for (int i = 0; i < 63; i++)
            {
                int swapIndex = rnd.Next(64);
                byte b = permutation[i];
                permutation[i] = permutation[swapIndex];
                permutation[swapIndex] = b;
            }
            pnwk = new PermutationNetwork(permutation);
            ulong testVal = ((ulong)rnd.Next() << 32) | (uint)rnd.Next();
            ulong resultVal = pnwk.Permute(testVal);
            TestPerm(permutation, testVal, resultVal);
        }
Exemple #3
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Add this network's contribution to the mask list. </summary>
        ///
        /// <remarks>
        /// Extract the masks from our inner networks, interleave them and wrap the resultant list with
        /// our own masks.  Darrellp, 12/7/2011.
        /// </remarks>
        ///
        /// <param name="even">			The even inner permutation network. </param>
        /// <param name="odd">			The odd inner permutation network. </param>
        /// <param name="inputMask">	Our own input mask. </param>
        /// <param name="outputMask">	Our own output mask. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        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);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <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);
        }
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 /// <summary>	Add this network's contribution to the mask list. </summary>
 ///
 /// <remarks>	
 /// Extract the masks from our inner networks, interleave them and wrap the resultant list with
 /// our own masks.  Darrellp, 12/7/2011. 
 /// </remarks>
 ///
 /// <param name="even">			The even inner permutation network. </param>
 /// <param name="odd">			The odd inner permutation network. </param>
 /// <param name="inputMask">	Our own input mask. </param>
 /// <param name="outputMask">	Our own output mask. </param>
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 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);
 }
 private static void TestTwoCycle(int i1, int i2, byte[] permutation)
 {
     Array.Copy(Identity, permutation, 64);
     permutation[i1] = (byte)i2;
     permutation[i2] = (byte)i1;
     PermutationNetwork pnwk = new PermutationNetwork(permutation);
     Assert.AreEqual(1UL << i2, pnwk.Permute(1UL << i1));
     Assert.AreEqual(1UL << i1, pnwk.Permute(1UL << i2));
 }