在上次实验(具体过程,请点击)的基础上,将攻击点改成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攻击差分值:
结论
一个数和它的补码具有线性相关性,经过一些同样(平行)的操作后,有关的相关性是一致的。