// //////////////////////////////////////////////////////////////////// // // Search for an S-Box // // clang -O3 sbox-s1.c -o sbox-s1 #include #include #include #include #include #include // //////////////////////////////////////////////////////////////////// #define SEPARATOR "------------------------------------------------------------------------------------------------" void test_sbox_qmc (int * sbox, int dimension, int verbose, int * num_products, int * max_degrees, int * sums_degrees, int * used_variables); #define OUTPUT_BFUNC_INPUT // //////////////////////////////////////////////////////////////////// #if 0 int popCount(unsigned x) { // Taken from book "Hackers Delight" x = x - ((x >> 1) & 0x55555555); x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = (x + (x >> 4)) & 0x0F0F0F0F; x = x + (x >> 8); x = x + (x >> 16); return x & 0x0000003F; } #else #define popCount __builtin_popcount #endif // Calculate hamming weight/distance of two integer numbers int hammingDistance(int v1, int v2) { return popCount(v1 ^ v2); } // //////////////////////////////////////////////////////////////////// #define QMC_NO_STANDALONE #include "./qmc.c" // //////////////////////////////////////////////////////////////////// #define limb_t uint32_t #define BITS_IN_LIMB 32 #define DEGREE 4 // //////////////////////////////////////////////////////////////////// int minimum(int a, int b) { return (a=0;--i) putchar(value & (1<=0;--i) printf("%d", i); printf("\n"); for (i=0;i maxout) maxout = diff[i][j]; \ printf("%3d ",maxout); \ if ((i % 16 == 15) || (i == size - 1)) printf("\n"); \ } \ } while(0) void evaluatesbox(int * sbox, int * numfix, int * maxdout_arith, int * maxdout_bitw, int dimension, int output) { int i,j,k; int t,max; int size = 1 << dimension; int diff[size][size]; * numfix = 0; for (i=0;imax) max=t; } *maxdout_arith = max; if (output) { printf("\nDOUTS (arithmetic)\n"); outputmaxdiffs(); } resetdiffs(); max = 0; for (i=0;imax) max=t; } *maxdout_bitw = max; if (output) { printf("\nDOUTS (bitwise)\n"); outputmaxdiffs(); } } // //////////////////////////////////////////////////////////////////// void process_one_sbox(int * sbox, int * sinv, int dimension) { int size = 1 << dimension; int i,j,lin, lin_inv; int mask; int numfix, maxdout_arith , maxdout_bitw; int numfix_inv, maxdout_arith_inv, maxdout_bitw_inv; // Store the NOT of an S-Box (also used for the NOT of the inverse) int sbox_not[size]; // Stats for the S-Box int countz[dimension][dimension+1]; // count the bit flips int weights[dimension]; // weights of the SOPs, for each output bit int weights_not[dimension]; // weights of the NOT-SOP --- int weights_min[dimension]; // min of the two above int degrees[dimension]; // max degree of the products in the SOP, for each output bit int degrees_not[dimension]; // max degree of the products in the NOT-SOP, for each output bit int degrees_min[dimension]; // min of the two above int sums_degrees[dimension]; // sum of the degrees of the products in the SOP (each output) int sums_degrees_not[dimension]; // same for the NOT-SOP int sums_degrees_min[dimension]; // min of the two abovey int used_variables[dimension]; int used_variables_not[dimension]; int used_variables_tot = 0; // Stats for the inverse S-Box (add "_inv", same descriptions) int countz_inv[dimension][dimension+1]; int weights_inv[dimension]; int weights_inv_not[dimension]; int weights_inv_min[dimension]; int degrees_inv[dimension]; int degrees_inv_not[dimension]; int degrees_inv_min[dimension]; int sums_degrees_inv[dimension]; int sums_degrees_inv_not[dimension]; int sums_degrees_inv_min[dimension]; int used_variables_inv[dimension]; int used_variables_inv_not[dimension]; /* int used_variables_tot_inv = 0; */ #ifdef COMPUTE_ANF int ANF[size]; int ANF_inv[size]; #endif int is_involution; is_involution = is_same(sbox, sinv, size); // //////////////////////////////////////////////////////////////// evaluatesbox(sbox, &numfix, &maxdout_arith, &maxdout_bitw, dimension, 0); lin = linearity(sbox, dimension); for (i=0,mask=1; i max_weight) max_weight = weights_min[i]; degrees_min[i] = minimum(degrees[i], degrees_not[i]); if (degrees_min[i] > max_degree) max_degree = degrees_min[i]; sums_degrees_min[i] = minimum(sums_degrees[i], sums_degrees_not[i]); if (sums_degrees_min[i] > max_sums_degrees) max_sums_degrees = sums_degrees_min[i]; tot_weight += weights_min[i]; used_variables_tot &= used_variables[i]; /* this same for function and not */ } if (!is_involution) { for (i=0; i max_weight_inv) max_weight_inv = weights_inv_min[i]; degrees_inv_min[i] = minimum(degrees_inv[i], degrees_inv_not[i]); if (degrees_inv_min[i] > max_degree_inv) max_degree_inv = degrees_inv_min[i]; sums_degrees_inv_min[i] = minimum(sums_degrees_inv[i], sums_degrees_inv_not[i]); if (sums_degrees_inv_min[i] > max_sums_degrees_inv) max_sums_degrees_inv = sums_degrees_inv_min[i]; tot_weight_inv += weights_inv_min[i]; /* used_variables_tot_inv &= used_variables_inv[i]; */ } } if ( ( (max_weight <= MAX_WEIGHT_IN_SOP) && (tot_weight <= MAX_SUM_WEIGHTS_IN_SOP) && (max_degree <= MAX_DEGREE_IN_SOP) && (max_sums_degrees <= MAX_SUM_OF_DEGREES_IN_SOP) && (used_variables_tot >= MIN_USED_VARIABLES) && (numfix <= MAX_FIXED_POINTS) ) && ( is_involution || ( (max_weight_inv <= MAX_WEIGHT_IN_SOP) && (tot_weight_inv <= MAX_SUM_WEIGHTS_IN_SOP) && (max_degree_inv <= MAX_DEGREE_IN_SOP) && (max_sums_degrees_inv <= MAX_SUM_OF_DEGREES_IN_SOP) /* && (used_variables_tot_inv >= MIN_USED_VARIABLES) */ ) ) ) { printf("SBOX = { "); for (i=0;i