Ejemplo n.º 1
0
        private void LowLevelDesAlgorithm(WorkingSet workingSet, KeySet[] keySets, bool bEncrypt)
        {
            //
            // Apply 1 or 3 keys to a block of data
            //

            // Loop through keys
            for (int iKeySetOffset = 0; iKeySetOffset < keySets.Length; iKeySetOffset++)
            {
                // Permute with byteIP
                workingSet.IP.Reset();
                int tableOffset;
                int iPermOffset;
                for (tableOffset = 0; tableOffset < DESTables.Ip.Length; tableOffset++)
                {
                    // Get perm offset
                    iPermOffset = DESTables.Ip[tableOffset];
                    iPermOffset--;

                    // Get and set bit
                    workingSet.IP.SetBit(
                        BitAddressToByteOffset(tableOffset, 8),
                        BitAddressToBitOffset(tableOffset, 8),
                        workingSet.DataBlockOut.GetBit(
                            BitAddressToByteOffset(iPermOffset, 8),
                            BitAddressToBitOffset(iPermOffset, 8)
                        )
                    );
                }

                // Create Ln[0] and Rn[0]
                workingSet.Ln[0].Reset();
                workingSet.Rn[0].Reset();
                int iArrayOffset;
                for (iArrayOffset = 0; iArrayOffset < 32; iArrayOffset++)
                {
                    int byteOffset = BitAddressToByteOffset(iArrayOffset, 8);
                    int bitOffset = BitAddressToBitOffset(iArrayOffset, 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 iBlockOffset = 1; iBlockOffset < 17; iBlockOffset++)
                {
                    // Get the array offset
                    int iKeyOffset;
                    if (bEncrypt != (iKeySetOffset == 1))
                        iKeyOffset = iBlockOffset;
                    else
                        iKeyOffset = 17 - iBlockOffset;

                    // Set Ln[N] = Rn[N-1]
                    workingSet.Ln[iBlockOffset].Set(workingSet.Rn[iBlockOffset - 1]);

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

                        // Get and set bit
                        workingSet.RnExpand.SetBit(
                            BitAddressToByteOffset(tableOffset, 6),
                            BitAddressToBitOffset(tableOffset, 6),
                            workingSet.Rn[iBlockOffset - 1].GetBit(
                                BitAddressToByteOffset(iPermOffset, 8),
                                BitAddressToBitOffset(iPermOffset, 8)
                            )
                        );

                    }

                    // XOR expanded block with K-block
                    if (bEncrypt != (iKeySetOffset == 1))
                        workingSet.XorBlock.Xor(workingSet.RnExpand, keySets[iKeySetOffset].GetAt(iKeyOffset));
                    else
                        workingSet.XorBlock.Xor(workingSet.RnExpand, keySets[keySets.Length - 1 - iKeySetOffset].GetAt(iKeyOffset));

                    // Set S-Box values
                    workingSet.SBoxValues.Reset();
                    for (tableOffset = 0; tableOffset < 8; tableOffset++)
                    {
                        // 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
                        iPermOffset = DESTables.SBox[(tableOffset * 4) + m, n];
                        workingSet.SBoxValues._data[tableOffset] = (byte)(iPermOffset << 4);
                    }

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

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

                    // Rn[N] = Ln[N-1] ^ f
                    workingSet.Rn[iBlockOffset].Reset();
                    for (tableOffset = 0; tableOffset < 8; tableOffset++)
                    {
                        // Get Ln[N-1] -> A
                        byte a = workingSet.Ln[iBlockOffset - 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[iBlockOffset]._data[tableOffset >> 1] |= Convert.ToByte((a ^ b) << 4);
                        else
                            workingSet.Rn[iBlockOffset]._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.DataBlockOut.Reset();
                for (tableOffset = 0; tableOffset < DESTables.Rfp.Length; tableOffset++)
                {
                    // Get perm offset
                    iPermOffset = DESTables.Rfp[tableOffset];
                    iPermOffset--;

                    // Get and set bit
                    workingSet.DataBlockOut.SetBit(
                        BitAddressToByteOffset(tableOffset, 8),
                        BitAddressToBitOffset(tableOffset, 8),
                        workingSet.X.GetBit(
                            BitAddressToByteOffset(iPermOffset, 8),
                            BitAddressToBitOffset(iPermOffset, 8)
                        )
                    );
                }
            }
        }
Ejemplo n.º 2
0
        protected void DESAlgorithm(byte[] bufferIn, ref byte[] bufferOut, KeySet[] keySets, bool encrypt)
        {
            //
            // Apply the DES algorithm to each block
            //

            // Declare a workset set of variables
            WorkingSet workingSet = new WorkingSet();

            // encode/decode blocks
            int iBufferPos = 0;
            while (true)
            {
                // Check buffer position
                if (encrypt)
                {
                    // If end of buffer...
                    if (iBufferPos >= bufferOut.Length)
                        break;
                    // Calulate remaining bytes
                    int iRemainder = (bufferIn.Length - iBufferPos);
                    if (iRemainder >= 8)
                        workingSet.DataBlockIn.Set(bufferIn, iBufferPos);
                    else
                    {
                        // Copy part-block
                        workingSet.DataBlockIn.Reset();
                        if (iRemainder > 0)
                            Array.Copy(bufferIn, iBufferPos, workingSet.DataBlockIn._data, 0, iRemainder);

                        // Get the padding byte
                        byte padding = Convert.ToByte(KEY_BYTE_LENGTH - iRemainder);

                        // Add padding to block
                        for (int byteOffset = iRemainder; byteOffset < KEY_BYTE_LENGTH; byteOffset++)
                            workingSet.DataBlockIn._data[byteOffset] = padding;
                    }
                }
                else
                {
                    // If end of buffer...
                    if (iBufferPos >= bufferIn.Length)
                        break;

                    // Get the next block
                    workingSet.DataBlockIn.Set(bufferIn, iBufferPos);
                }

                // if encrypting and not the first block...
                if ((encrypt) && (iBufferPos > 0))
                {
                    // Apply succession => XOR M with previous block
                    workingSet.DataBlockIn.Xor(workingSet.DataBlockOut, workingSet.DataBlockIn);
                }

                // Apply the algorithm
                workingSet.DataBlockOut.Set(workingSet.DataBlockIn);
                LowLevelDesAlgorithm(workingSet, keySets, encrypt);

                // If decrypting...
                if (!encrypt)
                {
                    // Retain the succession
                    if (iBufferPos > 0)
                        workingSet.DataBlockOut.Xor(workingSet.DecryptXorBlock, workingSet.DataBlockOut);

                    // Retain the last block
                    workingSet.DecryptXorBlock.Set(workingSet.DataBlockIn);
                }

                // Update buffer out
                Array.Copy(workingSet.DataBlockOut._data, 0, bufferOut, iBufferPos, 8);

                // Move on
                iBufferPos += 8;
            }

            // Scrub the working set
            workingSet.Scrub();
        }