Ejemplo n.º 1
0
        /// <summary>
        /// Apply the low level DES encryption algorithm to a WorkingSet with the calculated RoundKeys.
        /// </summary>
        /// <param name="workingSet">Contains the information needed in the encryption process</param>
        /// <param name="keySet">Set of the 16 RoundKeys needed for encryption</param>
        private void LowLevelDesAlgorithm(WorkingSet workingSet, KeySet keySet)
        {
            // Declaration of local variables
            int tableOffset;
            int arrayOffset;
            int permOffset;
            int byteOffset;
            int bitOffset;

            // Permute with byteIP
            for (tableOffset = 0; tableOffset < byteIP.Length; tableOffset++)
            {
                // Get perm offset
                permOffset = byteIP[tableOffset];
                permOffset--;

                // Get and set bit
                workingSet.ip.SetBit(
                    BitAddressToByteOffset(tableOffset, 8),
                    BitAddressToBitOffset(tableOffset, 8),
                    workingSet.inputBlock.GetBit(
                        BitAddressToByteOffset(permOffset, 8),
                        BitAddressToBitOffset(permOffset, 8)
                        )
                    );
            }

            // Create Ln[0] and Rn[0]
            for (arrayOffset = 0; arrayOffset < 32; arrayOffset++)
            {
                byteOffset = BitAddressToByteOffset(arrayOffset, 8);
                bitOffset  = BitAddressToBitOffset(arrayOffset, 8);
                workingSet.ln[0].SetBit(byteOffset, bitOffset, workingSet.ip.GetBit(byteOffset, bitOffset));
                workingSet.rn[0].SetBit(byteOffset, bitOffset, workingSet.ip.GetBit(byteOffset + 4, bitOffset));
            }

            // Loop through 17 interations
            for (int blockOffset = 1; blockOffset < 17; blockOffset++)
            {
                // Get the array offset
                int iKeyOffset = blockOffset;

                // Set Ln[N] = Rn[N-1]
                workingSet.ln[blockOffset].Set(workingSet.rn[blockOffset - 1]);

                // Set Rn[N] = Ln[0] + f(R[N-1],K[N])
                for (tableOffset = 0; tableOffset < byteE.Length; tableOffset++)
                {
                    // Get perm offset
                    permOffset = byteE[tableOffset];
                    permOffset--;

                    // Get and set bit
                    workingSet.rnExpand.SetBit(
                        BitAddressToByteOffset(tableOffset, 6),
                        BitAddressToBitOffset(tableOffset, 6),
                        workingSet.rn[blockOffset - 1].GetBit(
                            BitAddressToByteOffset(permOffset, 8),
                            BitAddressToBitOffset(permOffset, 8)
                            )
                        );
                }

                //Fill String Attribute
                roundDetails[blockOffset - 1, 0] = workingSet.rnExpand.ToBinaryString(48, 7);

                // XOR expanded block with K-block
                workingSet.xorBlock.Xor(workingSet.rnExpand, keySet.GetAt(iKeyOffset));

                //Fill String Attribute
                roundDetails[blockOffset - 1, 1] = workingSet.xorBlock.ToBinaryString(48, 7);

                // Set S-Box values
                workingSet.sBoxValues.Reset();
                for (tableOffset = 0; tableOffset < 8; tableOffset++)
                {
                    //Fill String Attribute
                    sBoxStringDetails[blockOffset - 1, tableOffset * 4] = Convert.ToString(workingSet.xorBlock.data[tableOffset], 2).PadLeft(8, '0').Remove(6, 2);

                    // Calculate m and n
                    int m = ((workingSet.xorBlock.GetBit(tableOffset, 7) ? 1 : 0) << 1) | (workingSet.xorBlock.GetBit(tableOffset, 2) ? 1 : 0);
                    int n = (workingSet.xorBlock.data[tableOffset] >> 3) & 0x0F;

                    // Get s-box value
                    permOffset = byteSBox[(tableOffset * 4) + m, n];
                    workingSet.sBoxValues.data[tableOffset] = (byte)(permOffset << 4);

                    //Fill String Attributes
                    sBoxNumberDetails[blockOffset - 1, tableOffset * 3]       = (byte)(m);
                    sBoxStringDetails[blockOffset - 1, (tableOffset * 4) + 1] = Convert.ToString(m, 2).PadLeft(2, '0');
                    sBoxNumberDetails[blockOffset - 1, (tableOffset * 3) + 1] = (byte)(n);
                    sBoxStringDetails[blockOffset - 1, (tableOffset * 4) + 2] = Convert.ToString(n, 2).PadLeft(4, '0');
                    sBoxNumberDetails[blockOffset - 1, (tableOffset * 3) + 2] = (byte)(workingSet.sBoxValues.data[tableOffset] >> 4);
                    sBoxStringDetails[blockOffset - 1, (tableOffset * 4) + 3] = Convert.ToString((byte)(workingSet.sBoxValues.data[tableOffset] >> 4), 2).PadLeft(4, '0');
                }

                //Fill String Attributes
                roundDetails[blockOffset - 1, 2] = workingSet.sBoxValues.ToBinaryString(32, 5);

                // Permute with P -> f
                workingSet.f.Reset();
                for (tableOffset = 0; tableOffset < byteP.Length; tableOffset++)
                {
                    // Get perm offset
                    permOffset = byteP[tableOffset];
                    permOffset--;

                    // Get and set bit
                    workingSet.f.SetBit(
                        BitAddressToByteOffset(tableOffset, 4),
                        BitAddressToBitOffset(tableOffset, 4),
                        workingSet.sBoxValues.GetBit(
                            BitAddressToByteOffset(permOffset, 4),
                            BitAddressToBitOffset(permOffset, 4)
                            )
                        );
                }

                //Fill String Attributes
                roundDetails[blockOffset - 1, 3] = workingSet.f.ToBinaryString(32, 5);

                // Rn[N] = Ln[N-1] ^ f
                workingSet.rn[blockOffset].Reset();
                for (tableOffset = 0; tableOffset < 8; tableOffset++)
                {
                    // Get Ln[N-1] -> A
                    byte a = workingSet.ln[blockOffset - 1].data[(tableOffset >> 1)];
                    if ((tableOffset % 2) == 0)
                    {
                        a >>= 4;
                    }
                    else
                    {
                        a &= 0x0F;
                    }

                    // Get f -> B
                    byte b = Convert.ToByte(workingSet.f.data[tableOffset] >> 4);

                    // Update Rn[N]
                    if ((tableOffset % 2) == 0)
                    {
                        workingSet.rn[blockOffset].data[tableOffset >> 1] |= Convert.ToByte((a ^ b) << 4);
                    }
                    else
                    {
                        workingSet.rn[blockOffset].data[tableOffset >> 1] |= Convert.ToByte(a ^ b);
                    }
                }
            }

            // X = R16 L16
            workingSet.x.Reset();
            for (tableOffset = 0; tableOffset < 4; tableOffset++)
            {
                workingSet.x.data[tableOffset]     = workingSet.rn[16].data[tableOffset];
                workingSet.x.data[tableOffset + 4] = workingSet.ln[16].data[tableOffset];
            }

            // C = X perm IP
            workingSet.outputBlock.Reset();
            for (tableOffset = 0; tableOffset < byteFP.Length; tableOffset++)
            {
                // Get perm offset
                permOffset = byteFP[tableOffset];
                permOffset--;

                // Get and set bit
                workingSet.outputBlock.SetBit(
                    BitAddressToByteOffset(tableOffset, 8),
                    BitAddressToBitOffset(tableOffset, 8),
                    workingSet.x.GetBit(
                        BitAddressToByteOffset(permOffset, 8),
                        BitAddressToBitOffset(permOffset, 8)
                        )
                    );
            }
            outputCiphertext = workingSet.outputBlock.data;

            //Fill String Attribute
            ciphertext = workingSet.outputBlock.ToBinaryString(64, 0);


            //Fill String Attributes
            if (textChanged)
            {
                for (int i = 0; i < 17; i++)
                {
                    lrDataB[i, 0] = workingSet.ln[i].ToBinaryString(32, 0);
                    lrDataB[i, 1] = workingSet.rn[i].ToBinaryString(32, 0);
                }
                //MessageBox.Show(lrDataB[1, 0] + lrDataB[1, 1]);
            }
            else
            {
                for (int i = 0; i < 17; i++)
                {
                    lrData[i, 0] = workingSet.ln[i].ToBinaryString(32, 0);
                    lrData[i, 1] = workingSet.rn[i].ToBinaryString(32, 0);
                }


                // MessageBox.Show(lrData[1, 0] + lrData[1, 1]);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Expand an 8 byte DES key into a set of permuted round keys.
        /// </summary>
        /// <param name="key">8 byte DES key</param>
        /// <returns>KeySet instance containing the round keys</returns>
        private KeySet ExpandKey(byte[] key)
        {
            // Declare return variable
            KeySet tmp = new KeySet();

            // Declaration of local variables
            int  tableOffset, arrayOffset, permOffset, byteOffset, bitOffset;
            bool bit;

            // Put key into an 8-bit block
            ByteBlock k = new ByteBlock();

            k.Set(key, 0);

            //Fill String Attribute
            this.key = k.ToBinaryString(64, 0);

            // Permutate Kp with PC1
            ByteBlock kp = new ByteBlock();

            for (arrayOffset = 0; arrayOffset < bytePC1.Length; arrayOffset++)
            {
                // Get permute offset
                permOffset = bytePC1[arrayOffset];
                permOffset--;

                // Get and set bit
                kp.SetBit(
                    BitAddressToByteOffset(arrayOffset, 7),
                    BitAddressToBitOffset(arrayOffset, 7),
                    k.GetBit(
                        BitAddressToByteOffset(permOffset, 8),
                        BitAddressToBitOffset(permOffset, 8)
                        )
                    );
            }


            // Create 17 blocks of C and D from Kp
            ByteBlock[] kpCn = new ByteBlock[17];
            ByteBlock[] kpDn = new ByteBlock[17];
            for (arrayOffset = 0; arrayOffset < 17; arrayOffset++)
            {
                kpCn[arrayOffset] = new ByteBlock();
                kpDn[arrayOffset] = new ByteBlock();
            }
            for (arrayOffset = 0; arrayOffset < 32; arrayOffset++)
            {
                // Set bit in KpCn
                byteOffset = BitAddressToByteOffset(arrayOffset, 8);
                bitOffset  = BitAddressToBitOffset(arrayOffset, 8);
                bit        = kp.GetBit(byteOffset, bitOffset);
                kpCn[0].SetBit(byteOffset, bitOffset, bit);

                // Set bit in KpDn
                bit = kp.GetBit(byteOffset + 4, bitOffset);
                kpDn[0].SetBit(byteOffset, bitOffset, bit);
            }

            for (arrayOffset = 1; arrayOffset < 17; arrayOffset++)
            {
                // Shift left wrapped
                kpCn[arrayOffset].ShiftLeftWrapped(kpCn[arrayOffset - 1], byteShifts[arrayOffset - 1]);
                kpDn[arrayOffset].ShiftLeftWrapped(kpDn[arrayOffset - 1], byteShifts[arrayOffset - 1]);
            }

            // Fill Cn und Dn  binary strings into KeySchedule
            for (arrayOffset = 0; arrayOffset < 17; arrayOffset++)
            {
                keySchedule[arrayOffset, 0] = kpCn[arrayOffset].ToBinaryString(29, 8).Remove(28, 1);
                keySchedule[arrayOffset, 1] = kpDn[arrayOffset].ToBinaryString(29, 8).Remove(28, 1);
            }


            // Create 17 keys Kn
            for (arrayOffset = 0; arrayOffset < 17; arrayOffset++)
            {
                // Loop through the bits
                for (tableOffset = 0; tableOffset < 48; tableOffset++)
                {
                    // Get address of bit
                    permOffset = bytePC2[tableOffset];
                    permOffset--;

                    // Convert to byte and bit offsets
                    byteOffset = BitAddressToByteOffset(permOffset, 7);
                    bitOffset  = BitAddressToBitOffset(permOffset, 7);

                    // Get bit
                    if (byteOffset < 4)
                    {
                        bit = kpCn[arrayOffset].GetBit(byteOffset, bitOffset);
                    }
                    else
                    {
                        bit = kpDn[arrayOffset].GetBit(byteOffset - 4, bitOffset);
                    }

                    // Set bit
                    byteOffset = BitAddressToByteOffset(tableOffset, 6);
                    bitOffset  = BitAddressToBitOffset(tableOffset, 6);
                    tmp.GetAt(arrayOffset).SetBit(byteOffset, bitOffset, bit);
                }
            }

            // Fill in binary strings into RoundKeys
            for (arrayOffset = 0; arrayOffset < 16; arrayOffset++)
            {
                roundKeys[arrayOffset] = tmp.GetAt(arrayOffset + 1).ToBinaryString(48, 7);
            }

            // Return filled KeySet variable tmp
            return(tmp);
        }