s-des密码算法实现

实验二 S-DES算法实现

 

一、S-DES算法分析

1、Simplified DES方案,简称S-DES方案。它是一个供教学而非安全的加密算法,它与DES的特性和结构类似,但参数小。

加密算法涉及五个函数:
(1)初始置换IP(initial permutation)
(2)复合函数fk1,它是由密钥K确定的,具有置换和代换的运算。      

(3)置换函数SW
(4)复合函数fk2
(5)初始置换IP的逆置换IP-1

下面是S-DES算法的框图。

 

 

 

 

 

 

(1) S-DES的密钥生成:
设10bit的密钥为( k1,k2,…,k10 )
几个重要的定义:

P10(k1,k2,…,k10)=(k3,k5,k2,k7,k4,k10,k1,k9,k8,k6)   

 

P8= (k1,k2,…,k10)=(k6,k3,k7,k4,k8,k5,k10,k9 ) 

LS-1为循环左移1位:abcdeàbcdea

LS-2为循环左移2位:  abcdeàcdeab

 

 

 

(2)    S-DES的加密运算:

  初始置换用IP函数:

   IP=      1 2 3 4 5 6 7 8 

     2 6 3 1 4 8 5 7

 

末端算法的置换为IP的逆置换:
IP-1=     1 2 3 4 5 6 7 8

           4 1 3 5 7 2 8 6

    

 

E/P为扩展置换,将4位1,2,3,4扩展置换如下:

E/P   4  1  2  3  2  3  4  1 

 

2个S盒的定义为:

 

 

S盒按下述规则运算:

将第1和第4的输入比特做为2- bit数,指示为S盒的一个行;将第2和第3的输入比特做为S盒的一个列。如此确定为S盒矩阵的(i,j)数。

例如:(P0,0, P0,3)=(00),并且(P0,1,P0,2)=(1 0)

确定了S0中的第0行2列(0,2)的系数为3,记为(1 1)输出。

由S0, S1输出4-bit经置换


 P4:      1        2      3    4

           2        4      3  1

它的输出就是F函数的输出。

 

 

总结如下: 

P10={3,5,2,7,4,10,1,9,8,6}; 

P8={6,3,7,4,8,5,10,9}; 

P4={2,4,3,1}; 

IP={2,6,3,1,4,8,5,7};

IP-1={4,1,3,5,7,2,8,6};

EP={4,1,2,3,2,3,4,1};

 

 

 

代码如下:

#include<iostream>
#include<string>
using namespace std;
int K1=0;
int K2=0;
static int P10MAX=10;
static int P8MAX=10;
static int P4MAX=4;
static int IPMAX=8;
static int IPIMAX=8;
static int EPMAX=4;
static int P10[]={3,5,2,7,4,10,1,9,8,6,'\0'};
static int P8[]={6,3,7,4,8,5,10,9,'\0'};
static int P4[]={2,4,3,1,'\0'};
static int IP[]={2,6,3,1,4,8,5,7,'\0'};
static int IPI[]={4,1,3,5,7,2,8,6,'\0'};
static int EP[]={4,1,2,3,2,3,4,1,'\0'};
static int S0[4][4]={
	{1,0,3,2},
	{3,2,1,0},
	{0,2,1,3},
	{3,1,3,2},
};
static int S1[4][4]={
	{0,1,2,3},
	{2,0,1,3},
	{3,0,1,0},
	{2,1,0,3},
};

int Getlength(int p[])
{
	int i=0;
	for(;p[i]!='\0';++i);
	return i;
}
int BinaryToDecimal(string binary){
	int result=0;
	for(int i=0;i<binary.length();i++){
		result=2*result+(binary[i]-'0');
	}
	return result;
}
void printBin(int x,int n)
{
	int mask=1<<(n-1);
	while(mask>0){
		((x&mask)==0)?printf("0"):printf("1");
		mask>>=1;
	}
	cout<<endl;
}
int Permute(int inum,int p[],int pmax)
{
	int result=0;
	int length=Getlength(p);
	for(int i=0;i<length;++i)
	{
		result<<=1;
		result=(inum>>(pmax-p[i]))&1;
	}
	return result;
}
int F(int R,int K){
	int t = Permute(R,EP,EPMAX)^K;
	int t0 = (t>>4)&0xf;
	int t1 = t&0xf;
	t0 = S0[((t0&0x8)>>2)|(t0&1)][(t0>>1)&0x3];
	t1 = S1[((t0&0x8)>>2)|(t1&1)][(t1>>1)&0x3];
	t = Permute((t0<<2)|t1,P4,P4MAX);
	return t;
}

