YAARX: Yet Another ARX Toolkit  0.1
 All Data Structures Files Functions Variables Macros Pages
xdp-add.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2013 Luxembourg University,
3  * Laboratory of Algorithmics, Cryptology and Security (LACS).
4  *
5  * This file is part of the YAARX toolkit. YAARX stands for
6  * Yet Another ARX toolkit for analysis of ARX cryptographic algorithms.
7  *
8  * YAARX is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * YAARX is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with YAARX. If not, see <http://www.gnu.org/licenses/>.
20  */
27 #ifndef XDP_ADD_H
28 #define XDP_ADD_H
29 
30 #ifndef XDP_ADD_MSIZE
31 #define XDP_ADD_MSIZE 4
32 #endif
33 #ifndef XDP_ADD_NMATRIX
34 #define XDP_ADD_NMATRIX 8
35 #endif
36 #ifndef XDP_ADD_NINPUTS
37 #define XDP_ADD_NINPUTS 2
38 #endif
39 #ifndef XDP_ADD_ISTATE
40 #define XDP_ADD_ISTATE 0
41 #endif
42 #ifndef XDP_ADD_COLSUM
43 #define XDP_ADD_COLSUM 4
44 #endif
45 #ifndef XDP_ADD_NORM
46 #define XDP_ADD_NORM 1.0 /(double)XDP_ADD_COLSUM
47 #endif
48 
49 void xdp_add_alloc_matrices(gsl_matrix* A[2][2][2]);
50 
51 void xdp_add_free_matrices(gsl_matrix* A[2][2][2]);
52 
53 void xdp_add_normalize_matrices(gsl_matrix* A[2][2][2]);
54 
55 void xdp_add_print_matrices(gsl_matrix* A[2][2][2]);
56 
57 void xdp_add_print_matrices_sage(gsl_matrix* A[2][2][2]);
58 
59 void xdp_add_sf(gsl_matrix* A[2][2][2]);
60 
61 double xdp_add(gsl_matrix* A[2][2][2], WORD_T da, WORD_T db, WORD_T dc);
62 
63 double xdp_add_exper(const WORD_T da, const WORD_T db, const WORD_T dc);
64 
65 WORD_T aop(WORD_T x, WORD_T n_in);
66 
67 WORD_T cap(WORD_T x, WORD_T y);
68 
69 bool is_eq(WORD_T x, WORD_T y, WORD_T z);
70 
71 WORD_T eq(const WORD_T x, const WORD_T y, const WORD_T z);
72 
73 WORD_T eq(const WORD_T x, const WORD_T y, const WORD_T z, const uint32_t word_size);
74 
75 bool xdp_add_is_nonzero(WORD_T da, WORD_T db, WORD_T dc);
76 
77 //double xdp_add_lm(WORD_T da, WORD_T db, WORD_T dc);
78 
79 //double xdp_add_lm(WORD_T da, WORD_T db, WORD_T dc, uint32_t word_size);
80 
93 inline double xdp_add_lm(WORD_T da, WORD_T db, WORD_T dc)
94 {
95 #if 0 // DEBUG
96  printf("[%s:%d] %s() %llX %llX %llX\n", __FILE__, __LINE__, __FUNCTION__,
97  (WORD_MAX_T)da, (WORD_MAX_T)db, (WORD_MAX_T)dc);
98 #endif// #if 0 // DEBUG
99  double p = 0.0;
100 #if(WORD_SIZE <= 32) // mask without the MSB
101  WORD_T mask_no_msb = (0xffffffffUL >> (32 - (WORD_SIZE - 1)));
102  WORD_T eq_d = eq(da, db, dc);
103  WORD_T eq_d_sl_1 = ((eq_d << 1) | 0x00000001UL) & MASK;
104 #else // #if(WORD_SIZE <= 32)
105  // WORD_T mask_no_msb = (0xffffffffffffffffUL >> (64 - (WORD_SIZE - 1))); <- ULL
106  WORD_T mask_no_msb = (0xffffffffffffffffULL >> (64 - (WORD_SIZE - 1)));
107  WORD_T eq_d = eq(da, db, dc);
108  WORD_T eq_d_sl_1 = ((eq_d << 1) | 0x0000000000000001ULL) & MASK;
109 #endif // #if(WORD_SIZE <= 32)
110  // bool b_is_possible = ((eq((da << 1), (db << 1), (dc << 1)) & (da ^ db ^ dc ^ (da << 1))) == 0);
111  bool b_is_possible = ((eq_d_sl_1 & (da ^ db ^ dc ^ (da << 1))) == 0);
112  if(b_is_possible) {
113  // WORD_T neq = ~eq(da, db, dc); // positions at which da,db and dc are not equal
114  WORD_T neq = ~eq_d; // positions at which da,db and dc are not equal
115 #if 1 // standard HW
116  uint32_t w = hamming_weight(neq & mask_no_msb);
117 #else // assembly instruction for HW (-mpopcnt)
118  uint32_t w = __builtin_popcount(neq & mask_no_msb);
119 #endif // #if 0 // standard HW
120  // p = (double)1.0 / (double)pow(2,w);
121  if (w == 64) { // this should almost never happen so we don't care if it is slow
122  p = pow(2, -64);
123  } else {
124  p = (double) 1.0 / (double)(1ULL << w); // efficient pow(2, w)
125  }
126 #if 0 // DEBUG
127  printf("\nneq = ");
128  print_binary(neq);
129  printf("\n");
130  printf("[%s:%d] w mask neq %d %llX %lld %lld\n", __FILE__, __LINE__,
131  w, (WORD_MAX_T)mask, (WORD_MAX_T)neq, (WORD_MAX_T)(neq & mask_no_msb));
132 #endif // #if 1 // DEBUG
133  }
134  // printf("[%s:%d] Exit %s()\n", __FILE__, __LINE__, __FUNCTION__);
135  return p;
136 }
137 
144 inline double xdp_add_lm(WORD_T da, WORD_T db, WORD_T dc, uint32_t word_size)
145 {
146  double p = 0.0;
147  if(word_size > 1) {
148 #if 0 // BUG?
149  WORD_MAX_T mask = (~0ULL >> (64 - word_size)); // full mask (word_size bits)
150 #endif
151  //#if(word_size <= 32) // mask without the MSB <--- BUG! must be WORD_SIZE
152 #if(WORD_SIZE <= 32) // mask without the MSB
153  // WORD_T mask = ~(0xffffffffUL << WORD_SIZE); // <--- BUG!!
154  WORD_T mask = ~(0xffffffffUL << word_size);
155  // WORD_T mask_no_msb = (mask >> 1);//(0xffffffffUL >> (32 - (word_size - 1)));
156  WORD_T eq_d = eq(da, db, dc);
157  WORD_T eq_d_sl_1 = ((eq_d << 1) | 0x00000001) & mask;
158 #else // #if(word_size <= 32)
159  WORD_T mask = ~(0xffffffffffffffffULL << word_size);
160  // WORD_T mask_no_msb = (mask >> 1);//(0xffffffffffffffffULL >> (64 - (word_size - 1)));
161  WORD_T eq_d = eq(da, db, dc);
162  WORD_T eq_d_sl_1 = ((eq_d << 1) | 0x0000000000000001ULL) & mask;
163 #endif // #if(WORD_SIZE <= 32)
164  // bool b_is_possible = ((eq((da << 1), (db << 1), (dc << 1), word_size) & (da ^ db ^ dc ^ (da << 1))) == 0);
165 
166  // printf("[%s:%d] word_size %d mask %llX mask_no_msb %X\n", __FILE__, __LINE__, word_size, mask, mask_no_msb);
167 
168  bool b_is_possible = ((eq_d_sl_1 & (da ^ db ^ dc ^ (da << 1))) == 0);
169  if(b_is_possible) {
170  // WORD_T neq = ~eq(da, db, dc, word_size); // positions at which da,db and dc are not equal
171  WORD_T neq = ~eq_d; // positions at which da,db and dc are not equal
172 #if 1 // standard HW
173  // uint32_t w = hamming_weight(neq & mask_no_msb);
174  uint32_t w = hamming_weight(neq & (mask >> 1));
175 #else // assembly instruction for HW (-mpopcnt)
176  uint32_t w = __builtin_popcount(neq & mask_no_msb);
177 #endif // #if 0 // standard HW
178  // p = (double)1.0 / (double)pow(2,w);
179  if (w == 64) { // this should almost never happen so we don't care if it is slow
180  p = pow(2, -64);
181  } else {
182  p = (double) 1.0 / (double)(1ULL << w); // efficient pow(2, w)
183  }
184 
185  }
186  } else {
187  if((da ^ db) == dc) {
188  p = 1.0;
189  } else {
190  p = 0.0;
191  }
192  }
193  return p;
194 }
195 
209 inline int xdp_add_lm_log2(WORD_T da, WORD_T db, WORD_T dc)
210 {
211  int p;
212 
213 #if(WORD_SIZE <= 32)
214  const WORD_T mask = (0xffffffffUL >> (32 - (WORD_SIZE - 1)));
215 #else // #if(WORD_SIZE <= 32)
216  const WORD_T mask = (0xffffffffffffffffULL >> (64 - (WORD_SIZE - 1)));
217 #endif // #if(WORD_SIZE <= 32)
218 
219  WORD_T eq_d = eq (da, db, dc);
220 #if (WORD_SIZE <= 32)
221  WORD_T eq_d_sl_1 = ((eq_d << 1) | 0x00000001UL) & MASK;
222 #else
223  WORD_T eq_d_sl_1 = ((eq_d << 1) | 0x0000000000000001ULL) & MASK;
224 #endif
225  bool b_is_possible = ((eq_d_sl_1 & (da ^ db ^ dc ^ (da << 1))) == 0);
226  if (b_is_possible)
227  {
228  WORD_T neq = ~eq_d; // positions at which da,db and dc are not equal
229  // uint32_t w = __builtin_popcount (neq & mask); // <- not work for word_size > 32
230  // uint32_t w = __builtin_popcountll (neq & mask); // <- WORKS for word_size > 32
231  uint32_t w = hamming_weight(neq & mask);
232  if (w == 64)
233  {
234  p = -64;
235  }
236  else
237  {
238  p = -w;
239  }
240  }
241  else
242  {
243  p = LOG0;
244  }
245  return p;
246 }
247 
254 inline int xdp_add_lm_log2(WORD_T da, WORD_T db, WORD_T dc, uint32_t word_size)
255 {
256  int p;
257  if (word_size > 1)
258  {
259 #if (WORD_SIZE <= 32)
260  WORD_T mask = ~(0xffffffffUL << word_size);
261 #else
262  WORD_T mask = ~(0xffffffffffffffffULL << word_size);
263 #endif
264 
265  WORD_T eq_d = eq(da, db, dc);
266  // WORD_T eq_d_sl_1 = ((eq_d << 1) | 0x00000001) & mask;
267 #if (WORD_SIZE <= 32)
268  WORD_T eq_d_sl_1 = ((eq_d << 1) | 0x00000001UL) & mask;
269 #else
270  WORD_T eq_d_sl_1 = ((eq_d << 1) | 0x0000000000000001ULL) & mask;
271 #endif
272  bool b_is_possible = ((eq_d_sl_1 & (da ^ db ^ dc ^ (da << 1))) == 0);
273  if (b_is_possible)
274  {
275  WORD_T neq = ~eq_d & (mask >> 1); // positions at which da,db and dc are not equal
276  // uint32_t w = __builtin_popcount(neq); // <- not work for word_size > 32
277  // uint32_t w = __builtin_popcountll (neq & mask); // <- WORKS for word_size > 32
278  uint32_t w = hamming_weight(neq);
279  if (w == 64)
280  {
281  p = -64;
282  }
283  else
284  {
285  p = -w;
286  }
287  }
288  else
289  {
290  p = LOG0;
291  }
292  }
293  else
294  {
295  if (((da & 1) ^ (db & 1)) == (dc & 1)) // lsb
296  {
297  p = 0;
298  }
299  else
300  {
301  p = LOG0; // prob = 0!
302  }
303  }
304  return p;
305 }
306 
307 
321 static inline WORD_T eq_opt(const WORD_T x, const WORD_T y, const WORD_T z)
322 {
323  WORD_T e = ~((x ^ y) | (x ^ z)) & MASK;
324  return e;
325 }
326 
339 static inline int xdp_add_lm_log2_opt(WORD_T da, WORD_T db, WORD_T dc)
340 {
341  const WORD_T eq_d = eq_opt(da, db, dc);
342  const WORD_T eq_d_sl_1 = ((eq_d << 1) | (WORD_T)1) & MASK;
343  const WORD_T b_is_possible_if_zero = (eq_d_sl_1 & (da ^ db ^ dc ^ (da << 1)));
344  if (b_is_possible_if_zero == 0)
345  {
346  const WORD_T neq = ~eq_d & MASK_NO_MSB; /* positions at which da,db and dc are not equal */
347  const int w = builtin_hamming_weight(neq);
348  return -w;
349  }
350  else
351  {
352  return LOG0;
353  }
354 }
355 
362 static inline int xdp_add_lm_log2_opt(WORD_T da, WORD_T db, WORD_T dc, uint32_t word_size)
363 {
364  int p;
365  if (word_size > 1)
366  {
367 #if (WORD_SIZE <= 32)
368  const WORD_T mask = ~(0xffffffffUL << word_size);
369 #else
370  const WORD_T mask = ~(0xffffffffffffffffULL << word_size);
371 #endif
372  const WORD_T eq_d = eq_opt(da, db, dc);
373  const WORD_T eq_d_sl_1 = ((eq_d << 1) | (WORD_T)1) & mask;
374  const WORD_T b_is_possible_if_zero = (eq_d_sl_1 & (da ^ db ^ dc ^ (da << 1)));
375  if (b_is_possible_if_zero == 0)
376  {
377  const WORD_T neq = ~eq_d & (mask >> 1); /* positions at which da,db and dc are not equal */
378  p = -builtin_hamming_weight(neq);
379  }
380  else
381  {
382  p = LOG0;
383  }
384  }
385  else
386  {
387  if (((da ^ db ^dc) & (WORD_T)1) == 0)
388  {
389  p = 0;
390  }
391  else
392  {
393  p = LOG0;
394  }
395  }
396  return p;
397 }
398 
399 #endif // #ifndef XDP_ADD_H
WORD_T eq(const WORD_T x, const WORD_T y, const WORD_T z)
Definition: xdp-add.cc:628
#define MASK
Definition: common.hh:129
WORD_T aop(WORD_T x, WORD_T n_in)
Definition: xdp-add.cc:436
#define WORD_SIZE
Definition: common.hh:119
double xdp_add_exper(const WORD_T da, const WORD_T db, const WORD_T dc)
Definition: xdp-add.cc:403
WORD_T cap(WORD_T x, WORD_T y)
Definition: xdp-add.cc:569
void xdp_add_free_matrices(gsl_matrix *A[2][2][2])
Definition: xdp-add.cc:58
void xdp_add_normalize_matrices(gsl_matrix *A[2][2][2])
Definition: xdp-add.cc:78
double xdp_add_lm(WORD_T da, WORD_T db, WORD_T dc)
Definition: xdp-add.hh:93
void xdp_add_print_matrices_sage(gsl_matrix *A[2][2][2])
Definition: xdp-add.cc:146
uint32_t hamming_weight(const WORD_T w)
Definition: common.cc:128
bool is_eq(WORD_T x, WORD_T y, WORD_T z)
Definition: xdp-add.cc:610
void xdp_add_alloc_matrices(gsl_matrix *A[2][2][2])
Definition: xdp-add.cc:39
void xdp_add_print_matrices(gsl_matrix *A[2][2][2])
Definition: xdp-add.cc:109
bool xdp_add_is_nonzero(WORD_T da, WORD_T db, WORD_T dc)
Definition: xdp-add.cc:676
double xdp_add(gsl_matrix *A[2][2][2], WORD_T da, WORD_T db, WORD_T dc)
Definition: xdp-add.cc:324
void xdp_add_sf(gsl_matrix *A[2][2][2])
Definition: xdp-add.cc:234
void print_binary(const uint64_t n)
Definition: common.cc:218
int xdp_add_lm_log2(WORD_T da, WORD_T db, WORD_T dc)
Definition: xdp-add.hh:209