帮我看看这个程序怎么会这样——相关攻击
总共有2个.cpp源文件和一个.h的头文件related_attack.h:
void acc_x3x4(int x1[],int x2[],int x3[],int x4[],int x[]);
1.cpp:
/* fx=x1+x2时符合率最大 P=0.75
LFSR1: x7 x5 x3 x 1
LFSR2: x8 x7 x2 x 1
LFSR3: x14 x12 x2 x 1
LFSR4: x20 x3 1
Cx=x15+x14+x13+x12+x11+x10+x8+x7+x6+x4+1
*/
#include<stdio.h>
#include<math.h>
#include "related_attack.h"
#define N 250
#define r 15
int acc_Ca(int x,int z[]);
void check(int x[],int y[],int n);
void select_m(int a[][r],int b[],int a1,int k);
void lie_f_c(int a[][r]);
void gaosi(int a[][r],int b[],int x1[],int x2[]);
int main()
{
double p=0.75,Er,D,Tr;
int x1[N]={0},x2[N]={0},x3[N]={0},x4[N]={0},z[N]={1,0,0,0,0,1,1,0,1,0,1,0,1,1,1,0,0,1,0,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,1,0,1,1,1,1,0,1,0,1,1,1,1,1,1,1,0,1,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,0,0,1,0,1,0,1,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,1,0,1,1,0,1,0,1,1,0,0,1,0,0,0,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,0,0,1,0,0,0,1,1,1,0,0,0,1,0,1,1,0,1,0,0,1,1,0,1,0,0,1,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,1,1,1,1,0,1,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0};
int i,ca;
Er=N*(2*p-1);
D=4*N*p*(1-p);
Tr=Er-3.09*sqrt(D);
for (i=31976;i<32768;i++)//31977
{
ca=abs(acc_Ca(i,z));
if((double)ca>=Tr)
{
printf("%d ",ca);
printf("\n accept %d \n ",i);
check(x1,x2,i);
acc_x3x4(x1,x2,x3,x4,z);//当i=31977调试完这一步时,p,Er,D,Tr,的值全部变成了0
}
}
}
int acc_Ca(int x,int z[])
{
int i,j;
int a[N]={0},c[r]={1,0,0,0,1,0,1,1,1,0,1,1,1,1,1}; //Cx=x15+x14+x13+x12+x11+x10+x8+x7+x6+x4+1
for (i=0;i<r;i++)
{
a[i]=x%2;
x=x/2;
}
for (i=r;i<N;i++)
for (j=0;j<r;j++)
a[i]=(a[i]+a[i-r+j]*c[j])%2;
for (j=0,i=0;i<N;i++)
{
j=j+1-2*abs((a[i]+z[i])%2);
}
return j;
}
void check (int x[],int y[],int n)
{
int i;
int c[r],a[r][r]={0};
for (i=0;i<r;i++)
{
c[i]=n%2;
n=n/2;
printf("%d",c[i]);
}
printf("\n");
lie_f_c(a);
gaosi(a,c,x,y);
}
void lie_f_c(int a[][r])
{
int i,j;
int a1[r][7]={0},a2[r][8]={0};
for(i=0;i<r;i++){
for(j=0;j<7;j++){
if(i<7) a1[i][i]=1;
else a1[i][j]=(abs(a1[i-7][j]+a1[i-6][j]+a1[i-4][j]+a1[i-2][j]))%2;
//printf("%d",a1[i][j]);
}
//printf("\n");
}
for(i=0;i<r;i++){
for(j=0;j<8;j++){
if(i<8) a2[i][i]=1;
else a2[i][j]=(abs(a2[i-8][j]+a2[i-7][j]+a2[i-6][j]+a2[i-1][j]))%2;
//printf("%d",a2[i][j]);
}
//printf("\n");
}
for(i=0;i<r;i++){
for(j=0;j<r;j++){
if(j<7) a[i][j]=a1[i][j];
else a[i][j]=a2[i][j-7];
//printf("%d",a[i][j]);
}
//printf("\n");
}
}
/*高斯消元法解线性方程组*/
void gaosi(int a[][r],int b[],int x1[],int x2[])
{
int k,j,i;
for(k=0;k<r;k++){
select_m(a,b,a[k][k],k);//选取主元素
for(j=k+1;j<r;j++){
a[k][j]=(abs(a[k][j]/a[k][k]))%2; //wrong!!
}
b[k]=(b[k]/a[k][k])%2;
for(i=k+1;i<r;i++){
for(j=k+1;j<r;j++){
a[i][j]=(abs(a[i][j]-a[i][k]*a[k][j]))%2;
}
b[i]=(abs(b[i]-a[i][k]*b[k]))%2;
}
}
for(i=r-2;i>=0;i--){
for(j=i+1;j<r;j++){
b[i]=(abs(b[i]-a[i][j]*b[j]))%2;
}
}
for(i=0;i<r;i++){
if(i<7) {
if(i==0)
printf("序列a的初态: ");
x1[i]=b[i];
printf("%d ",b[i]);
}
else {
if(i==7)
printf("\n序列b的初态: ");
x2[i-7]=b[i];
printf("%d ",b[i]);
}
}
printf("\n");
}
/*选主元素*/
void select_m(int a[][r],int b[],int a1,int k)
{
int d,t;
int l,i,j;
d=a1;
l=k;
for(i=k+1;i<r;i++){
if(abs(a[i][k])>abs(d)){
d=a[i][k];
l=i;
}
}
if(d==0)
printf("fail!!");
else
if(l!=k){
for(j=k;j<r;j++){
t=a[l][j];
a[l][j]=a[k][j];
a[k][j]=t;
}
t=b[k];
b[k]=b[l];
b[l]=t;
}
}
2.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "related_attack.h"
#define N 250
void acc(int x,int p,int n,int x1[],int x2[],int x3[],int x4[],int z[],int y[]);
void acc_x1(int x[]);
void acc_x2(int x[]);
void acc_x3(int x[]);
void acc_x4(int x1[],int x2[],int x3[],int x4[],int z[]);
int g(int x,int y,int z,int w);
int ensure(int x1[],int x2[],int x3[],int x4[],int z[]);
void acc_x3x4(int x1[],int x2[],int x3[],int x4[],int x[])//x是z
{
int b[14],k[14]={0};
int i,j,n,p=0;
acc_x1(x1);
acc_x2(x2);
for(i=0,j=0;i<14;i++) //找可以由x1x2直接确定的x3x4
{
if(x1[i]==0&&x2[i]==0&&x[i]==1)
{
x3[i]=1;
x4[i]=1;
k[j]=i;
j++;
}
else if(x1[i]==0&&x2[i]==1&&x[i]==0)
{
x3[i]=0;
x4[i]=1;
k[j]=i;
j++;
}
else if(x1[i]==1&&x2[i]==0&&x[i]==0)
{
x3[i]=1;
x4[i]=0;
k[j]=i;
j++;
}
else if(x1[i]==1&&x2[i]==1&&x[i]==1)
{
x3[i]=1;
x4[i]=1;
k[j]=i;
j++;
}
}
/* printf("%d\n",j);
for (i=0;i<14;i++) //调试
printf("%4d",x1[i]);
printf("\n");
for (i=0;i<14;i++)
printf("%4d",x2[i]);
printf("\n"); //调试
for (i=0;i<14;i++)
printf("%4d",x[i]);
printf("\n");
for (i=0;i<14;i++)
printf("%4d",k[i]);
printf("\n"); */
n=(int)pow(2.0,(double)(14-j));
for(i=0;i<n;i++)
{
acc(i,p,n,x1,x2,x3,x4,x,k); //p用作计数来判断x3x4是否合适
if(p==250)
{
for(i=0;i<N;i++)
if(i==0)
printf("x1序列:%d",x1[i]);
else
printf("%d",x1[i]);
printf("\n");
for(i=0;i<N;i++)
if(i==0)
printf("x2序列:%d",x2[i]);
else
printf("%d",x2[i]);
printf("\n");
for(i=0;i<N;i++)
if(i==0)
printf("x3序列:%d",x3[i]);
else
printf("%d",x3[i]);
printf("\n");
for(i=0;i<N;i++)
if(i==0)
printf("x4序列:%d",x4[i]);
else
printf("%d",x4[i]);
printf("\n");
}
}
}
void acc (int x,int p,int n,int x1[],int x2[],int x3[],int x4[],int z[],int y[])
{
int i,j,k,m=0,q=x;
for(i=0,j=0;i<14;i++)
{
if(i==y[j])
j++;
else
{
x3[i]=q%2;
q=q/2;
}
}
for(k=0;k<n;k++,m=k)
{
for(i=0,j=0;i<n;i++)//当i=260时,x3[7]由1变为9;当i=261时,x3[7]和x3[8]都由1变为0;当i=264时,x3[7]x3[8]x3[11]都由1变为0
{
if(i==y[j])
j++;
else
{
x4[i]=m%2;
m=m/2;
}
}
acc_x3(x3);
acc_x4(x1,x2,x3,x4,z);
p=ensure(x1,x2,x3,x4,z);
// printf("%4d",p);
if(p==250)
break;
}
}
void acc_x1(int x[])
{
int i;
for(i=7;i<N;i++)
{
x[i]=(x[i-7]+x[i-6]+x[i-4]+x[i-2])%2;
}
}// x7 x5 x3 x 1
void acc_x2(int x[])
{
int i;
for(i=8;i<N;i++)
x[i]=(x[i-8]+x[i-7]+x[i-6]+x[i-1])%2;
}// x8 x7 x2 x 1
void acc_x3(int x[])
{
int i;
for(i=14;i<N;i++)
x[i]=(x[i-2]+x[i-12]+x[i-13]+x[i-14])%2;
} //x14 x12 x2 x 1
void acc_x4(int x1[],int x2[],int x3[],int x4[],int z[])
{
int i,j;
for(i=14;i<20;i++)
if(z[i]==g(x1[i],x2[i],x3[i],0))
x4[i]=0;
else
x4[i]=1;
for(i=20;i<N;i++)
x4[i]=(x4[i-17])%2;
}// x20 x3
int g(int x,int y,int z,int w)
{
int i;
i=(x+y+x*z+y*w+z*w+x*y*z+x*y*w)%2;
return i;
}//x1x2x1x3 x2x4x3x4x1x2x3x1x2x4
int ensure(int x1[],int x2[],int x3[],int x4[],int z[])
{
int i;
for(i=0;i<N;i++)
if(z[i]!=g(x1[i],x2[i],x3[i],x4[i]))
break;
return i;
}
问题就在代码的注释中,1.cpp里如果不把“acc_x3x4(x1,x2,x3,x4,z);”这一行注释掉,当i=31977调试完这一步时,p,Er,D,Tr,的值全部变成了0,如果注释掉p,Er,D,Tr,的值就一直正常;
2.cpp里 acc(int x,int p,int n,int x1[],int x2[],int x3[],int x4[],int z[],int y[])函数里第二个循环当i=260时,x3[7]由1变为9;当i=261时,x3[7]和x3[8]都由1变为0;当i=264时,x3[7]x3[8]x3[11]都由1变为0,而且我调试以后在这个双重循环里到后面对x4[]的赋值全改变到了对x3[]赋值,不知道为什么。。