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>
usingnamespace
constint KEY = 10; //密钥长度
constint HALF_KEY = 5; //密钥长度的一半
constint SUB_KEY = 8; //子密钥长度
constint TEXT = 8; //明文或密文的长度
constint HALF_TEXT = 4; //明文或密文长度的一半
constint QUARTER_TEXT = 2; //明文或密文长度的四分之一
const"2416390875"; //置换密钥的字符串
const"52637498"; //从位的密钥中抽取位组成子密钥的置换字符串
const"15203746"; //置换明文的字符串
const"30246175"; //逆置换明文的字符串
const"30121230"; //扩展置换的字符串
constint S0[4][4] = //S0 Box
{
{1, 0, 3, 2},
{3, 2, 1, 0},
{0, 2, 1, 3},
{3, 1, 3, 2}
};
constint 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
}
//加密
bitset<TEXT> Encrypt(string src)
{
return
}
//解密
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
}
//解密
bitset<TEXT> Decrypt(string src)
{
return
}
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
for
{
rs.at(KEY - 1 - i) = src.at(KEY -1 - newPos[i] + '0');
}
return
}
//根据参数newPos改变明文各位的位置
bitset<TEXT> ExchangeTextPos(bitset<TEXT> src, string newPos)
{
bitset<TEXT> rs;
int
for
{
rs.at(TEXT - 1 - i) = src.at(TEXT -1 - newPos[i] + '0');
}
return
}
//获取密钥的左半边
bitset<HALF_KEY> GetKeyLeft(bitset<KEY> src)
{
bitset<HALF_KEY> leftKey;
int
for
{
leftKey.at(i) = src.at(HALF_KEY + i);
}
return
}
//获取密钥的右半边
bitset<HALF_KEY> GetKeyRight(bitset<KEY> src)
{
bitset<HALF_KEY> rightKey;
int
for
{
rightKey.at(i - HALF_KEY) = src.at(i - HALF_KEY);
}
return
}
//根据密钥的左右两边形成完整的密钥
bitset<KEY> FormKey(bitset<HALF_KEY> leftKey, bitset<HALF_KEY> rightKey)
{
bitset<KEY> rsKey;
int
for
{
rsKey.at(i) = rightKey.at(i);
}
for
{
rsKey.at(i) = leftKey.at(i - HALF_KEY);
}
return
}
//获取明文的左半边
bitset<HALF_TEXT> GetTextLeft(bitset<TEXT> src)
{
bitset<HALF_TEXT> leftText;
int
for
{
leftText.at(i) = src.at(HALF_TEXT + i);
}
return
}
//获取明文的右半边
bitset<HALF_TEXT> GetTextRight(bitset<TEXT> src)
{
bitset<HALF_TEXT> rightText;
int
for
{
rightText.at(i - HALF_TEXT) = src.at(i - HALF_TEXT);
}
return
}
//根据明文的左右两边形成完整的明文
bitset<TEXT> FormText(bitset<HALF_TEXT> leftText, bitset<HALF_TEXT> rightText)
{
bitset<TEXT> rsText;
int
for
{
rsText.at(i) = rightText.at(i);
}
for
{
rsText.at(i) = leftText.at(i - HALF_TEXT);
}
return
}
//根据参数newPos从位的密钥中抽取位组成子密钥
bitset<SUB_KEY> PickSubKey(bitset<KEY> src,string newPos)
{
bitset<SUB_KEY> rs;
int
for
{
rs.at(SUB_KEY -1 -i) = src.at(KEY -1 - newPos[i] + '0');
}
return
}
//根据参数newPos将位明文数据扩展成位
bitset<TEXT> ExtendText(bitset<HALF_TEXT> src, string newPos)
{
bitset<TEXT> rs;
int
for
{
rs.at(TEXT - 1 - i) = src.at(HALF_TEXT -1 - newPos[i] + '0');
}
return
}
//将一半长的密钥循环左移(有效范围~HALF_KEY位)
bitset<HALF_KEY> CircleMoveLeft(bitset<HALF_KEY> src, int
{
bitset<HALF_KEY> tmp1,tmp2,rs;
tmp1 = src << moveStep;
tmp2 = src >> HALF_KEY - moveStep;
rs = tmp1 | tmp2;
return
}
//创建子密钥
bitset<SUB_KEY> CreateSubKey(bitset<KEY> src, int
{
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
}
//创建子密钥K1
bitset<SUB_KEY> CreateK1(bitset<KEY> src)
{
return
}
//创建子密钥K2
bitset<SUB_KEY> CreateK2(bitset<KEY> src)
{
//由于K2是在K1循环左移位的基础上循环左移位,因此总共循环左移位
return
}
//返回二进制数据的十进制形式(有效位数位)
int
{
if (binary == "11")
{
return
}
else if (binary == "10")
{
return
}
else if (binary == "01")
{
return
}
else if (binary == "00")
{
return
}
else
{
return
}
}
//SBox
bitset<QUARTER_TEXT> SBox(bitset<HALF_TEXT> src, const int
{
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
}
//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
}
//一次加密
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
}
};
intint argc, char
{
//验证输入参数并显示用法
bool isValid=true;
if
{
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>"
cout << endl;
return
}
//加密或解密
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
}
#include<iostream>
#include<bitset>
#include<string>
usingnamespace
constint KEY = 10; //密钥长度
constint HALF_KEY = 5; //密钥长度的一半
constint SUB_KEY = 8; //子密钥长度
constint TEXT = 8; //明文或密文的长度
constint HALF_TEXT = 4; //明文或密文长度的一半
constint QUARTER_TEXT = 2; //明文或密文长度的四分之一
const"2416390875"; //置换密钥的字符串
const"52637498"; //从位的密钥中抽取位组成子密钥的置换字符串
const"15203746"; //置换明文的字符串
const"30246175"; //逆置换明文的字符串
const"30121230"; //扩展置换的字符串
constint S0[4][4] = //S0 Box
{
{1, 0, 3, 2},
{3, 2, 1, 0},
{0, 2, 1, 3},
{3, 1, 3, 2}
};
constint 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
}
//加密
bitset<TEXT> Encrypt(string src)
{
return
}
//解密
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
}
//解密
bitset<TEXT> Decrypt(string src)
{
return
}
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
for
{
rs.at(KEY - 1 - i) = src.at(KEY -1 - newPos[i] + '0');
}
return
}
//根据参数newPos改变明文各位的位置
bitset<TEXT> ExchangeTextPos(bitset<TEXT> src, string newPos)
{
bitset<TEXT> rs;
int
for
{
rs.at(TEXT - 1 - i) = src.at(TEXT -1 - newPos[i] + '0');
}
return
}
//获取密钥的左半边
bitset<HALF_KEY> GetKeyLeft(bitset<KEY> src)
{
bitset<HALF_KEY> leftKey;
int
for
{
leftKey.at(i) = src.at(HALF_KEY + i);
}
return
}
//获取密钥的右半边
bitset<HALF_KEY> GetKeyRight(bitset<KEY> src)
{
bitset<HALF_KEY> rightKey;
int
for
{
rightKey.at(i - HALF_KEY) = src.at(i - HALF_KEY);
}
return
}
//根据密钥的左右两边形成完整的密钥
bitset<KEY> FormKey(bitset<HALF_KEY> leftKey, bitset<HALF_KEY> rightKey)
{
bitset<KEY> rsKey;
int
for
{
rsKey.at(i) = rightKey.at(i);
}
for
{
rsKey.at(i) = leftKey.at(i - HALF_KEY);
}
return
}
//获取明文的左半边
bitset<HALF_TEXT> GetTextLeft(bitset<TEXT> src)
{
bitset<HALF_TEXT> leftText;
int
for
{
leftText.at(i) = src.at(HALF_TEXT + i);
}
return
}
//获取明文的右半边
bitset<HALF_TEXT> GetTextRight(bitset<TEXT> src)
{
bitset<HALF_TEXT> rightText;
int
for
{
rightText.at(i - HALF_TEXT) = src.at(i - HALF_TEXT);
}
return
}
//根据明文的左右两边形成完整的明文
bitset<TEXT> FormText(bitset<HALF_TEXT> leftText, bitset<HALF_TEXT> rightText)
{
bitset<TEXT> rsText;
int
for
{
rsText.at(i) = rightText.at(i);
}
for
{
rsText.at(i) = leftText.at(i - HALF_TEXT);
}
return
}
//根据参数newPos从位的密钥中抽取位组成子密钥
bitset<SUB_KEY> PickSubKey(bitset<KEY> src,string newPos)
{
bitset<SUB_KEY> rs;
int
for
{
rs.at(SUB_KEY -1 -i) = src.at(KEY -1 - newPos[i] + '0');
}
return
}
//根据参数newPos将位明文数据扩展成位
bitset<TEXT> ExtendText(bitset<HALF_TEXT> src, string newPos)
{
bitset<TEXT> rs;
int
for
{
rs.at(TEXT - 1 - i) = src.at(HALF_TEXT -1 - newPos[i] + '0');
}
return
}
//将一半长的密钥循环左移(有效范围~HALF_KEY位)
bitset<HALF_KEY> CircleMoveLeft(bitset<HALF_KEY> src, int
{
bitset<HALF_KEY> tmp1,tmp2,rs;
tmp1 = src << moveStep;
tmp2 = src >> HALF_KEY - moveStep;
rs = tmp1 | tmp2;
return
}
//创建子密钥
bitset<SUB_KEY> CreateSubKey(bitset<KEY> src, int
{
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
}
//创建子密钥K1
bitset<SUB_KEY> CreateK1(bitset<KEY> src)
{
return
}
//创建子密钥K2
bitset<SUB_KEY> CreateK2(bitset<KEY> src)
{
//由于K2是在K1循环左移位的基础上循环左移位,因此总共循环左移位
return
}
//返回二进制数据的十进制形式(有效位数位)
int
{
if (binary == "11")
{
return
}
else if (binary == "10")
{
return
}
else if (binary == "01")
{
return
}
else if (binary == "00")
{
return
}
else
{
return
}
}
//SBox
bitset<QUARTER_TEXT> SBox(bitset<HALF_TEXT> src, const int
{
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
}
//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
}
//一次加密
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
}
};
intint argc, char
{
//验证输入参数并显示用法
bool isValid=true;
if
{
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>"
cout << endl;
return
}
//加密或解密
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
}