DES入盒前的CPA攻击

在上次实验(具体过程,请点击)的基础上,将攻击点改成Sbox的输入做CPA攻击。记录并思考解释其攻击结果

实验源码

#include <iostream>
#include<math.h>
#include<iomanip>
using namespace std;

int HWFun(int num);
int Sboxout(int num, int Nkey,int i);
double Corr(int n, int Pstd[], int Ptest[]);
double meanNum(int n, int num[]);
void Dpa();

int S_Box1[4][16] = {                     //8个S盒   三维数组
	// 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 };

int mingwen[20] = { 41,35,62,4,33,
				44,22,46,18,16,
				9,49,49,59,41,
				43,51,38,27,60 };

int HWw[64][20];
int Ptest[64][20];
int Pstd[20];
int HWstd[20];


//DPA
double DpaP[64][2];
//记录上述差值
double Deta[64];
int DpaMax;

int Sout[64][20];
double Rl[64];
//相关系数最大位置
int Max;


int main()
{
	//int Key = 0b00101011;
	int Key = 0;
	cout << "序号	明文	二进制明文	Sout	HW	P\n";
	for (int Nkey = 0; Nkey < 64; Nkey++) {

		for (int i = 0; i < 20; i++) {
			Sboxout(mingwen[i] ^ Key, Nkey,i);
		}
		//密钥从0-63
		Key++;
	}

	cout << "HW:key0-19\n";
	for (int i = 0; i < 20; i++) {

		for (int j = 0; j < 20; j++) {
			cout << HWw[i][j] << "   ";
		}
		cout << "\n";
	}
	cout << "HW:key20-39\n";
	for (int i = 0; i < 20; i++) {
		for (int j = 20; j < 40; j++) {
			cout << HWw[j][i] << "   ";
		}
		cout << "\n";
	}
	cout << "HW:key40-63\n";
	for (int i = 0; i < 20; i++) {
		for (int j = 40; j < 60; j++) {
			cout << HWw[j][i] << "   ";
		}
		cout << "\n";
	}
	cout << "HW:key60-63\n";
	for (int i = 0; i < 20; i++) {
		for (int j = 60; j < 64; j++) {
			cout << HWw[j][i] << "   ";
		}
		cout << "\n";
	}
	cout << "相关系数:R0-63:\n";
	double temp=0.0;
	for (int i = 0; i < 64; i++) {
		Rl[i]=abs( Corr(10, Pstd, HWw[i]));
		if (Rl[i] > temp) {
			Max = i;
			temp = Rl[i];
		}
		cout << setw(10) << Rl[i] << "  ";
		if ((i+1) % 8 == 0)
			cout << "\n";
	}

	cout << "\nCPA攻击:\n";
	cout << "最大相关:R" << Max << "=" << Rl[Max];
	cout << "\n正确密钥:";
	int bit[6];
	int temp1 = Max;
	for (int j =5; j >= 0; j--) {
		bit[j] = temp1 % 2;

		temp1 = temp1 / 2;
	}
	for (int j = 0; j < 6; j++) {
		cout << bit[j];
	}
	Dpa();

	cout << "\nKey20和Key43:HW20和HW43值:\n";
	for (int i = 0; i < 20; i++) {
		cout << HWw[20][i] << " ";
	}
	cout << "\n";
	for (int i = 0; i < 20; i++) {
		cout << HWw[43][i] << " ";
	}


	cout << "\nKey20和Key43:P20和P43值:\n";
	for (int i = 0; i < 20; i++) {
		cout << Ptest[20][i] << " ";
	}
	cout << "\n";
	for (int i = 0; i < 20; i++) {
		cout << Ptest[43][i] << " ";
	}


	cout << "\nKey20和Key43:异或后输入的值:\n";
	for (int i = 0; i < 20; i++) {
		cout << Sout[20][i] << " ";
	}
	cout << "\n";
	for (int i = 0; i < 20; i++) {
		cout << Sout[43][i] << " ";
	}

	return 0;
}

void Dpa() {
	//以2为界
	int Larr[20];
	int Harr[20];
	int Lc = 0;
	int Hc = 0;

	for (int i = 0; i < 20; i++) {
		if (HWstd[i] < 2) {
			Larr[Lc] = i;
			Lc++;
		}
		else {
			Harr[Hc] = i;
			Hc++;
		}
	}
	
	for (int i = 0; i < 64; i++) {
		int Htemp = 0;
		int Ltemp = 0;
		
		//HW小于2,对应累加
		for (int j= 0; j < Lc; j++) {
		
			Ltemp += Ptest[i][Larr[j]];
		}
		//HW大于2,对应累加
		for (int j = 0; j < Hc; j++) {

			Htemp += Ptest[i][Harr[j]];
		}
		

		DpaP[i][0] = Ltemp*1.0/Lc;
		DpaP[i][1] = Htemp*1.0/Hc;
		Deta[i] = abs(DpaP[i][0] - DpaP[i][1]);


	}

	cout << "\nDPA攻击\n差分值:Deta0-63:\n";
	for (int i = 0; i < 64; i++) {
		cout <<setw(10)<< Deta[i] << " ";
		if ((i + 1) % 8 == 0) {
			cout << "\n";
		}
	}

	double temp = 0.0;
	for (int i = 0; i < 64; i++) {
		if (Deta[i] > temp) {
			DpaMax= i;
			temp = Deta[i];
		}
	}

	cout << "\n最大差分值:Deta"<<DpaMax<<"="<< Deta[DpaMax];

	cout << "\n正确密钥:";
	int bit[6];
	int temp1 =DpaMax;
	for (int j = 5; j >= 0; j--) {
		bit[j] = temp1 % 2;

		temp1 = temp1 / 2;
	}
	for (int j = 0; j < 6; j++) {
		cout << bit[j];
	}

}

int Sboxout(int num, int Nkey,int i) {

	int HW = 0;
	int P = 0;

	Sout[Nkey][i] = num;

	HWw[Nkey][i] = HWFun(num);
	Ptest[Nkey][i] = HWw[Nkey][i] * 5;
	//cout << "	" << HWw[Nkey][i];
	P = HWw[Nkey][i] * 5;
	if (Nkey == 43) {
		Pstd[i] = P;
		HWstd[i] = HWw[Nkey][i];
	
	}
		
	return num;
}


int HWFun(int num) {
	int count = 0;
	int bit;
	for (int i = 5; i >= 0; i--) {
		bit = num % 2;
		if (bit == 1)
			count++;
		num = num / 2;
	};

	return count;
}


double meanNum(int n, int num[]) {
	double total=0.0;
	for (int i = 0; i < n; i++) {
		total = total + num[i];
	}
	return total / n;
}

double Corr(int n, int Pstd[], int Ptest[]) {

	//int E_Pstd;
	double fenzi=0.0;
	double PstdMean = meanNum(n, Pstd);
	double PtestdMean = meanNum(n, Ptest);
	

	double fenmu1 = 0.0;
	double fenmu2 = 0.0;
	double corr = 0.0;

	for (int i = 0; i < n; i++) {
		fenzi += (Pstd[i] - PstdMean) * (Ptest[i] - PtestdMean);
		fenmu2 += (Ptest[i] - PtestdMean)* (Ptest[i] - PtestdMean);
		fenmu1 += (Pstd[i] - PstdMean) * (Pstd[i] - PstdMean);

	}

	corr = fenzi / (sqrt(fenmu1) * sqrt(fenmu2));

	return corr;
}

在这里插入图片描述
在这里插入图片描述

分析

Key20和Key43:异或后输入的值:
61 55 42 16 53 56 2 58 6 4 29 37 37 47 61 63 39 50 15 40
2 8 21 47 10 7 61 5 57 59 34 26 26 16 2 0 24 13 48 23
Key20和Key43:
HW20和HW43值:
HW20:5 5 3 1 4 3 1 4 2 1 4 3 3 5 5 6 4 3 4 2
HW43:1 1 3 5 2 3 5 2 4 5 2 3 3 1 1 0 2 3 2 4
和: 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
可以看出两者对应位的HW和为6,即密钥key的位数。

20二进制:010100
43二进制:101011
20+43=63,所以二者在6bit中互为补码。
HW20=6-HW43 HW20与HW43线性相关
P=HW*5;
P20=6-P43/5 P20与P43线性相关
所以R20=R43=1;

调整控制台输出,观察CPA攻击系数:
在这里插入图片描述
相关系数的值和对称位置相等。
在这里插入图片描述
观察DPA攻击差分值:

结论

一个数和它的补码具有线性相关性,经过一些同样(平行)的操作后,有关的相关性是一致的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值