int fk(int m,int k){
	int l = (m>>4)&0xf;
	int r = m&0xf;
	return((l^F(r,k))<<4)|r;
}

int SW(int x){
	return((x&0xf)<<4)|((x>>4)&0xf);
}
int encrypt(int m){
	m=Permute(m,IP,IPMAX);
	m=fk(m,K1);
	m=SW(m);
	m=fk(m,K2);
	m=Permute(m,IPI,IPMAX);
	return m;
}

int decrypt(int m){
	m=Permute(m,IP,IPMAX);
	m=fk(m,K2);
	m=SW(m);
	m=fk(m,K1);
	m=Permute(m,IPI,IPMAX);
	return m;
}

void SDES(int K){
	int t1=0,t2=0;
	K=Permute(K,P10,P10MAX);
	t1=(K>>5)&&0x1f;
	t2=K & 0x1f;
	t1=((t1&0xf)<<1)|((t1&0x10)>>4);
	t2=((t2&0xf)<<1)|((t2 & 0x10)>>4);
	K1=Permute((t1<<5)|t2,P8,P8MAX);
	t1=((t1 & 0x07)<<2)|((t1 & 0x18)>>3);
	t2=((t2 & 0x07)<<2)|((t2 & 0x18)>>3);
	K2=Permute((t1<<5)|t2,P8,P8MAX);
	cout<<"K1 为:"<<endl;
	cout<<K1<<endl;
	cout<<"K2 为:"<<endl;
	cout<<K2<<endl;
}

