S-DES算法的实现

    技术2022-05-11  122

    S-DES算法的实现

     

    介绍

    加密算法涉及五个函数:                                                  

    (1) 初始置换IP (initial permutation)

    (2) 复合函数fk1,它是由子密钥K1确定的,混合了代换和置换的运算。

         (3) 交换函数SW (Switch)

         (4) 复合函数fk2 ,由子密钥K2确定

         (5) 初始置换IP的逆置换IP-1

     

    加密算法的数学表示:  IP-1*fk2*SW*fk1*IP

    也可写为   密文=IP-1(fk2(SW(fk1(IP(明文)))))                                                其中       K1=P8(移位(P10(密钥K)))                                                                              K2=P8(移位(移位(P10(密钥K))))

    解密算法的数学表示:  明文=IP-1(fk1(SW(fk2(IP(密文)))))

    以下是用C++写的源码

     

    #include <iostream>

    #include <bitset>

    #include <string>

     

    using namespace std;

     

    const int KEY = 10;                                //密钥长度

    const int HALF_KEY = 5;                        //密钥长度的一半

    const int SUB_KEY = 8;                         //子密钥长度

    const int TEXT = 8;                                //明文或密文的长度

    const int HALF_TEXT = 4;                       //明文或密文长度的一半

    const int QUARTER_TEXT = 2;                    //明文或密文长度的四分之一

     

    const string P10 = "2416390875";          //置换密钥的字符串

    const string P8 = "52637498";                  //从位的密钥中抽取位组成子密钥的置换字符串

    const string IP = "15203746";                  //置换明文的字符串

    const string IP_1 = "30246175";                //逆置换明文的字符串

    const string EP = "30121230";                  //扩展置换的字符串

    const int S0[4][4] =                           //S0 Box

    {

         {1, 0, 3, 2},     

         {3, 2, 1, 0},

         {0, 2, 1, 3},

         {3, 1, 3, 2}

    };

     

    const int S1[4][4] =                           //S1 Box

    {

         {0, 1, 2, 3},

         {2, 0, 1, 3},

         {3, 0, 1, 0},

         {2, 1, 0, 3}

    };

     

     

    class SDES

    {

    public:

         //构造函数

         SDES(const char* password)

         {

             key = bitset<KEY>(password);    

             k1 = CreateK1(key);

             k2 = CreateK2(key);

         }

     

         SDES(string password)

         {

             key = bitset<KEY>(password);    

             k1 = CreateK1(key);

             k2 = CreateK2(key);

         }

        

         //加密

         bitset<TEXT> Encrypt(bitset<TEXT> src)

         {

             bitset<TEXT> ipText = ExchangeTextPos(src, IP);

             bitset<HALF_TEXT> leftText = GetTextLeft(ipText);

             bitset<HALF_TEXT> rightText = GetTextRight(ipText);

             bitset<HALF_TEXT> boxOutput, rsOutput;

             boxOutput = EncryptBox(leftText, rightText, k1);

             rsOutput = EncryptBox(rightText, boxOutput, k2);

             bitset<TEXT> ip_1Text = FormText(rsOutput, boxOutput); 

             return ExchangeTextPos(ip_1Text, IP_1);

        

         }

     

         //加密

         bitset<TEXT> Encrypt(string src)

         {

             return Encrypt(bitset<TEXT>(src));

         }

        

         //解密

         bitset<TEXT> Decrypt(bitset<TEXT> src)

         {

             bitset<TEXT> ipText = ExchangeTextPos(src, IP);

             bitset<HALF_TEXT> leftText = GetTextLeft(ipText);

             bitset<HALF_TEXT> rightText = GetTextRight(ipText);

             bitset<HALF_TEXT> boxOutput, rsOutput;

             boxOutput = EncryptBox(leftText, rightText, k2);

             rsOutput = EncryptBox(rightText, boxOutput, k1);

             bitset<TEXT> ip_1Text = FormText(rsOutput, boxOutput);

             return ExchangeTextPos(ip_1Text, IP_1);

         }

     

         //解密

         bitset<TEXT> Decrypt(string src)

         {

             return Decrypt(bitset<TEXT>(src));

         }

        

    private:

         bitset<KEY> key;            //密钥

         bitset<SUB_KEY> k1;              //子密钥K1

         bitset<SUB_KEY> k2;              //子密钥K2

        

         //根据参数newPos改变密钥各位的位置

         bitset<KEY> ExchangeKeyPos(bitset<KEY> src, string newPos)

         {

             bitset<KEY> rs;

             int i;

             for (i = 0; i < KEY; i++)

             {

                  rs.at(KEY - 1 - i) = src.at(KEY -1 - newPos[i] + '0');

             }

             return rs;

         }

        

         //根据参数newPos改变明文各位的位置

         bitset<TEXT> ExchangeTextPos(bitset<TEXT> src, string newPos)

         {

             bitset<TEXT> rs;

             int i;

             for (i = 0; i < TEXT; i++)

             {

                  rs.at(TEXT - 1 - i) = src.at(TEXT -1 - newPos[i] + '0');

             }

             return rs;

         }

        

         //获取密钥的左半边

         bitset<HALF_KEY> GetKeyLeft(bitset<KEY> src)

         {

             bitset<HALF_KEY> leftKey;

             int i;

             for (i = 0; i < HALF_KEY; i++)

             {

                  leftKey.at(i) = src.at(HALF_KEY + i);

             }

             return leftKey;

         }

        

         //获取密钥的右半边

         bitset<HALF_KEY> GetKeyRight(bitset<KEY> src)

         {

             bitset<HALF_KEY> rightKey;

             int i;

             for (i = HALF_KEY; i < KEY; i++)

             {

                  rightKey.at(i - HALF_KEY) = src.at(i - HALF_KEY);

             }

             return rightKey;

         }

        

         //根据密钥的左右两边形成完整的密钥

         bitset<KEY> FormKey(bitset<HALF_KEY> leftKey, bitset<HALF_KEY> rightKey)

         {

             bitset<KEY> rsKey;

             int i;

             for (i = 0; i < HALF_KEY; i++)

             {

                  rsKey.at(i) = rightKey.at(i);

             }

             for (i = HALF_KEY; i < KEY; i++)

             {

                  rsKey.at(i) = leftKey.at(i - HALF_KEY);

             }

             return rsKey;

         }

        

         //获取明文的左半边

         bitset<HALF_TEXT> GetTextLeft(bitset<TEXT> src)

         {

             bitset<HALF_TEXT> leftText;

             int i;

             for (i = 0; i < HALF_TEXT; i++)

             {

                  leftText.at(i) = src.at(HALF_TEXT + i);

             }

             return leftText;

         }

        

         //获取明文的右半边

         bitset<HALF_TEXT> GetTextRight(bitset<TEXT> src)

         {

             bitset<HALF_TEXT> rightText;

             int i;

             for (i = HALF_TEXT; i < TEXT; i++)

             {

                  rightText.at(i - HALF_TEXT) = src.at(i - HALF_TEXT);

             }

             return rightText;

         }

        

         //根据明文的左右两边形成完整的明文

         bitset<TEXT> FormText(bitset<HALF_TEXT> leftText, bitset<HALF_TEXT> rightText)

         {

             bitset<TEXT> rsText;

             int i;

             for (i = 0; i < HALF_TEXT; i++)

             {

                  rsText.at(i) = rightText.at(i);

             }

             for (i = HALF_TEXT; i < TEXT; i++)

             {

                  rsText.at(i) = leftText.at(i - HALF_TEXT);

             }

             return rsText;

         }

        

         //根据参数newPos从位的密钥中抽取位组成子密钥

         bitset<SUB_KEY> PickSubKey(bitset<KEY> src,string newPos)

         {

             bitset<SUB_KEY> rs;

             int i;

             for (i = 0; i < SUB_KEY; i++)

             {

                  rs.at(SUB_KEY -1 -i) = src.at(KEY -1 - newPos[i] + '0');

             }

             return rs;

         }

        

         //根据参数newPos将位明文数据扩展成位

         bitset<TEXT> ExtendText(bitset<HALF_TEXT> src, string newPos)

         {

             bitset<TEXT> rs;

             int i;

             for (i = 0; i < TEXT; i++)

             {

                  rs.at(TEXT - 1 - i) = src.at(HALF_TEXT -1 - newPos[i] + '0');

             }

             return rs;

         }

        

         //将一半长的密钥循环左移(有效范围~HALF_KEY位)

         bitset<HALF_KEY> CircleMoveLeft(bitset<HALF_KEY> src, int moveStep)

         {

             bitset<HALF_KEY> tmp1,tmp2,rs;

             tmp1 = src << moveStep;

             tmp2 = src >> HALF_KEY - moveStep;

             rs = tmp1 | tmp2;

             return rs;

         }

        

         //创建子密钥

         bitset<SUB_KEY> CreateSubKey(bitset<KEY> src, int moveLeft)

         {

             bitset<KEY> p10Key = ExchangeKeyPos(src, P10);

             //将密钥拆分成两半

             bitset<HALF_KEY> hKey1, hKey2;

             hKey1 = GetKeyLeft(p10Key);

             hKey2 = GetKeyRight(p10Key);

             //循环左移

             hKey1 = CircleMoveLeft(hKey1, moveLeft);

             hKey2 = CircleMoveLeft(hKey2, moveLeft);

             //将已拆成的两半重新组合成密钥

             bitset<KEY> tmpKey = FormKey(hKey1,hKey2);

             //从位的密钥中抽取位组成子密钥

             return PickSubKey(tmpKey, P8);

         }

        

         //创建子密钥K1

         bitset<SUB_KEY> CreateK1(bitset<KEY> src)

         {

             return CreateSubKey(src, 1);

         }

        

         //创建子密钥K2

         bitset<SUB_KEY> CreateK2(bitset<KEY> src)

         {

             //由于K2是在K1循环左移位的基础上循环左移位,因此总共循环左移位

             return CreateSubKey(src, 3);

         }

        

         //返回二进制数据的十进制形式(有效位数位)

         int ReturnDecimal(string binary)

         {

             if (binary == "11")

             {

                  return 3;

             }

             else if (binary == "10")

             {

                  return 2;

             }

             else if (binary == "01")

             {

                  return 1;

             }

             else if (binary == "00")

             {

                  return 0;

             }

             else

             {

                  return -1;

             }

         }

        

         //SBox

         bitset<QUARTER_TEXT> SBox(bitset<HALF_TEXT> src, const int sbox[4][4])

         {

             string row = "00", col = "00";

             row[0] = src[3] + '0';

             row[1] = src[0] + '0';

             col[0] = src[2] + '0';

             col[1] = src[1] + '0';

             int decimal = sbox[ReturnDecimal(row)][ReturnDecimal(col)];

             return bitset<QUARTER_TEXT>(decimal);

         }

        

         //P4

         bitset<HALF_TEXT> P4(bitset<QUARTER_TEXT> src1, bitset<QUARTER_TEXT> src2)

         {

             bitset<HALF_TEXT> rs;

             rs[3] = src1[0];

             rs[2] = src2[0];

             rs[1] = src2[1];

             rs[0] = src1[1];

             return rs;

         }

        

         //一次加密

         bitset<HALF_TEXT> EncryptBox(bitset<HALF_TEXT> leftText, bitset<HALF_TEXT> rightText,

             bitset<SUB_KEY> subKey)

         {

             bitset<TEXT> epText = ExtendText(rightText, EP);

             bitset<TEXT> xorText1 = epText ^ subKey;

             bitset<HALF_TEXT> s0Input, s1Input;

             bitset<QUARTER_TEXT> s0Output, s1Output;

             s0Input = GetTextLeft(xorText1);

             s1Input = GetTextRight(xorText1);

             s0Output = SBox(s0Input, S0);

             s1Output = SBox(s1Input, S1);

             bitset<HALF_TEXT> p4 = P4(s0Output, s1Output);

             bitset<HALF_TEXT> boxOutput = p4 ^ leftText;

             return boxOutput;

         }   

        

    };

     

     

    int main(int argc, char *argv[])

    {

         //验证输入参数并显示用法

         bool isValid=true;

         if (argc == 4)

         {

             isValid &= (strcmp(argv[1], "e")==0 || strcmp(argv[1], "d")==0

                  || strcmp(argv[1], "E")==0 || strcmp(argv[1], "D")==0);

             isValid &= (strlen(argv[2])==10);

             isValid &= (strlen(argv[3])==8);

         }

         else

         {

             isValid = false;

         }

         if (isValid == false)

         {

             cout << endl;

             cout << "Usage: S-DES <E|D> <Key> <Text>" << endl ;

             cout << endl;

             return 0;

         }

     

         //加密或解密

         string key(argv[2]), text(argv[3]);

         SDES des(key);

         if (strcmp(argv[1], "e") == 0 || strcmp(argv[1], "E") ==0 )

         {

             cout << des.Encrypt(text) << endl;

         }

         else

         {

             cout << des.Decrypt(text) << endl;

         }

         return 0;

    }

     

     

     


    最新回复(0)