正在尝试生成线性近似 table。输出值不正确

Attempting to produce linear approximation table. Values in output are incorrect

这里是c语言给出的代码,s框table为{0xE,0x4,0xD,0x1,0x2,0xF,0xB,0x8,0x3,0xA,0x6,0xC,0x5 , 0x9, 0x0, 0x7};, 当我们 运行 这段代码时,我们得到了错误的输出。我们应该从这段代码中得到线性近似值 table。我认为我得到的错误是在 sbox 输出部分。

#include <stdio.h>
#include <stdlib.h>
typedef unsigned short int UINT16; 

UINT16  sbox_table[16] =  {0xE, 0x4, 0xD, 0x1, 0x2, 0xF, 0xB, 0x8, 0x3, 0xA, 0x6, 0xC, 0x5, 0x9, 0x0, 0x7}; 

int lin_appr_table[16][16];


void construct_lin_appr_table()
{
    UINT16 i, j, k;

    UINT16 X, Y, x;
    UINT16 X_xor, Y_xor;
    int counter;

    for (i=0 ; i<16 ; i++)//sbox input
    {
        
        for (j=0 ; j<16 ; j++)//sbox output
        {
            X=i;
            Y=j;
            
            counter=0;
            for (k=0;k<16;k++)
            {
              X_xor=X&k;
              Y_xor=Y&sbox_table[k];
              
              if(X_xor^Y_xor==0) counter++;
              
             
            }
            
            lin_appr_table[i][j]=counter-8;
            
            //Write the code that makes up the table

        }

    }

    //Write the code that printed the table on the screen
    
    
    for (i=0 ; i<16 ; i++)//sbox input
    {
        for (j=0 ; j<16 ; j++)//sbox output
        {
            printf("% d ", lin_appr_table[i][j]);
        }
        printf("\n");
    }
}  

int main()
{
    construct_lin_appr_table();
    
    getch();
    return 0;
}

预期输出:

建议进行以下两项更改以产生以下 table:

      //if(X_xor^Y_xor==0) counter++;
      if((X_xor^Y_xor)==0) counter++;

注意:对于上面的语句,打开警告应该会导致类似于:

36, 19    warning: ^ has lower precedence than ==; == will be evaluated first   
      //X_xor=X&k;
      X_xor = X & (1 << k); //credit to Weather Vane in comments

结果如下 table:

旁白:通常,在声明期间初始化变量也是一个好主意,并且始终在使用之前。例如:

int lin_appr_table[16][16] = {{0}};//initializes all locations to 0

如果可以,选择使用 portable 而不是 non-portable 代码:

    getchar(); //portable
    //getch(); //not portable

密钥代码更改:参见//if ((X_xor ^ Y_xor) == 0)

#include <stdio.h>
#include <stdlib.h>
typedef unsigned short int UINT16;

const UINT16 sbox_table[16] = {0xE, 0x4, 0xD, 0x1, 0x2, 0xF, 0xB, 0x8, 0x3, 0xA,
    0x6, 0xC, 0x5, 0x9, 0x0, 0x7};

int lin_appr_table[16][16];

// There exist various hacks to quickly count the ones in an integer.
// This is just a simple loop.
unsigned count1(unsigned i) {
  unsigned count = 0;
  while (i) {
    count += i & 1;
    i >>= 1;
  }
  return count;
}

void construct_lin_appr_table() {
  UINT16 i, j, k;
  UINT16 X, Y; //, x;
  UINT16 X_xor, Y_xor;
  int counter;

  for (i = 0; i < 16; i++) {
    for (j = 0; j < 16; j++) {
      X = i;
      Y = j;

      counter = 0;
      for (k = 0; k < 16; k++) {
        X_xor = X & k;
        Y_xor = Y & sbox_table[k];

        //if ((X_xor ^ Y_xor) == 0)
        //if ((count1(X_xor) - count1(Y_xor)) % 2 == 0)
        if ((count1(X_xor ^ Y_xor) & 1) == 0)
          counter++;
      }
      lin_appr_table[i][j] = counter - 16 / 2;
    }
  }

  for (i = 0; i < 16; i++) {
    for (j = 0; j < 16; j++) {
      printf("% d ", lin_appr_table[i][j]);
    }
    printf("\n");
  }
}

int main() {
  construct_lin_appr_table();
  return 0;
}

输出

 8  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
 0  0 -2 -2  0  0 -2  6  2  2  0  0  2  2  0  0 
 0  0 -2 -2  0  0 -2 -2  0  0  2  2  0  0 -6  2 
 0  0  0  0  0  0  0  0  2 -6 -2 -2  2  2 -2 -2 
 0  2  0 -2 -2 -4 -2  0  0 -2  0  2  2 -4  2  0 
 0 -2 -2  0 -2  0  4  2 -2  0 -4  2  0 -2 -2  0 
 0  2 -2  4  2  0  0  2  0 -2  2  4 -2  0  0 -2 
 0 -2  0  2  2 -4  2  0 -2  0  2  0  4  2  0  2 
 0  0  0  0  0  0  0  0 -2  2  2 -2  2 -2 -2 -6 
 0  0 -2 -2  0  0 -2 -2 -4  0 -2  2  0  4  2 -2 
 0  4 -2  2 -4  0  2 -2  2  2  0  0  2  2  0  0 
 0  4  0 -4  4  0  4  0  0  0  0  0  0  0  0  0 
 0 -2  4 -2 -2  0  2  0  2  0  2  4  0  2  0 -2 
 0  2  2  0 -2  4  0  2 -4 -2  2  0  2  0  0  2 
 0  2  2  0 -2 -4  0  2 -2  0  0 -2 -4  2 -2  0 
 0 -2 -4 -2 -2  0  2  0  0 -2  4 -2 -2  0  2  0 

Ref

参见 How to count the number of set bits in a 32-bit integer? 以获得更快的 count1()