int main()
{   cout<<"***************输入均为二进制***************"<<endl;
loop: cout<<"***************请选择:加密为1 解密为0***************"<<endl;
	int i;
cin>>i;
if(i==0)
{

	cout<<"***************解密:***************"<<endl;
	 string plaintext;
 cout<<"***************请输入密文:***************"<<endl;
	 cin>>plaintext;

	 string key;
 cout<<"***************请输入密钥:***************"<<endl;
 cin>>key;
 SDES(BinaryToDecimal(key));
 cout<<"***************得到明文:***************"<<endl;
 printBin(encrypt(BinaryToDecimal(plaintext)),8);
 cout<<"***************是否跳出 跳出为0 继续为1***************"<<endl;
 int j;
		 cin>>j;
		 switch(j)
		 {
		 case 0: {cout<<"***************欢迎使用s-des程序***************"<<endl;
				 cout<<"***************czy***************";
				 return 0;}
		 case 1: goto loop;
		 }
}
  if (i==1)
	{
		cout<<"***************加密:***************"<<endl;
	 string ciphertext;
		cout<<"***************请输入明文:***************"<<endl;
		 cin>>ciphertext;
	 cout<<"***************请输入密钥:***************"<<endl;
	 string key;
	 cin>>key;
	 SDES(BinaryToDecimal(key));
		cout<<"***************得到密文:***************"<<endl;
		 printBin(decrypt(BinaryToDecimal(ciphertext)),8);
		 cout<<"***************是否跳出 跳出为0 继续为1***************"<<endl;
		 int j;
		 cin>>j;
		 switch(j)
		 {
		 case 0: {cout<<"***************欢迎使用s-des程序***************"<<endl;
			 cout<<"***************czy***************";return 0;}
		 case 1: goto loop;
		 }
	}
}



  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的C++实现DES密码算法的示例代码。由于DES算法中使用了大量的位运算,因此代码可能看起来比较复杂。 ```cpp #include <iostream> #include <bitset> #include <cstring> using namespace std; // 初始置换表IP int IP_Table[64] = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 }; // 逆置换表IP^-1 int IP_1_Table[64] = { 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 }; // 扩展置换表E int E_Table[48] = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 }; // S盒 int S_Box[8][4][16] = { { // S1 {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13} }, { // S2 {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9} }, { // S3 {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12} }, { // S4 {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14} }, { // S5 {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3} }, { // S6 {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13} }, { // S7 {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12} }, { // S8 {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} } }; // 置换函数P int P_Table[32] = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 }; // 左移位数表 int Shift_Table[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; // 密钥置换表PC-1 int PC_1_Table[56] = { 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 }; // 密钥置换表PC-2 int PC_2_Table[48] = { 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 }; // 子密钥数组 int SubKey[16][48]; // 将64位的明文或密文进行初始置换IP void IP_Transform(bool* data) { bool temp[64]; for (int i = 0; i < 64; i++) { temp[i] = data[IP_Table[i] - 1]; } memcpy(data, temp, sizeof(temp)); } // 将64位的明文或密文进行逆置换IP^-1 void IP_1_Transform(bool* data) { bool temp[64]; for (int i = 0; i < 64; i++) { temp[i] = data[IP_1_Table[i] - 1]; } memcpy(data, temp, sizeof(temp)); } // 将32位的数据左移shift位 void Shift_Left(bool* data, int shift) { bool temp[256]; memcpy(temp, data, sizeof(temp)); for (int i = 0; i < 32; i++) { data[i] = temp[(i + shift) % 32]; } } // 将64位密钥进行PC-1置换 void PC_1_Transform(bool* key) { bool temp[56]; for (int i = 0; i < 56; i++) { temp[i] = key[PC_1_Table[i] - 1]; } memcpy(key, temp, sizeof(temp)); } // 将56位密钥进行PC-2置换,生成48位的子密钥 void PC_2_Transform(bool* key, int index) { bool temp[48]; for (int i = 0; i < 48; i++) { temp[i] = key[PC_2_Table[i] - 1]; } memcpy(SubKey[index], temp, sizeof(temp)); } // 将48位数据进行扩展,扩展为64位 void E_Transform(bool* data) { bool temp[64]; for (int i = 0; i < 48; i++) { temp[i] = data[E_Table[i] - 1]; } memcpy(data, temp, sizeof(temp)); } // S盒代替函数 void S_Box_Transform(bool* data) { int index; for (int i = 0, j = 0; i < 8; i++, j += 6) { int x = (data[j] << 1) + data[j + 5]; int y = (data[j + 1] << 3) + (data[j + 2] << 2) + (data[j + 3] << 1) + data[j + 4]; index = (i << 2) + y; int value = S_Box[i][x][y]; for (int k = 0; k < 4; k++) { data[j + 3 - k] = (value >> k) & 1; } } } // P置换 void P_Transform(bool* data) { bool temp[32]; for (int i = 0; i < 32; i++) { temp[i] = data[P_Table[i] - 1]; } memcpy(data, temp, sizeof(temp)); } // 生成子密钥 void Generate_SubKey(bool* key) { bool temp[64]; PC_1_Transform(key); for (int i = 0; i < 16; i++) { memcpy(temp, key, sizeof(temp)); Shift_Left(temp, Shift_Table[i]); PC_2_Transform(temp, i); } } // 加密单个64位分组 void Encrypt_One_Block(bool* block) { IP_Transform(block); for (int i = 0; i < 16; i++) { bool L[32]; bool R[32]; bool temp[32]; memcpy(L, block, 32); memcpy(R, block + 32, 32); memcpy(temp, R, 32); E_Transform(temp); for (int j = 0; j < 48; j++) { temp[j] ^= SubKey[i][j]; } S_Box_Transform(temp); P_Transform(temp); for (int j = 0; j < 32; j++) { R[j] ^= temp[j]; } memcpy(block, L, 32); memcpy(block + 32, R, 32); } IP_1_Transform(block); } // 加密函数 void Encrypt(bool* data, int len, bool* key) { Generate_SubKey(key); for (int i = 0; i < len; i += 8) { Encrypt_One_Block(data + i); } } // 测试 int main() { // 明文 bool data[64] = { 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0,

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值