private static void _desAlgorithm(byte[] bufferIn, ref byte[] bufferOut, KEY_SET[] KeySets, byte[] iv, bool bEncrypt) { // // Apply the DES algorithm to each block // // Declare a workset set of variables WORKING_SET workingSet = new WORKING_SET(); workingSet.DecryptXorBlock.Set(iv, 0); // encode/decode blocks int iBufferPos = 0; while (true) { // Check buffer position if (bEncrypt) { // 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.m_data, 0, iRemainder); // Get the padding byte byte Padding = Convert.ToByte(KEY_BYTE_LENGTH - iRemainder); // Add padding to block for (int iByteOffset = iRemainder; iByteOffset < KEY_BYTE_LENGTH; iByteOffset++) workingSet.DataBlockIn.m_data[iByteOffset] = 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 (bEncrypt) { // Apply succession => XOR M with previous block if (iBufferPos == 0) { workingSet.DataBlockIn.Xor(workingSet.DecryptXorBlock, workingSet.DataBlockIn); } else { workingSet.DataBlockIn.Xor(workingSet.DataBlockOut, workingSet.DataBlockIn); } } // Apply the algorithm workingSet.DataBlockOut.Set(workingSet.DataBlockIn); _lowLevel_desAlgorithm(workingSet, KeySets, bEncrypt); // If decrypting... if (!bEncrypt) { // Retain the succession workingSet.DataBlockOut.Xor(workingSet.DecryptXorBlock, workingSet.DataBlockOut); // Retain the last block workingSet.DecryptXorBlock.Set(workingSet.DataBlockIn); } // Update buffer out Array.Copy(workingSet.DataBlockOut.m_data, 0, bufferOut, iBufferPos, 8); // Move on iBufferPos += 8; } // Scrub the working set workingSet.Scrub(); }
private static void _lowLevel_desAlgorithm(WORKING_SET workingSet, KEY_SET[] KeySets, bool bEncrypt) { // // Apply 1 or 3 keys to a block of data // // Declaration of local variables int iTableOffset; int iArrayOffset; int iPermOffset; int iByteOffset; int iBitOffset; // Loop through keys for (int iKeySetOffset = 0; iKeySetOffset < KeySets.Length; iKeySetOffset++) { // Permute with byteIP workingSet.IP.Reset(); for (iTableOffset = 0; iTableOffset < byteIP.Length; iTableOffset++) { // Get perm offset iPermOffset = byteIP[iTableOffset]; iPermOffset--; // Get and set bit workingSet.IP.SetBit( _bitAddressToByteOffset(iTableOffset, 8), _bitAddressToBitOffset(iTableOffset, 8), workingSet.DataBlockOut.GetBit( _bitAddressToByteOffset(iPermOffset, 8), _bitAddressToBitOffset(iPermOffset, 8) ) ); } // Create Ln[0] and Rn[0] workingSet.Ln[0].Reset(); workingSet.Rn[0].Reset(); for (iArrayOffset = 0; iArrayOffset < 32; iArrayOffset++) { iByteOffset = _bitAddressToByteOffset(iArrayOffset, 8); iBitOffset = _bitAddressToBitOffset(iArrayOffset, 8); workingSet.Ln[0].SetBit(iByteOffset, iBitOffset, workingSet.IP.GetBit(iByteOffset, iBitOffset)); workingSet.Rn[0].SetBit(iByteOffset, iBitOffset, workingSet.IP.GetBit(iByteOffset + 4, iBitOffset)); } // 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 (iTableOffset = 0; iTableOffset < byteE.Length; iTableOffset++) { // Get perm offset iPermOffset = byteE[iTableOffset]; iPermOffset--; // Get and set bit workingSet.RnExpand.SetBit( _bitAddressToByteOffset(iTableOffset, 6), _bitAddressToBitOffset(iTableOffset, 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 (iTableOffset = 0; iTableOffset < 8; iTableOffset++) { // Calculate m and n int m = ((workingSet.XorBlock.GetBit(iTableOffset, 7) ? 1 : 0) << 1) | (workingSet.XorBlock.GetBit(iTableOffset, 2) ? 1 : 0); int n = (workingSet.XorBlock.m_data[iTableOffset] >> 3) & 0x0F; // Get s-box value iPermOffset = byteSBox[(iTableOffset * 4) + m, n]; workingSet.SBoxValues.m_data[iTableOffset] = (byte)(iPermOffset << 4); } // Permute with P -> f workingSet.f.Reset(); for (iTableOffset = 0; iTableOffset < byteP.Length; iTableOffset++) { // Get perm offset iPermOffset = byteP[iTableOffset]; iPermOffset--; // Get and set bit workingSet.f.SetBit( _bitAddressToByteOffset(iTableOffset, 4), _bitAddressToBitOffset(iTableOffset, 4), workingSet.SBoxValues.GetBit( _bitAddressToByteOffset(iPermOffset, 4), _bitAddressToBitOffset(iPermOffset, 4) ) ); } // Rn[N] = Ln[N-1] ^ f workingSet.Rn[iBlockOffset].Reset(); for (iTableOffset = 0; iTableOffset < 8; iTableOffset++) { // Get Ln[N-1] -> A byte A = workingSet.Ln[iBlockOffset - 1].m_data[(iTableOffset >> 1)]; if ((iTableOffset % 2) == 0) { A >>= 4; } else { A &= 0x0F; } // Get f -> B byte B = Convert.ToByte(workingSet.f.m_data[iTableOffset] >> 4); // Update Rn[N] if ((iTableOffset % 2) == 0) { workingSet.Rn[iBlockOffset].m_data[iTableOffset >> 1] |= Convert.ToByte((A ^ B) << 4); } else { workingSet.Rn[iBlockOffset].m_data[iTableOffset >> 1] |= Convert.ToByte(A ^ B); } } } // X = R16 L16 workingSet.X.Reset(); for (iTableOffset = 0; iTableOffset < 4; iTableOffset++) { workingSet.X.m_data[iTableOffset] = workingSet.Rn[16].m_data[iTableOffset]; workingSet.X.m_data[iTableOffset + 4] = workingSet.Ln[16].m_data[iTableOffset]; } // C = X perm IP workingSet.DataBlockOut.Reset(); for (iTableOffset = 0; iTableOffset < byteRFP.Length; iTableOffset++) { // Get perm offset iPermOffset = byteRFP[iTableOffset]; iPermOffset--; // Get and set bit workingSet.DataBlockOut.SetBit( _bitAddressToByteOffset(iTableOffset, 8), _bitAddressToBitOffset(iTableOffset, 8), workingSet.X.GetBit( _bitAddressToByteOffset(iPermOffset, 8), _bitAddressToBitOffset(iPermOffset, 8) ) ); } } // key loop }
private static void _lowLevel_desAlgorithm(WORKING_SET workingSet, KEY_SET[] KeySets, bool bEncrypt) { // // Apply 1 or 3 keys to a block of data // // Declaration of local variables int iTableOffset; int iArrayOffset; int iPermOffset; int iByteOffset; int iBitOffset; // Loop through keys for (int iKeySetOffset = 0; iKeySetOffset < KeySets.Length; iKeySetOffset++) { // Permute with byteIP workingSet.IP.Reset(); for (iTableOffset = 0; iTableOffset < byteIP.Length; iTableOffset++) { // Get perm offset iPermOffset = byteIP[iTableOffset]; iPermOffset--; // Get and set bit workingSet.IP.SetBit( _bitAddressToByteOffset(iTableOffset, 8), _bitAddressToBitOffset(iTableOffset, 8), workingSet.DataBlockOut.GetBit( _bitAddressToByteOffset(iPermOffset, 8), _bitAddressToBitOffset(iPermOffset, 8) ) ); } // Create Ln[0] and Rn[0] workingSet.Ln[0].Reset(); workingSet.Rn[0].Reset(); for (iArrayOffset = 0; iArrayOffset < 32; iArrayOffset++) { iByteOffset = _bitAddressToByteOffset(iArrayOffset, 8); iBitOffset = _bitAddressToBitOffset(iArrayOffset, 8); workingSet.Ln[0].SetBit(iByteOffset, iBitOffset, workingSet.IP.GetBit(iByteOffset, iBitOffset)); workingSet.Rn[0].SetBit(iByteOffset, iBitOffset, workingSet.IP.GetBit(iByteOffset + 4, iBitOffset)); } // 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 (iTableOffset = 0; iTableOffset < byteE.Length; iTableOffset++) { // Get perm offset iPermOffset = byteE[iTableOffset]; iPermOffset--; // Get and set bit workingSet.RnExpand.SetBit( _bitAddressToByteOffset(iTableOffset, 6), _bitAddressToBitOffset(iTableOffset, 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 (iTableOffset = 0; iTableOffset < 8; iTableOffset++) { // Calculate m and n int m = ((workingSet.XorBlock.GetBit(iTableOffset, 7) ? 1 : 0) << 1) | (workingSet.XorBlock.GetBit(iTableOffset, 2) ? 1 : 0); int n = (workingSet.XorBlock.m_data[iTableOffset] >> 3) & 0x0F; // Get s-box value iPermOffset = byteSBox[(iTableOffset * 4) + m, n]; workingSet.SBoxValues.m_data[iTableOffset] = (byte)(iPermOffset << 4); } // Permute with P -> f workingSet.f.Reset(); for (iTableOffset = 0; iTableOffset < byteP.Length; iTableOffset++) { // Get perm offset iPermOffset = byteP[iTableOffset]; iPermOffset--; // Get and set bit workingSet.f.SetBit( _bitAddressToByteOffset(iTableOffset, 4), _bitAddressToBitOffset(iTableOffset, 4), workingSet.SBoxValues.GetBit( _bitAddressToByteOffset(iPermOffset, 4), _bitAddressToBitOffset(iPermOffset, 4) ) ); } // Rn[N] = Ln[N-1] ^ f workingSet.Rn[iBlockOffset].Reset(); for (iTableOffset = 0; iTableOffset < 8; iTableOffset++) { // Get Ln[N-1] -> A byte A = workingSet.Ln[iBlockOffset - 1].m_data[(iTableOffset >> 1)]; if ((iTableOffset % 2) == 0) A >>= 4; else A &= 0x0F; // Get f -> B byte B = Convert.ToByte(workingSet.f.m_data[iTableOffset] >> 4); // Update Rn[N] if ((iTableOffset % 2) == 0) workingSet.Rn[iBlockOffset].m_data[iTableOffset >> 1] |= Convert.ToByte((A ^ B) << 4); else workingSet.Rn[iBlockOffset].m_data[iTableOffset >> 1] |= Convert.ToByte(A ^ B); } } // X = R16 L16 workingSet.X.Reset(); for (iTableOffset = 0; iTableOffset < 4; iTableOffset++) { workingSet.X.m_data[iTableOffset] = workingSet.Rn[16].m_data[iTableOffset]; workingSet.X.m_data[iTableOffset + 4] = workingSet.Ln[16].m_data[iTableOffset]; } // C = X perm IP workingSet.DataBlockOut.Reset(); for (iTableOffset = 0; iTableOffset < byteRFP.Length; iTableOffset++) { // Get perm offset iPermOffset = byteRFP[iTableOffset]; iPermOffset--; // Get and set bit workingSet.DataBlockOut.SetBit( _bitAddressToByteOffset(iTableOffset, 8), _bitAddressToBitOffset(iTableOffset, 8), workingSet.X.GetBit( _bitAddressToByteOffset(iPermOffset, 8), _bitAddressToBitOffset(iPermOffset, 8) ) ); } } // key loop }
private static void _desAlgorithm(byte[] bufferIn, ref byte[] bufferOut, KEY_SET[] KeySets, bool bEncrypt) { // // Apply the DES algorithm to each block // // Declare a workset set of variables WORKING_SET workingSet = new WORKING_SET(); // encode/decode blocks int iBufferPos = 0; while (true) { // Check buffer position if (bEncrypt) { // 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.m_data, 0, iRemainder); } // Get the padding byte byte Padding = Convert.ToByte(KEY_BYTE_LENGTH - iRemainder); // Add padding to block for (int iByteOffset = iRemainder; iByteOffset < KEY_BYTE_LENGTH; iByteOffset++) { workingSet.DataBlockIn.m_data[iByteOffset] = 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 ((bEncrypt) && (iBufferPos > 0)) { // Amri commented these lines since Amri need EBC, not CBC // Apply succession => XOR M with previous block //workingSet.DataBlockIn.Xor(workingSet.DataBlockOut, workingSet.DataBlockIn); } // Apply the algorithm workingSet.DataBlockOut.Set(workingSet.DataBlockIn); _lowLevel_desAlgorithm(workingSet, KeySets, bEncrypt); // If decrypting... if (!bEncrypt) { // Amri commented these lines since Amri need EBC, not CBC // 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.m_data, 0, bufferOut, iBufferPos, 8); // Move on iBufferPos += 8; } // Scrub the working set workingSet.Scrub(); }