Merge pull request #2672 from kitsunehunter/laundry-keys
[RRG-proxmark3.git] / client / deps / hardnested / hardnested_tables.c
blobaade0c0cd061480499daf980cddc0edd2e1475c8
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2015, 2016 by piwi
3 //
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
6 // the license.
7 //-----------------------------------------------------------------------------
8 // Implements a card only attack based on crypto text (encrypted nonces
9 // received during a nested authentication) only. Unlike other card only
10 // attacks this doesn't rely on implementation errors but only on the
11 // inherent weaknesses of the crypto1 cypher. Described in
12 // Carlo Meijer, Roel Verdult, "Ciphertext-only Cryptanalysis on Hardened
13 // Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on
14 // Computer and Communications Security, 2015
15 //-----------------------------------------------------------------------------
17 // This program calculates tables with possible states for a given
18 // bitflip property.
20 //-----------------------------------------------------------------------------
22 // To compile it:
23 // gcc -I../../../common -I../../../include -o hardnested_tables hardnested_tables.c
25 #include <inttypes.h>
26 #include <stdbool.h>
27 #include <stdlib.h>
28 #ifndef __APPLE__
29 #include <malloc.h>
30 #endif
31 #include <string.h>
32 #include <stdio.h>
33 #include <time.h>
34 #include "crapto1/crapto1.h"
35 #include "parity.h"
38 #define NUM_PART_SUMS 9
39 #define BITFLIP_2ND_BYTE 0x0200
41 typedef enum {
42 EVEN_STATE = 0,
43 ODD_STATE = 1
44 } odd_even_t;
47 static uint16_t PartialSumProperty(uint32_t state, odd_even_t odd_even) {
48 uint16_t sum = 0;
49 for (uint16_t j = 0; j < 16; j++) {
50 uint32_t st = state;
51 uint16_t part_sum = 0;
52 if (odd_even == ODD_STATE) {
53 part_sum ^= filter(st);
54 for (uint16_t i = 0; i < 4; i++) {
55 st = (st << 1) | ((j >> (3 - i)) & 0x01) ;
56 part_sum ^= filter(st);
58 part_sum ^= 1; // XOR 1 cancelled out for the other 8 bits
59 } else {
60 for (uint16_t i = 0; i < 4; i++) {
61 st = (st << 1) | ((j >> (3 - i)) & 0x01) ;
62 part_sum ^= filter(st);
65 sum += part_sum;
67 return sum;
71 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
72 // bitarray functions
74 #if defined (_WIN32)
75 #define malloc_bitarray(x) __builtin_assume_aligned(_aligned_malloc((x), __BIGGEST_ALIGNMENT__), __BIGGEST_ALIGNMENT__)
76 #define free_bitarray(x) _aligned_free(x)
77 #elif defined (__APPLE__)
78 static void *malloc_bitarray(size_t x) {
79 char *allocated_memory;
80 if (posix_memalign((void **)&allocated_memory, __BIGGEST_ALIGNMENT__, x)) {
81 return NULL;
82 } else {
83 return __builtin_assume_aligned(allocated_memory, __BIGGEST_ALIGNMENT__);
86 #define free_bitarray(x) free(x)
87 #else
88 //#define malloc_bitarray(x) memalign(__BIGGEST_ALIGNMENT__, (x))
89 #define malloc_bitarray(x) __builtin_assume_aligned(memalign(__BIGGEST_ALIGNMENT__, (x)), __BIGGEST_ALIGNMENT__);
90 #define free_bitarray(x) free(x)
91 #endif
93 static inline void clear_bitarray24(uint32_t *bitarray) {
94 memset(bitarray, 0x00, sizeof(uint32_t) * (1 << 19));
97 static inline uint32_t test_bit24(const uint32_t *bitarray, uint32_t index) {
98 return bitarray[index >> 5] & (0x80000000 >> (index & 0x0000001f));
101 static inline void set_bit24(uint32_t *bitarray, uint32_t index) {
102 bitarray[index >> 5] |= 0x80000000 >> (index & 0x0000001f);
105 static inline uint32_t next_state(const uint32_t *bitset, uint32_t state) {
106 if (++state == 1 << 24) {
107 return 1 << 24;
110 uint32_t index = state >> 5;
111 uint_fast8_t bit = state & 0x1f;
112 uint32_t line = bitset[index] << bit;
113 while (bit <= 0x1f) {
114 if (line & 0x80000000) {
115 return state;
117 state++;
118 bit++;
119 line <<= 1;
122 index++;
123 while (bitset[index] == 0x00000000 && state < 1 << 24) {
124 index++;
125 state += 0x20;
128 if (state >= 1 << 24) {
129 return 1 << 24;
131 #if defined __GNUC__
132 return state + __builtin_clz(bitset[index]);
133 #else
134 bit = 0x00;
135 line = bitset[index];
136 while (bit <= 0x1f) {
137 if (line & 0x80000000) {
138 return state;
140 state++;
141 bit++;
142 line <<= 1;
144 return 1 << 24;
145 #endif
149 static inline uint32_t next_not_state(const uint32_t *bitset, uint32_t state) {
150 if (++state == 1 << 24) return 1 << 24;
151 uint32_t index = state >> 5;
152 uint_fast8_t bit = state & 0x1f;
153 uint32_t line = bitset[index] << bit;
154 while (bit <= 0x1f) {
155 if ((line & 0x80000000) == 0) return state;
156 state++;
157 bit++;
158 line <<= 1;
160 index++;
161 while (bitset[index] == 0xffffffff && state < 1 << 24) {
162 index++;
163 state += 0x20;
165 if (state >= 1 << 24) return 1 << 24;
166 #if defined __GNUC__
167 return state + __builtin_clz(~bitset[index]);
168 #else
169 bit = 0x00;
170 line = bitset[index];
171 while (bit <= 0x1f) {
172 if ((line & 0x80000000) == 0) return state;
173 state++;
174 bit++;
175 line <<= 1;
177 return 1 << 24;
178 #endif
182 static inline uint32_t bitcount(uint32_t a) {
183 #if defined __GNUC__
184 return __builtin_popcountl(a);
185 #else
186 a = a - ((a >> 1) & 0x55555555);
187 a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
188 return (((a + (a >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24;
189 #endif
193 static inline uint32_t count_states(uint32_t *bitset) {
194 uint32_t count = 0;
195 for (uint32_t i = 0; i < (1 << 19); i++) {
196 count += bitcount(bitset[i]);
198 return count;
202 static void write_bitflips_file(odd_even_t odd_even, uint16_t bitflip, int sum_a0, uint32_t *bitset, uint32_t count) {
203 char filename[80];
204 snprintf(filename, sizeof(filename), "bitflip_%d_%03" PRIx16 "_sum%d_states.bin", odd_even, bitflip, sum_a0);
205 FILE *outfile = fopen(filename, "wb");
206 fwrite(&count, 1, sizeof(count), outfile);
207 fwrite(bitset, 1, sizeof(uint32_t) * (1 << 19), outfile);
208 fclose(outfile);
212 uint32_t *restrict part_sum_a0_bitarrays[2][NUM_PART_SUMS];
214 static void init_part_sum_bitarrays(void) {
215 printf("init_part_sum_bitarrays()...");
216 for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) {
217 for (uint16_t part_sum_a0 = 0; part_sum_a0 < NUM_PART_SUMS; part_sum_a0++) {
218 part_sum_a0_bitarrays[odd_even][part_sum_a0] = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19));
219 if (part_sum_a0_bitarrays[odd_even][part_sum_a0] == NULL) {
220 printf("Out of memory error in init_part_suma0_statelists(). Aborting...\n");
221 exit(4);
223 clear_bitarray24(part_sum_a0_bitarrays[odd_even][part_sum_a0]);
226 for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) {
227 //printf("(%d, %" PRIu16 ")...", odd_even, part_sum_a0);
228 for (uint32_t state = 0; state < (1 << 20); state++) {
229 uint16_t part_sum_a0 = PartialSumProperty(state, odd_even) / 2;
230 for (uint16_t low_bits = 0; low_bits < 1 << 4; low_bits++) {
231 set_bit24(part_sum_a0_bitarrays[odd_even][part_sum_a0], state << 4 | low_bits);
235 printf("done.\n");
239 static void free_part_sum_bitarrays(void) {
240 printf("free_part_sum_bitarrays()...");
241 for (int16_t part_sum_a0 = (NUM_PART_SUMS - 1); part_sum_a0 >= 0; part_sum_a0--) {
242 free_bitarray(part_sum_a0_bitarrays[ODD_STATE][part_sum_a0]);
244 for (int16_t part_sum_a0 = (NUM_PART_SUMS - 1); part_sum_a0 >= 0; part_sum_a0--) {
245 free_bitarray(part_sum_a0_bitarrays[EVEN_STATE][part_sum_a0]);
247 printf("done.\n");
250 uint32_t *restrict sum_a0_bitarray[2];
252 void init_sum_bitarray(uint16_t sum_a0) {
253 printf("init_sum_bitarray()...\n");
254 for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) {
255 sum_a0_bitarray[odd_even] = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19));
256 if (sum_a0_bitarray[odd_even] == NULL) {
257 printf("Out of memory error in init_sum_bitarrays(). Aborting...\n");
258 exit(4);
260 clear_bitarray24(sum_a0_bitarray[odd_even]);
262 for (uint8_t p = 0; p < NUM_PART_SUMS; p++) {
263 for (uint8_t q = 0; q < NUM_PART_SUMS; q++) {
264 if (sum_a0 == 2 * p * (16 - 2 * q) + (16 - 2 * p) * 2 * q) {
265 for (uint32_t i = 0; i < (1 << 19); i++) {
266 sum_a0_bitarray[EVEN_STATE][i] |= part_sum_a0_bitarrays[EVEN_STATE][q][i];
267 sum_a0_bitarray[ODD_STATE][i] |= part_sum_a0_bitarrays[ODD_STATE][p][i];
272 for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) {
273 uint32_t count = count_states(sum_a0_bitarray[odd_even]);
274 printf("sum_a0_bitarray[%s] has %u states (%5.2f%%)\n", odd_even == EVEN_STATE ? "even" : "odd ", count, (float)count / (1 << 24) * 100.0);
276 printf("done.\n");
280 static void free_sum_bitarray(void) {
281 printf("free_sum_bitarray()...");
282 free_bitarray(sum_a0_bitarray[ODD_STATE]);
283 free_bitarray(sum_a0_bitarray[EVEN_STATE]);
284 printf("done.\n");
288 static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t const sum_a0) {
289 // #define TEST_RUN
290 #ifdef TEST_RUN
291 #define NUM_TEST_STATES (1<<10)
292 #else
293 #define NUM_TEST_STATES (1<<23)
294 #endif
296 time_t start_time = time(NULL);
297 time_t last_check_time = start_time;
299 uint32_t *restrict test_bitarray[2];
300 uint32_t *restrict test_not_bitarray[2];
302 test_bitarray[EVEN_STATE] = malloc_bitarray(sizeof(uint32_t) * (1 << 19));
303 clear_bitarray24(test_bitarray[EVEN_STATE]);
304 test_bitarray[ODD_STATE] = malloc_bitarray(sizeof(uint32_t) * (1 << 19));
305 clear_bitarray24(test_bitarray[ODD_STATE]);
307 test_not_bitarray[EVEN_STATE] = malloc_bitarray(sizeof(uint32_t) * (1 << 19));
308 clear_bitarray24(test_not_bitarray[EVEN_STATE]);
309 test_not_bitarray[ODD_STATE] = malloc_bitarray(sizeof(uint32_t) * (1 << 19));
310 clear_bitarray24(test_not_bitarray[ODD_STATE]);
312 uint32_t count[2];
313 bool all_odd_states_are_possible_for_notbitflip = false;
315 printf("\n\nStarting search for crypto1 states resulting in bitflip property 0x%03x...\n", bitflip);
316 for (uint32_t even_state = next_state(sum_a0_bitarray[EVEN_STATE], -1); even_state < NUM_TEST_STATES; even_state = next_state(sum_a0_bitarray[EVEN_STATE], even_state)) {
317 bool even_state_is_possible = false;
318 time_t time_now = time(NULL);
319 if (difftime(time_now, last_check_time) > 5 * 60) { // print status every 5 minutes
320 float runtime = difftime(time_now, start_time);
321 float remaining_time = runtime * ((1 << 23) - even_state) / even_state;
322 printf("\n%1.1f hours elapsed, expected completion in %1.1f hours (%1.1f days)", runtime / 3600, remaining_time / 3600, remaining_time / 3600 / 24);
323 last_check_time = time_now;
325 for (uint32_t odd_state = next_state(sum_a0_bitarray[ODD_STATE], -1); odd_state < (1 << 24); odd_state = next_state(test_bitarray[ODD_STATE], odd_state)) {
326 if (even_state_is_possible && test_bit24(test_bitarray[ODD_STATE], odd_state)) continue;
327 // load crypto1 state
328 struct Crypto1State cs;
329 cs.odd = odd_state >> 4;
330 cs.even = even_state >> 4;
332 // track flipping bits in state
333 struct Crypto1DeltaState {
334 uint_fast8_t odd;
335 uint_fast8_t even;
336 } cs_delta;
337 cs_delta.odd = 0;
338 cs_delta.even = 0;
340 uint_fast16_t keystream = 0;
342 // decrypt 9 bits
343 for (int i = 0; i < 9; i++) {
344 uint_fast8_t keystream_bit = filter(cs.odd & 0x000fffff) ^ filter((cs.odd & 0x000fffff) ^ cs_delta.odd);
345 keystream = keystream << 1 | keystream_bit;
346 uint_fast8_t nt_bit = BIT(bitflip, i) ^ keystream_bit;
347 uint_fast8_t LSFR_feedback = BIT(cs_delta.odd, 2) ^ BIT(cs_delta.even, 2) ^ BIT(cs_delta.odd, 3);
349 cs_delta.even = cs_delta.even << 1 | (LSFR_feedback ^ nt_bit);
350 uint_fast8_t tmp = cs_delta.odd;
351 cs_delta.odd = cs_delta.even;
352 cs_delta.even = tmp;
354 cs.even = cs.odd;
355 if (i & 1) {
356 cs.odd = odd_state >> (7 - i) / 2;
357 } else {
358 cs.odd = even_state >> (7 - i) / 2;
362 if (evenparity32(keystream) == evenparity32(bitflip)) {
363 // found valid bitflip state
364 even_state_is_possible = true;
365 set_bit24(test_bitarray[EVEN_STATE], even_state);
366 set_bit24(test_bitarray[EVEN_STATE], 1 << 23 | even_state);
367 set_bit24(test_bitarray[ODD_STATE], odd_state);
368 } else {
369 // found valid !bitflip state
370 set_bit24(test_not_bitarray[EVEN_STATE], even_state);
371 set_bit24(test_not_bitarray[EVEN_STATE], 1 << 23 | even_state);
372 set_bit24(test_not_bitarray[ODD_STATE], odd_state);
375 if (!even_state_is_possible) {
376 all_odd_states_are_possible_for_notbitflip = true;
380 printf("\nAnalysis completed. Checking for effective bitflip properties...\n");
381 for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) {
382 count[odd_even] = count_states(test_bitarray[odd_even]);
383 if (count[odd_even] != 1 << 24) {
384 printf("Writing %u possible %s states for bitflip property %03x (%u (%1.2f%%) states eliminated)\n",
385 count[odd_even],
386 odd_even == EVEN_STATE ? "even" : "odd",
387 bitflip,
388 (1 << 24) - count[odd_even],
389 (float)((1 << 24) - count[odd_even]) / (1 << 24) * 100.0);
390 #ifndef TEST_RUN
391 write_bitflips_file(odd_even, bitflip, sum_a0, test_bitarray[odd_even], count[odd_even]);
392 #endif
393 } else {
394 printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even == EVEN_STATE ? "even" : "odd", bitflip);
397 uint32_t *restrict test_bitarray_2nd = malloc_bitarray(sizeof(uint32_t) * (1 << 19));
398 clear_bitarray24(test_bitarray_2nd);
399 for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) {
400 if (count[odd_even] != 1 << 24) {
401 for (uint32_t state = 0; state < (1 << 24); state += 1 << 4) {
402 uint32_t line = test_bitarray[odd_even][state >> 5];
403 uint16_t half_line = (state & 0x000000010) ? line & 0x0000ffff : line >> 16;
404 if (half_line != 0) {
405 for (uint32_t low_bits = 0; low_bits < (1 << 4); low_bits++) {
406 set_bit24(test_bitarray_2nd, low_bits << 20 | state >> 4);
410 count[odd_even] = count_states(test_bitarray_2nd);
411 if (count[odd_even] != 1 << 24) {
412 printf("Writing %u possible %s states for bitflip property %03x (%u (%1.2f%%) states eliminated)\n",
413 count[odd_even],
414 odd_even == EVEN_STATE ? "even" : "odd",
415 bitflip | BITFLIP_2ND_BYTE,
416 (1 << 24) - count[odd_even],
417 (float)((1 << 24) - count[odd_even]) / (1 << 24) * 100.0);
418 #ifndef TEST_RUN
419 write_bitflips_file(odd_even, bitflip | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd, count[odd_even]);
420 #endif
421 } else {
422 printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even == EVEN_STATE ? "even" : "odd", bitflip | BITFLIP_2ND_BYTE);
424 } else {
425 printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even == EVEN_STATE ? "even" : "odd", bitflip | BITFLIP_2ND_BYTE);
429 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
430 // second run for the remaining "not bitflip" states
431 printf("\n\nStarting search for crypto1 states resulting in bitflip property 0x%03x...", bitflip | 0x100);
432 start_time = time(NULL);
433 last_check_time = start_time;
434 for (uint32_t even_state = next_state(sum_a0_bitarray[EVEN_STATE], -1); even_state < NUM_TEST_STATES; even_state = next_state(sum_a0_bitarray[EVEN_STATE], even_state)) {
435 bool even_state_is_possible = test_bit24(test_not_bitarray[EVEN_STATE], even_state);
436 time_t time_now = time(NULL);
437 if (difftime(time_now, last_check_time) > 5 * 60) { // print status every 5 minutes
438 float runtime = difftime(time_now, start_time);
439 float remaining_time = runtime * ((1 << 23) - even_state) / even_state;
440 printf("\n%1.1f hours elapsed, expected completion in %1.1f hours (%1.1f days)", runtime / 3600, remaining_time / 3600, remaining_time / 3600 / 24);
441 last_check_time = time_now;
443 for (uint32_t odd_state = next_state(sum_a0_bitarray[ODD_STATE], -1); odd_state < (1 << 24); odd_state = next_state(sum_a0_bitarray[ODD_STATE], odd_state)) {
444 if (even_state_is_possible) {
445 if (all_odd_states_are_possible_for_notbitflip) break;
446 if (test_bit24(test_not_bitarray[ODD_STATE], odd_state)) continue;
448 // load crypto1 state
449 struct Crypto1State cs;
450 cs.odd = odd_state >> 4;
451 cs.even = even_state >> 4;
453 // track flipping bits in state
454 struct Crypto1DeltaState {
455 uint_fast8_t odd;
456 uint_fast8_t even;
457 } cs_delta;
458 cs_delta.odd = 0;
459 cs_delta.even = 0;
461 uint_fast16_t keystream = 0;
462 // uint_fast16_t nt = 0;
464 // decrypt 9 bits
465 for (int i = 0; i < 9; i++) {
466 uint_fast8_t keystream_bit = filter(cs.odd & 0x000fffff) ^ filter((cs.odd & 0x000fffff) ^ cs_delta.odd);
467 keystream = keystream << 1 | keystream_bit;
468 uint_fast8_t nt_bit = BIT(bitflip | 0x100, i) ^ keystream_bit;
469 uint_fast8_t LSFR_feedback = BIT(cs_delta.odd, 2) ^ BIT(cs_delta.even, 2) ^ BIT(cs_delta.odd, 3);
471 cs_delta.even = cs_delta.even << 1 | (LSFR_feedback ^ nt_bit);
472 uint_fast8_t tmp = cs_delta.odd;
473 cs_delta.odd = cs_delta.even;
474 cs_delta.even = tmp;
476 cs.even = cs.odd;
477 if (i & 1) {
478 cs.odd = odd_state >> (7 - i) / 2;
479 } else {
480 cs.odd = even_state >> (7 - i) / 2;
484 if (evenparity32(keystream) != evenparity32(bitflip)) {
485 // found valid !bitflip state
486 even_state_is_possible = true;
487 set_bit24(test_not_bitarray[EVEN_STATE], even_state);
488 set_bit24(test_not_bitarray[EVEN_STATE], 1 << 23 | even_state);
489 set_bit24(test_not_bitarray[ODD_STATE], odd_state);
494 printf("\nAnalysis completed. Checking for effective !bitflip properties...\n");
495 for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) {
496 count[odd_even] = count_states(test_not_bitarray[odd_even]);
497 if (count[odd_even] != 1 << 24) {
498 printf("Writing %u possible %s states for bitflip property %03x (%u (%1.2f%%) states eliminated)\n",
499 count[odd_even],
500 odd_even == EVEN_STATE ? "even" : "odd",
501 bitflip | 0x100,
502 (1 << 24) - count[odd_even],
503 (float)((1 << 24) - count[odd_even]) / (1 << 24) * 100.0);
504 #ifndef TEST_RUN
505 write_bitflips_file(odd_even, bitflip | 0x100, sum_a0, test_not_bitarray[odd_even], count[odd_even]);
506 #endif
507 } else {
508 printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even == EVEN_STATE ? "even" : "odd", bitflip | 0x100);
512 clear_bitarray24(test_bitarray_2nd);
513 for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) {
514 if (count[odd_even] != 1 << 24) {
515 for (uint32_t state = 0; state < (1 << 24); state += 1 << 4) {
516 uint32_t line = test_not_bitarray[odd_even][state >> 5];
517 uint16_t half_line = (state & 0x000000010) ? line & 0x0000ffff : line >> 16;
518 if (half_line != 0) {
519 for (uint32_t low_bits = 0; low_bits < (1 << 4); low_bits++) {
520 set_bit24(test_bitarray_2nd, low_bits << 20 | state >> 4);
524 count[odd_even] = count_states(test_bitarray_2nd);
525 if (count[odd_even] != 1 << 24) {
526 printf("Writing %u possible %s states for bitflip property %03x (%u (%1.2f%%) states eliminated)\n",
527 count[odd_even],
528 odd_even == EVEN_STATE ? "even" : "odd",
529 bitflip | 0x100 | BITFLIP_2ND_BYTE,
530 (1 << 24) - count[odd_even],
531 (float)((1 << 24) - count[odd_even]) / (1 << 24) * 100.0);
532 #ifndef TEST_RUN
533 write_bitflips_file(odd_even, bitflip | 0x100 | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd, count[odd_even]);
534 #endif
535 } else {
536 printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even == EVEN_STATE ? "even" : "odd", bitflip | 0x100 | BITFLIP_2ND_BYTE);
538 } else {
539 printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even == EVEN_STATE ? "even" : "odd", bitflip | 0x100 | BITFLIP_2ND_BYTE);
543 free_bitarray(test_bitarray_2nd);
544 free_bitarray(test_not_bitarray[ODD_STATE]);
545 free_bitarray(test_not_bitarray[EVEN_STATE]);
546 free_bitarray(test_bitarray[ODD_STATE]);
547 free_bitarray(test_bitarray[EVEN_STATE]);
548 exit(0);
552 int main(int argc, char *argv[]) {
554 unsigned int bitflip_in;
555 int sum_a0 = 0;
557 printf("Create tables required by hardnested attack.\n");
558 printf("Expect a runtime in the range of days or weeks.\n");
559 printf("Single thread only. If you want to use several threads, start it multiple times :-)\n\n");
561 if (argc != 2 && argc != 3) {
562 printf(" syntax: %s <bitflip property> [<Sum_a0>]\n\n", argv[0]);
563 printf(" example: %s 1f\n", argv[0]);
564 return 1;
567 sscanf(argv[1], "%x", &bitflip_in);
569 if (bitflip_in > 255) {
570 printf("Bitflip property must be less than or equal to 0xff\n\n");
571 return 1;
574 if (argc == 3) {
575 sscanf(argv[2], "%d", &sum_a0);
578 switch (sum_a0) {
579 case 0:
580 case 32:
581 case 56:
582 case 64:
583 case 80:
584 case 96:
585 case 104:
586 case 112:
587 case 120:
588 case 128:
589 case 136:
590 case 144:
591 case 152:
592 case 160:
593 case 176:
594 case 192:
595 case 200:
596 case 224:
597 case 256:
598 break;
599 default:
600 sum_a0 = -1;
603 printf("Calculating for bitflip = %02x, sum_a0 = %d\n", bitflip_in, sum_a0);
605 init_part_sum_bitarrays();
606 init_sum_bitarray(sum_a0);
608 precalculate_bit0_bitflip_bitarrays(bitflip_in, sum_a0);
610 free_sum_bitarray();
611 free_part_sum_bitarrays();
613 return 0;