hf mf fchk - output style
[RRG-proxmark3.git] / tools / hitag2crack / crack5 / ht2crack5.c
blob196f16420621cc07300764d82e8a31aa4a3fc430
1 /* ht2crack5.c
3 * This code is heavily based on the HiTag2 Hell CPU implementation
4 * from https://github.com/factoritbv/hitag2hell by FactorIT B.V.,
5 * with the following changes:
6 * * Main takes a UID and 2 {nR},{aR} pairs as arguments
7 * and searches for states producing the first aR sample,
8 * reconstructs the corresponding key candidates
9 * and tests them against the second nR,aR pair;
10 * * Reuses the Hitag helping functions of the other attacks.
13 #include <stdint.h>
14 #include <stdbool.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <inttypes.h>
20 #include <pthread.h>
21 #include "ht2crackutils.h"
23 const uint8_t bits[9] = {20, 14, 4, 3, 1, 1, 1, 1, 1};
24 #define lfsr_inv(state) (((state)<<1) | (__builtin_parityll((state) & ((0xce0044c101cd>>1)|(1ull<<(47))))))
25 #define i4(x,a,b,c,d) ((uint32_t)((((x)>>(a))&1)<<3)|(((x)>>(b))&1)<<2|(((x)>>(c))&1)<<1|(((x)>>(d))&1))
26 #define f(state) ((0xdd3929b >> ( (((0x3c65 >> i4(state, 2, 3, 5, 6) ) & 1) <<4) \
27 | ((( 0xee5 >> i4(state, 8,12,14,15) ) & 1) <<3) \
28 | ((( 0xee5 >> i4(state,17,21,23,26) ) & 1) <<2) \
29 | ((( 0xee5 >> i4(state,28,29,31,33) ) & 1) <<1) \
30 | (((0x3c65 >> i4(state,34,43,44,46) ) & 1) ))) & 1)
32 #define MAX_BITSLICES 256
33 #define VECTOR_SIZE (MAX_BITSLICES/8)
35 typedef unsigned int __attribute__((aligned(VECTOR_SIZE))) __attribute__((vector_size(VECTOR_SIZE))) bitslice_value_t;
36 typedef union {
37 bitslice_value_t value;
38 uint64_t bytes64[MAX_BITSLICES / 64];
39 uint8_t bytes[MAX_BITSLICES / 8];
40 } bitslice_t;
42 // we never actually set or use the lowest 2 bits the initial state, so we can save 2 bitslices everywhere
43 __thread bitslice_t state[-2 + 32 + 48];
45 bitslice_t keystream[32];
46 bitslice_t bs_zeroes, bs_ones;
48 #define f_a_bs(a,b,c,d) (~(((a|b)&c)^(a|d)^b)) // 6 ops
49 #define f_b_bs(a,b,c,d) (~(((d|c)&(a^b))^(d|a|b))) // 7 ops
50 #define f_c_bs(a,b,c,d,e) (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c)))) // 13 ops
51 #define lfsr_bs(i) (state[-2+i+ 0].value ^ state[-2+i+ 2].value ^ state[-2+i+ 3].value ^ state[-2+i+ 6].value ^ \
52 state[-2+i+ 7].value ^ state[-2+i+ 8].value ^ state[-2+i+16].value ^ state[-2+i+22].value ^ \
53 state[-2+i+23].value ^ state[-2+i+26].value ^ state[-2+i+30].value ^ state[-2+i+41].value ^ \
54 state[-2+i+42].value ^ state[-2+i+43].value ^ state[-2+i+46].value ^ state[-2+i+47].value);
55 #define get_bit(n, word) ((word >> (n)) & 1)
56 #define get_vector_bit(slice, value) get_bit(slice&0x3f, value.bytes64[slice>>6])
58 static uint64_t expand(uint64_t mask, uint64_t value) {
59 uint64_t fill = 0;
60 for (uint64_t bit_index = 0; bit_index < 48; bit_index++) {
61 if (mask & 1) {
62 fill |= (value & 1) << bit_index;
63 value >>= 1;
65 mask >>= 1;
67 return fill;
70 static void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const size_t bit_len, bool reverse) {
71 size_t bit_idx;
72 for (bit_idx = 0; bit_idx < bit_len; bit_idx++) {
73 bool bit;
74 if (reverse) {
75 bit = get_bit(bit_len - 1 - bit_idx, value);
76 } else {
77 bit = get_bit(bit_idx, value);
79 if (bit) {
80 bitsliced_value[bit_idx].value = bs_ones.value;
81 } else {
82 bitsliced_value[bit_idx].value = bs_zeroes.value;
87 static uint64_t unbitslice(const bitslice_t *restrict b, const uint8_t s, const uint8_t n) {
88 uint64_t result = 0;
89 for (uint8_t i = 0; i < n; ++i) {
90 result <<= 1;
91 result |= get_vector_bit(s, b[n - 1 - i]);
93 return result;
97 // determine number of logical CPU cores (use for multithreaded functions)
98 static int num_CPUs(void) {
99 #if defined(_WIN32)
100 #include <sysinfoapi.h>
101 SYSTEM_INFO sysinfo;
102 GetSystemInfo(&sysinfo);
103 return sysinfo.dwNumberOfProcessors;
104 #else
105 #include <unistd.h>
106 int count = sysconf(_SC_NPROCESSORS_ONLN);
107 if (count < 2)
108 count = 2;
109 return count;
110 #endif
114 uint32_t uid, nR1, aR1, nR2, aR2;
116 uint64_t candidates[(1 << 20)];
117 bitslice_t initial_bitslices[48];
118 size_t filter_pos[20] = {4, 7, 9, 13, 16, 18, 22, 24, 27, 30, 32, 35, 45, 47 };
119 size_t thread_count = 8;
120 uint64_t layer_0_found;
121 static void *find_state(void *thread_d);
122 static void try_state(uint64_t s);
124 int main(int argc, char *argv[]) {
126 if (argc < 6) {
127 printf("%s UID {nR1} {aR1} {nR2} {aR2}\n", argv[0]);
128 exit(1);
131 // set constants
132 memset(bs_ones.bytes, 0xff, VECTOR_SIZE);
133 memset(bs_zeroes.bytes, 0x00, VECTOR_SIZE);
135 uint32_t target = 0;
137 thread_count = num_CPUs();
139 if (!strncmp(argv[1], "0x", 2) || !strncmp(argv[1], "0X", 2)) {
140 uid = rev32(hexreversetoulong(argv[1] + 2));
141 } else {
142 uid = rev32(hexreversetoulong(argv[1]));
145 if (!strncmp(argv[2], "0x", 2) || !strncmp(argv[2], "0X", 2)) {
146 nR1 = rev32(hexreversetoulong(argv[2] + 2));
147 } else {
148 nR1 = rev32(hexreversetoulong(argv[2]));
151 aR1 = strtol(argv[3], NULL, 16);
153 if (!strncmp(argv[4], "0x", 2) || !strncmp(argv[4], "0X", 2)) {
154 nR2 = rev32(hexreversetoulong(argv[4] + 2));
155 } else {
156 nR2 = rev32(hexreversetoulong(argv[4]));
159 aR2 = strtol(argv[5], NULL, 16);
161 target = ~aR1;
162 // bitslice inverse target bits
163 bitslice(~target, keystream, 32, true);
165 // bitslice all possible 256 values in the lowest 8 bits
166 memset(initial_bitslices[0].bytes, 0xaa, VECTOR_SIZE);
167 memset(initial_bitslices[1].bytes, 0xcc, VECTOR_SIZE);
168 memset(initial_bitslices[2].bytes, 0xf0, VECTOR_SIZE);
169 size_t interval = 1;
170 for (size_t bit = 3; bit < 8; bit++) {
171 for (size_t byte = 0; byte < VECTOR_SIZE;) {
172 for (size_t length = 0; length < interval; length++) {
173 initial_bitslices[bit].bytes[byte++] = 0x00;
175 for (size_t length = 0; length < interval; length++) {
176 initial_bitslices[bit].bytes[byte++] = 0xff;
179 interval <<= 1;
182 // compute layer 0 output
183 for (size_t i0 = 0; i0 < 1 << 20; i0++) {
184 uint64_t state0 = expand(0x5806b4a2d16c, i0);
186 if (f(state0) == target >> 31) {
187 candidates[layer_0_found++] = state0;
191 // start threads and wait on them
192 pthread_t thread_handles[thread_count];
193 for (size_t thread = 0; thread < thread_count; thread++) {
194 pthread_create(&thread_handles[thread], NULL, find_state, (void *) thread);
196 for (size_t thread = 0; thread < thread_count; thread++) {
197 pthread_join(thread_handles[thread], NULL);
200 printf("Key not found\n");
201 exit(1);
204 static void *find_state(void *thread_d) {
205 uint64_t thread = (uint64_t)thread_d;
207 for (uint64_t index = thread; index < layer_0_found; index += thread_count) {
209 if (((index / thread_count) & 0xFF) == 0)
210 printf("Thread %" PRIu64 " slice %" PRIu64 "/%" PRIu64 "\n", thread, index / thread_count / 256 + 1, layer_0_found / thread_count / 256);
212 uint64_t state0 = candidates[index];
213 bitslice(state0 >> 2, &state[0], 46, false);
215 for (size_t bit = 0; bit < 8; bit++) {
216 state[-2 + filter_pos[bit]] = initial_bitslices[bit];
219 for (uint16_t i1 = 0; i1 < (1 << (bits[1] + 1) >> 8); i1++) {
220 state[-2 + 27].value = ((bool)(i1 & 0x1)) ? bs_ones.value : bs_zeroes.value;
221 state[-2 + 30].value = ((bool)(i1 & 0x2)) ? bs_ones.value : bs_zeroes.value;
222 state[-2 + 32].value = ((bool)(i1 & 0x4)) ? bs_ones.value : bs_zeroes.value;
223 state[-2 + 35].value = ((bool)(i1 & 0x8)) ? bs_ones.value : bs_zeroes.value;
224 state[-2 + 45].value = ((bool)(i1 & 0x10)) ? bs_ones.value : bs_zeroes.value;
225 state[-2 + 47].value = ((bool)(i1 & 0x20)) ? bs_ones.value : bs_zeroes.value;
226 state[-2 + 48].value = ((bool)(i1 & 0x40)) ? bs_ones.value : bs_zeroes.value; // guess lfsr output 0
227 // 0xfc07fef3f9fe
228 const bitslice_value_t filter1_0 = f_a_bs(state[-2 + 3].value, state[-2 + 4].value, state[-2 + 6].value, state[-2 + 7].value);
229 const bitslice_value_t filter1_1 = f_b_bs(state[-2 + 9].value, state[-2 + 13].value, state[-2 + 15].value, state[-2 + 16].value);
230 const bitslice_value_t filter1_2 = f_b_bs(state[-2 + 18].value, state[-2 + 22].value, state[-2 + 24].value, state[-2 + 27].value);
231 const bitslice_value_t filter1_3 = f_b_bs(state[-2 + 29].value, state[-2 + 30].value, state[-2 + 32].value, state[-2 + 34].value);
232 const bitslice_value_t filter1_4 = f_a_bs(state[-2 + 35].value, state[-2 + 44].value, state[-2 + 45].value, state[-2 + 47].value);
233 const bitslice_value_t filter1 = f_c_bs(filter1_0, filter1_1, filter1_2, filter1_3, filter1_4);
234 bitslice_t results1;
235 results1.value = filter1 ^ keystream[1].value;
237 if (results1.bytes64[0] == 0
238 && results1.bytes64[1] == 0
239 && results1.bytes64[2] == 0
240 && results1.bytes64[3] == 0
242 continue;
244 const bitslice_value_t filter2_0 = f_a_bs(state[-2 + 4].value, state[-2 + 5].value, state[-2 + 7].value, state[-2 + 8].value);
245 const bitslice_value_t filter2_3 = f_b_bs(state[-2 + 30].value, state[-2 + 31].value, state[-2 + 33].value, state[-2 + 35].value);
246 const bitslice_value_t filter3_0 = f_a_bs(state[-2 + 5].value, state[-2 + 6].value, state[-2 + 8].value, state[-2 + 9].value);
247 const bitslice_value_t filter5_2 = f_b_bs(state[-2 + 22].value, state[-2 + 26].value, state[-2 + 28].value, state[-2 + 31].value);
248 const bitslice_value_t filter6_2 = f_b_bs(state[-2 + 23].value, state[-2 + 27].value, state[-2 + 29].value, state[-2 + 32].value);
249 const bitslice_value_t filter7_2 = f_b_bs(state[-2 + 24].value, state[-2 + 28].value, state[-2 + 30].value, state[-2 + 33].value);
250 const bitslice_value_t filter9_1 = f_b_bs(state[-2 + 17].value, state[-2 + 21].value, state[-2 + 23].value, state[-2 + 24].value);
251 const bitslice_value_t filter9_2 = f_b_bs(state[-2 + 26].value, state[-2 + 30].value, state[-2 + 32].value, state[-2 + 35].value);
252 const bitslice_value_t filter10_0 = f_a_bs(state[-2 + 12].value, state[-2 + 13].value, state[-2 + 15].value, state[-2 + 16].value);
253 const bitslice_value_t filter11_0 = f_a_bs(state[-2 + 13].value, state[-2 + 14].value, state[-2 + 16].value, state[-2 + 17].value);
254 const bitslice_value_t filter12_0 = f_a_bs(state[-2 + 14].value, state[-2 + 15].value, state[-2 + 17].value, state[-2 + 18].value);
256 for (uint16_t i2 = 0; i2 < (1 << (bits[2] + 1)); i2++) {
257 state[-2 + 10].value = ((bool)(i2 & 0x1)) ? bs_ones.value : bs_zeroes.value;
258 state[-2 + 19].value = ((bool)(i2 & 0x2)) ? bs_ones.value : bs_zeroes.value;
259 state[-2 + 25].value = ((bool)(i2 & 0x4)) ? bs_ones.value : bs_zeroes.value;
260 state[-2 + 36].value = ((bool)(i2 & 0x8)) ? bs_ones.value : bs_zeroes.value;
261 state[-2 + 49].value = ((bool)(i2 & 0x10)) ? bs_ones.value : bs_zeroes.value; // guess lfsr output 1
262 // 0xfe07fffbfdff
263 const bitslice_value_t filter2_1 = f_b_bs(state[-2 + 10].value, state[-2 + 14].value, state[-2 + 16].value, state[-2 + 17].value);
264 const bitslice_value_t filter2_2 = f_b_bs(state[-2 + 19].value, state[-2 + 23].value, state[-2 + 25].value, state[-2 + 28].value);
265 const bitslice_value_t filter2_4 = f_a_bs(state[-2 + 36].value, state[-2 + 45].value, state[-2 + 46].value, state[-2 + 48].value);
266 const bitslice_value_t filter2 = f_c_bs(filter2_0, filter2_1, filter2_2, filter2_3, filter2_4);
267 bitslice_t results2;
268 results2.value = results1.value & (filter2 ^ keystream[2].value);
270 if (results2.bytes64[0] == 0
271 && results2.bytes64[1] == 0
272 && results2.bytes64[2] == 0
273 && results2.bytes64[3] == 0
275 continue;
277 state[-2 + 50].value = lfsr_bs(2);
278 const bitslice_value_t filter3_3 = f_b_bs(state[-2 + 31].value, state[-2 + 32].value, state[-2 + 34].value, state[-2 + 36].value);
279 const bitslice_value_t filter4_0 = f_a_bs(state[-2 + 6].value, state[-2 + 7].value, state[-2 + 9].value, state[-2 + 10].value);
280 const bitslice_value_t filter4_1 = f_b_bs(state[-2 + 12].value, state[-2 + 16].value, state[-2 + 18].value, state[-2 + 19].value);
281 const bitslice_value_t filter4_2 = f_b_bs(state[-2 + 21].value, state[-2 + 25].value, state[-2 + 27].value, state[-2 + 30].value);
282 const bitslice_value_t filter7_0 = f_a_bs(state[-2 + 9].value, state[-2 + 10].value, state[-2 + 12].value, state[-2 + 13].value);
283 const bitslice_value_t filter7_1 = f_b_bs(state[-2 + 15].value, state[-2 + 19].value, state[-2 + 21].value, state[-2 + 22].value);
284 const bitslice_value_t filter8_2 = f_b_bs(state[-2 + 25].value, state[-2 + 29].value, state[-2 + 31].value, state[-2 + 34].value);
285 const bitslice_value_t filter10_1 = f_b_bs(state[-2 + 18].value, state[-2 + 22].value, state[-2 + 24].value, state[-2 + 25].value);
286 const bitslice_value_t filter10_2 = f_b_bs(state[-2 + 27].value, state[-2 + 31].value, state[-2 + 33].value, state[-2 + 36].value);
287 const bitslice_value_t filter11_1 = f_b_bs(state[-2 + 19].value, state[-2 + 23].value, state[-2 + 25].value, state[-2 + 26].value);
289 for (uint8_t i3 = 0; i3 < (1 << bits[3]); i3++) {
290 state[-2 + 11].value = ((bool)(i3 & 0x1)) ? bs_ones.value : bs_zeroes.value;
291 state[-2 + 20].value = ((bool)(i3 & 0x2)) ? bs_ones.value : bs_zeroes.value;
292 state[-2 + 37].value = ((bool)(i3 & 0x4)) ? bs_ones.value : bs_zeroes.value;
293 // 0xff07ffffffff
294 const bitslice_value_t filter3_1 = f_b_bs(state[-2 + 11].value, state[-2 + 15].value, state[-2 + 17].value, state[-2 + 18].value);
295 const bitslice_value_t filter3_2 = f_b_bs(state[-2 + 20].value, state[-2 + 24].value, state[-2 + 26].value, state[-2 + 29].value);
296 const bitslice_value_t filter3_4 = f_a_bs(state[-2 + 37].value, state[-2 + 46].value, state[-2 + 47].value, state[-2 + 49].value);
297 const bitslice_value_t filter3 = f_c_bs(filter3_0, filter3_1, filter3_2, filter3_3, filter3_4);
298 bitslice_t results3;
299 results3.value = results2.value & (filter3 ^ keystream[3].value);
301 if (results3.bytes64[0] == 0
302 && results3.bytes64[1] == 0
303 && results3.bytes64[2] == 0
304 && results3.bytes64[3] == 0
306 continue;
309 state[-2 + 51].value = lfsr_bs(3);
310 state[-2 + 52].value = lfsr_bs(4);
311 state[-2 + 53].value = lfsr_bs(5);
312 state[-2 + 54].value = lfsr_bs(6);
313 state[-2 + 55].value = lfsr_bs(7);
314 const bitslice_value_t filter4_3 = f_b_bs(state[-2 + 32].value, state[-2 + 33].value, state[-2 + 35].value, state[-2 + 37].value);
315 const bitslice_value_t filter5_0 = f_a_bs(state[-2 + 7].value, state[-2 + 8].value, state[-2 + 10].value, state[-2 + 11].value);
316 const bitslice_value_t filter5_1 = f_b_bs(state[-2 + 13].value, state[-2 + 17].value, state[-2 + 19].value, state[-2 + 20].value);
317 const bitslice_value_t filter6_0 = f_a_bs(state[-2 + 8].value, state[-2 + 9].value, state[-2 + 11].value, state[-2 + 12].value);
318 const bitslice_value_t filter6_1 = f_b_bs(state[-2 + 14].value, state[-2 + 18].value, state[-2 + 20].value, state[-2 + 21].value);
319 const bitslice_value_t filter8_0 = f_a_bs(state[-2 + 10].value, state[-2 + 11].value, state[-2 + 13].value, state[-2 + 14].value);
320 const bitslice_value_t filter8_1 = f_b_bs(state[-2 + 16].value, state[-2 + 20].value, state[-2 + 22].value, state[-2 + 23].value);
321 const bitslice_value_t filter9_0 = f_a_bs(state[-2 + 11].value, state[-2 + 12].value, state[-2 + 14].value, state[-2 + 15].value);
322 const bitslice_value_t filter9_4 = f_a_bs(state[-2 + 43].value, state[-2 + 52].value, state[-2 + 53].value, state[-2 + 55].value);
323 const bitslice_value_t filter11_2 = f_b_bs(state[-2 + 28].value, state[-2 + 32].value, state[-2 + 34].value, state[-2 + 37].value);
324 const bitslice_value_t filter12_1 = f_b_bs(state[-2 + 20].value, state[-2 + 24].value, state[-2 + 26].value, state[-2 + 27].value);
326 for (uint8_t i4 = 0; i4 < (1 << bits[4]); i4++) {
327 state[-2 + 38].value = ((bool)(i4 & 0x1)) ? bs_ones.value : bs_zeroes.value;
328 // 0xff87ffffffff
329 const bitslice_value_t filter4_4 = f_a_bs(state[-2 + 38].value, state[-2 + 47].value, state[-2 + 48].value, state[-2 + 50].value);
330 const bitslice_value_t filter4 = f_c_bs(filter4_0, filter4_1, filter4_2, filter4_3, filter4_4);
331 bitslice_t results4;
332 results4.value = results3.value & (filter4 ^ keystream[4].value);
333 if (results4.bytes64[0] == 0
334 && results4.bytes64[1] == 0
335 && results4.bytes64[2] == 0
336 && results4.bytes64[3] == 0
338 continue;
341 state[-2 + 56].value = lfsr_bs(8);
342 const bitslice_value_t filter5_3 = f_b_bs(state[-2 + 33].value, state[-2 + 34].value, state[-2 + 36].value, state[-2 + 38].value);
343 const bitslice_value_t filter10_4 = f_a_bs(state[-2 + 44].value, state[-2 + 53].value, state[-2 + 54].value, state[-2 + 56].value);
344 const bitslice_value_t filter12_2 = f_b_bs(state[-2 + 29].value, state[-2 + 33].value, state[-2 + 35].value, state[-2 + 38].value);
346 for (uint8_t i5 = 0; i5 < (1 << bits[5]); i5++) {
347 state[-2 + 39].value = ((bool)(i5 & 0x1)) ? bs_ones.value : bs_zeroes.value;
348 // 0xffc7ffffffff
349 const bitslice_value_t filter5_4 = f_a_bs(state[-2 + 39].value, state[-2 + 48].value, state[-2 + 49].value, state[-2 + 51].value);
350 const bitslice_value_t filter5 = f_c_bs(filter5_0, filter5_1, filter5_2, filter5_3, filter5_4);
351 bitslice_t results5;
352 results5.value = results4.value & (filter5 ^ keystream[5].value);
354 if (results5.bytes64[0] == 0
355 && results5.bytes64[1] == 0
356 && results5.bytes64[2] == 0
357 && results5.bytes64[3] == 0
359 continue;
362 state[-2 + 57].value = lfsr_bs(9);
363 const bitslice_value_t filter6_3 = f_b_bs(state[-2 + 34].value, state[-2 + 35].value, state[-2 + 37].value, state[-2 + 39].value);
364 const bitslice_value_t filter11_4 = f_a_bs(state[-2 + 45].value, state[-2 + 54].value, state[-2 + 55].value, state[-2 + 57].value);
365 for (uint8_t i6 = 0; i6 < (1 << bits[6]); i6++) {
366 state[-2 + 40].value = ((bool)(i6 & 0x1)) ? bs_ones.value : bs_zeroes.value;
367 // 0xffe7ffffffff
368 const bitslice_value_t filter6_4 = f_a_bs(state[-2 + 40].value, state[-2 + 49].value, state[-2 + 50].value, state[-2 + 52].value);
369 const bitslice_value_t filter6 = f_c_bs(filter6_0, filter6_1, filter6_2, filter6_3, filter6_4);
370 bitslice_t results6;
371 results6.value = results5.value & (filter6 ^ keystream[6].value);
373 if (results6.bytes64[0] == 0
374 && results6.bytes64[1] == 0
375 && results6.bytes64[2] == 0
376 && results6.bytes64[3] == 0
378 continue;
381 state[-2 + 58].value = lfsr_bs(10);
382 const bitslice_value_t filter7_3 = f_b_bs(state[-2 + 35].value, state[-2 + 36].value, state[-2 + 38].value, state[-2 + 40].value);
383 const bitslice_value_t filter12_4 = f_a_bs(state[-2 + 46].value, state[-2 + 55].value, state[-2 + 56].value, state[-2 + 58].value);
384 for (uint8_t i7 = 0; i7 < (1 << bits[7]); i7++) {
385 state[-2 + 41].value = ((bool)(i7 & 0x1)) ? bs_ones.value : bs_zeroes.value;
386 // 0xfff7ffffffff
387 const bitslice_value_t filter7_4 = f_a_bs(state[-2 + 41].value, state[-2 + 50].value, state[-2 + 51].value, state[-2 + 53].value);
388 const bitslice_value_t filter7 = f_c_bs(filter7_0, filter7_1, filter7_2, filter7_3, filter7_4);
389 bitslice_t results7;
390 results7.value = results6.value & (filter7 ^ keystream[7].value);
391 if (results7.bytes64[0] == 0
392 && results7.bytes64[1] == 0
393 && results7.bytes64[2] == 0
394 && results7.bytes64[3] == 0
396 continue;
399 state[-2 + 59].value = lfsr_bs(11);
400 const bitslice_value_t filter8_3 = f_b_bs(state[-2 + 36].value, state[-2 + 37].value, state[-2 + 39].value, state[-2 + 41].value);
401 const bitslice_value_t filter10_3 = f_b_bs(state[-2 + 38].value, state[-2 + 39].value, state[-2 + 41].value, state[-2 + 43].value);
402 const bitslice_value_t filter12_3 = f_b_bs(state[-2 + 40].value, state[-2 + 41].value, state[-2 + 43].value, state[-2 + 45].value);
403 for (uint8_t i8 = 0; i8 < (1 << bits[8]); i8++) {
404 state[-2 + 42].value = ((bool)(i8 & 0x1)) ? bs_ones.value : bs_zeroes.value;
405 // 0xffffffffffff
406 const bitslice_value_t filter8_4 = f_a_bs(state[-2 + 42].value, state[-2 + 51].value, state[-2 + 52].value, state[-2 + 54].value);
407 const bitslice_value_t filter8 = f_c_bs(filter8_0, filter8_1, filter8_2, filter8_3, filter8_4);
408 bitslice_t results8;
409 results8.value = results7.value & (filter8 ^ keystream[8].value);
411 if (results8.bytes64[0] == 0
412 && results8.bytes64[1] == 0
413 && results8.bytes64[2] == 0
414 && results8.bytes64[3] == 0
416 continue;
419 const bitslice_value_t filter9_3 = f_b_bs(state[-2 + 37].value, state[-2 + 38].value, state[-2 + 40].value, state[-2 + 42].value);
420 const bitslice_value_t filter9 = f_c_bs(filter9_0, filter9_1, filter9_2, filter9_3, filter9_4);
421 results8.value &= (filter9 ^ keystream[9].value);
423 if (results8.bytes64[0] == 0
424 && results8.bytes64[1] == 0
425 && results8.bytes64[2] == 0
426 && results8.bytes64[3] == 0
428 continue;
431 const bitslice_value_t filter10 = f_c_bs(filter10_0, filter10_1, filter10_2, filter10_3, filter10_4);
432 results8.value &= (filter10 ^ keystream[10].value);
434 if (results8.bytes64[0] == 0
435 && results8.bytes64[1] == 0
436 && results8.bytes64[2] == 0
437 && results8.bytes64[3] == 0
439 continue;
442 const bitslice_value_t filter11_3 = f_b_bs(state[-2 + 39].value, state[-2 + 40].value, state[-2 + 42].value, state[-2 + 44].value);
443 const bitslice_value_t filter11 = f_c_bs(filter11_0, filter11_1, filter11_2, filter11_3, filter11_4);
444 results8.value &= (filter11 ^ keystream[11].value);
446 if (results8.bytes64[0] == 0
447 && results8.bytes64[1] == 0
448 && results8.bytes64[2] == 0
449 && results8.bytes64[3] == 0
451 continue;
454 const bitslice_value_t filter12 = f_c_bs(filter12_0, filter12_1, filter12_2, filter12_3, filter12_4);
455 results8.value &= (filter12 ^ keystream[12].value);
457 if (results8.bytes64[0] == 0
458 && results8.bytes64[1] == 0
459 && results8.bytes64[2] == 0
460 && results8.bytes64[3] == 0
462 continue;
465 const bitslice_value_t filter13_0 = f_a_bs(state[-2 + 15].value, state[-2 + 16].value, state[-2 + 18].value, state[-2 + 19].value);
466 const bitslice_value_t filter13_1 = f_b_bs(state[-2 + 21].value, state[-2 + 25].value, state[-2 + 27].value, state[-2 + 28].value);
467 const bitslice_value_t filter13_2 = f_b_bs(state[-2 + 30].value, state[-2 + 34].value, state[-2 + 36].value, state[-2 + 39].value);
468 const bitslice_value_t filter13_3 = f_b_bs(state[-2 + 41].value, state[-2 + 42].value, state[-2 + 44].value, state[-2 + 46].value);
469 const bitslice_value_t filter13_4 = f_a_bs(state[-2 + 47].value, state[-2 + 56].value, state[-2 + 57].value, state[-2 + 59].value);
470 const bitslice_value_t filter13 = f_c_bs(filter13_0, filter13_1, filter13_2, filter13_3, filter13_4);
471 results8.value &= (filter13 ^ keystream[13].value);
473 if (results8.bytes64[0] == 0
474 && results8.bytes64[1] == 0
475 && results8.bytes64[2] == 0
476 && results8.bytes64[3] == 0
478 continue;
481 state[-2 + 60].value = lfsr_bs(12);
482 const bitslice_value_t filter14_0 = f_a_bs(state[-2 + 16].value, state[-2 + 17].value, state[-2 + 19].value, state[-2 + 20].value);
483 const bitslice_value_t filter14_1 = f_b_bs(state[-2 + 22].value, state[-2 + 26].value, state[-2 + 28].value, state[-2 + 29].value);
484 const bitslice_value_t filter14_2 = f_b_bs(state[-2 + 31].value, state[-2 + 35].value, state[-2 + 37].value, state[-2 + 40].value);
485 const bitslice_value_t filter14_3 = f_b_bs(state[-2 + 42].value, state[-2 + 43].value, state[-2 + 45].value, state[-2 + 47].value);
486 const bitslice_value_t filter14_4 = f_a_bs(state[-2 + 48].value, state[-2 + 57].value, state[-2 + 58].value, state[-2 + 60].value);
487 const bitslice_value_t filter14 = f_c_bs(filter14_0, filter14_1, filter14_2, filter14_3, filter14_4);
488 results8.value &= (filter14 ^ keystream[14].value);
490 if (results8.bytes64[0] == 0
491 && results8.bytes64[1] == 0
492 && results8.bytes64[2] == 0
493 && results8.bytes64[3] == 0
495 continue;
498 state[-2 + 61].value = lfsr_bs(13);
499 const bitslice_value_t filter15_0 = f_a_bs(state[-2 + 17].value, state[-2 + 18].value, state[-2 + 20].value, state[-2 + 21].value);
500 const bitslice_value_t filter15_1 = f_b_bs(state[-2 + 23].value, state[-2 + 27].value, state[-2 + 29].value, state[-2 + 30].value);
501 const bitslice_value_t filter15_2 = f_b_bs(state[-2 + 32].value, state[-2 + 36].value, state[-2 + 38].value, state[-2 + 41].value);
502 const bitslice_value_t filter15_3 = f_b_bs(state[-2 + 43].value, state[-2 + 44].value, state[-2 + 46].value, state[-2 + 48].value);
503 const bitslice_value_t filter15_4 = f_a_bs(state[-2 + 49].value, state[-2 + 58].value, state[-2 + 59].value, state[-2 + 61].value);
504 const bitslice_value_t filter15 = f_c_bs(filter15_0, filter15_1, filter15_2, filter15_3, filter15_4);
505 results8.value &= (filter15 ^ keystream[15].value);
507 if (results8.bytes64[0] == 0
508 && results8.bytes64[1] == 0
509 && results8.bytes64[2] == 0
510 && results8.bytes64[3] == 0
512 continue;
515 state[-2 + 62].value = lfsr_bs(14);
516 const bitslice_value_t filter16_0 = f_a_bs(state[-2 + 18].value, state[-2 + 19].value, state[-2 + 21].value, state[-2 + 22].value);
517 const bitslice_value_t filter16_1 = f_b_bs(state[-2 + 24].value, state[-2 + 28].value, state[-2 + 30].value, state[-2 + 31].value);
518 const bitslice_value_t filter16_2 = f_b_bs(state[-2 + 33].value, state[-2 + 37].value, state[-2 + 39].value, state[-2 + 42].value);
519 const bitslice_value_t filter16_3 = f_b_bs(state[-2 + 44].value, state[-2 + 45].value, state[-2 + 47].value, state[-2 + 49].value);
520 const bitslice_value_t filter16_4 = f_a_bs(state[-2 + 50].value, state[-2 + 59].value, state[-2 + 60].value, state[-2 + 62].value);
521 const bitslice_value_t filter16 = f_c_bs(filter16_0, filter16_1, filter16_2, filter16_3, filter16_4);
522 results8.value &= (filter16 ^ keystream[16].value);
524 if (results8.bytes64[0] == 0
525 && results8.bytes64[1] == 0
526 && results8.bytes64[2] == 0
527 && results8.bytes64[3] == 0
529 continue;
532 state[-2 + 63].value = lfsr_bs(15);
533 const bitslice_value_t filter17_0 = f_a_bs(state[-2 + 19].value, state[-2 + 20].value, state[-2 + 22].value, state[-2 + 23].value);
534 const bitslice_value_t filter17_1 = f_b_bs(state[-2 + 25].value, state[-2 + 29].value, state[-2 + 31].value, state[-2 + 32].value);
535 const bitslice_value_t filter17_2 = f_b_bs(state[-2 + 34].value, state[-2 + 38].value, state[-2 + 40].value, state[-2 + 43].value);
536 const bitslice_value_t filter17_3 = f_b_bs(state[-2 + 45].value, state[-2 + 46].value, state[-2 + 48].value, state[-2 + 50].value);
537 const bitslice_value_t filter17_4 = f_a_bs(state[-2 + 51].value, state[-2 + 60].value, state[-2 + 61].value, state[-2 + 63].value);
538 const bitslice_value_t filter17 = f_c_bs(filter17_0, filter17_1, filter17_2, filter17_3, filter17_4);
539 results8.value &= (filter17 ^ keystream[17].value);
541 if (results8.bytes64[0] == 0
542 && results8.bytes64[1] == 0
543 && results8.bytes64[2] == 0
544 && results8.bytes64[3] == 0
546 continue;
549 state[-2 + 64].value = lfsr_bs(16);
550 const bitslice_value_t filter18_0 = f_a_bs(state[-2 + 20].value, state[-2 + 21].value, state[-2 + 23].value, state[-2 + 24].value);
551 const bitslice_value_t filter18_1 = f_b_bs(state[-2 + 26].value, state[-2 + 30].value, state[-2 + 32].value, state[-2 + 33].value);
552 const bitslice_value_t filter18_2 = f_b_bs(state[-2 + 35].value, state[-2 + 39].value, state[-2 + 41].value, state[-2 + 44].value);
553 const bitslice_value_t filter18_3 = f_b_bs(state[-2 + 46].value, state[-2 + 47].value, state[-2 + 49].value, state[-2 + 51].value);
554 const bitslice_value_t filter18_4 = f_a_bs(state[-2 + 52].value, state[-2 + 61].value, state[-2 + 62].value, state[-2 + 64].value);
555 const bitslice_value_t filter18 = f_c_bs(filter18_0, filter18_1, filter18_2, filter18_3, filter18_4);
556 results8.value &= (filter18 ^ keystream[18].value);
558 if (results8.bytes64[0] == 0
559 && results8.bytes64[1] == 0
560 && results8.bytes64[2] == 0
561 && results8.bytes64[3] == 0
563 continue;
566 state[-2 + 65].value = lfsr_bs(17);
567 const bitslice_value_t filter19_0 = f_a_bs(state[-2 + 21].value, state[-2 + 22].value, state[-2 + 24].value, state[-2 + 25].value);
568 const bitslice_value_t filter19_1 = f_b_bs(state[-2 + 27].value, state[-2 + 31].value, state[-2 + 33].value, state[-2 + 34].value);
569 const bitslice_value_t filter19_2 = f_b_bs(state[-2 + 36].value, state[-2 + 40].value, state[-2 + 42].value, state[-2 + 45].value);
570 const bitslice_value_t filter19_3 = f_b_bs(state[-2 + 47].value, state[-2 + 48].value, state[-2 + 50].value, state[-2 + 52].value);
571 const bitslice_value_t filter19_4 = f_a_bs(state[-2 + 53].value, state[-2 + 62].value, state[-2 + 63].value, state[-2 + 65].value);
572 const bitslice_value_t filter19 = f_c_bs(filter19_0, filter19_1, filter19_2, filter19_3, filter19_4);
573 results8.value &= (filter19 ^ keystream[19].value);
575 if (results8.bytes64[0] == 0
576 && results8.bytes64[1] == 0
577 && results8.bytes64[2] == 0
578 && results8.bytes64[3] == 0
580 continue;
583 state[-2 + 66].value = lfsr_bs(18);
584 const bitslice_value_t filter20_0 = f_a_bs(state[-2 + 22].value, state[-2 + 23].value, state[-2 + 25].value, state[-2 + 26].value);
585 const bitslice_value_t filter20_1 = f_b_bs(state[-2 + 28].value, state[-2 + 32].value, state[-2 + 34].value, state[-2 + 35].value);
586 const bitslice_value_t filter20_2 = f_b_bs(state[-2 + 37].value, state[-2 + 41].value, state[-2 + 43].value, state[-2 + 46].value);
587 const bitslice_value_t filter20_3 = f_b_bs(state[-2 + 48].value, state[-2 + 49].value, state[-2 + 51].value, state[-2 + 53].value);
588 const bitslice_value_t filter20_4 = f_a_bs(state[-2 + 54].value, state[-2 + 63].value, state[-2 + 64].value, state[-2 + 66].value);
589 const bitslice_value_t filter20 = f_c_bs(filter20_0, filter20_1, filter20_2, filter20_3, filter20_4);
590 results8.value &= (filter20 ^ keystream[20].value);
592 if (results8.bytes64[0] == 0
593 && results8.bytes64[1] == 0
594 && results8.bytes64[2] == 0
595 && results8.bytes64[3] == 0
597 continue;
600 state[-2 + 67].value = lfsr_bs(19);
601 const bitslice_value_t filter21_0 = f_a_bs(state[-2 + 23].value, state[-2 + 24].value, state[-2 + 26].value, state[-2 + 27].value);
602 const bitslice_value_t filter21_1 = f_b_bs(state[-2 + 29].value, state[-2 + 33].value, state[-2 + 35].value, state[-2 + 36].value);
603 const bitslice_value_t filter21_2 = f_b_bs(state[-2 + 38].value, state[-2 + 42].value, state[-2 + 44].value, state[-2 + 47].value);
604 const bitslice_value_t filter21_3 = f_b_bs(state[-2 + 49].value, state[-2 + 50].value, state[-2 + 52].value, state[-2 + 54].value);
605 const bitslice_value_t filter21_4 = f_a_bs(state[-2 + 55].value, state[-2 + 64].value, state[-2 + 65].value, state[-2 + 67].value);
606 const bitslice_value_t filter21 = f_c_bs(filter21_0, filter21_1, filter21_2, filter21_3, filter21_4);
607 results8.value &= (filter21 ^ keystream[21].value);
609 if (results8.bytes64[0] == 0
610 && results8.bytes64[1] == 0
611 && results8.bytes64[2] == 0
612 && results8.bytes64[3] == 0
614 continue;
617 state[-2 + 68].value = lfsr_bs(20);
618 const bitslice_value_t filter22_0 = f_a_bs(state[-2 + 24].value, state[-2 + 25].value, state[-2 + 27].value, state[-2 + 28].value);
619 const bitslice_value_t filter22_1 = f_b_bs(state[-2 + 30].value, state[-2 + 34].value, state[-2 + 36].value, state[-2 + 37].value);
620 const bitslice_value_t filter22_2 = f_b_bs(state[-2 + 39].value, state[-2 + 43].value, state[-2 + 45].value, state[-2 + 48].value);
621 const bitslice_value_t filter22_3 = f_b_bs(state[-2 + 50].value, state[-2 + 51].value, state[-2 + 53].value, state[-2 + 55].value);
622 const bitslice_value_t filter22_4 = f_a_bs(state[-2 + 56].value, state[-2 + 65].value, state[-2 + 66].value, state[-2 + 68].value);
623 const bitslice_value_t filter22 = f_c_bs(filter22_0, filter22_1, filter22_2, filter22_3, filter22_4);
624 results8.value &= (filter22 ^ keystream[22].value);
626 if (results8.bytes64[0] == 0
627 && results8.bytes64[1] == 0
628 && results8.bytes64[2] == 0
629 && results8.bytes64[3] == 0
631 continue;
634 state[-2 + 69].value = lfsr_bs(21);
635 const bitslice_value_t filter23_0 = f_a_bs(state[-2 + 25].value, state[-2 + 26].value, state[-2 + 28].value, state[-2 + 29].value);
636 const bitslice_value_t filter23_1 = f_b_bs(state[-2 + 31].value, state[-2 + 35].value, state[-2 + 37].value, state[-2 + 38].value);
637 const bitslice_value_t filter23_2 = f_b_bs(state[-2 + 40].value, state[-2 + 44].value, state[-2 + 46].value, state[-2 + 49].value);
638 const bitslice_value_t filter23_3 = f_b_bs(state[-2 + 51].value, state[-2 + 52].value, state[-2 + 54].value, state[-2 + 56].value);
639 const bitslice_value_t filter23_4 = f_a_bs(state[-2 + 57].value, state[-2 + 66].value, state[-2 + 67].value, state[-2 + 69].value);
640 const bitslice_value_t filter23 = f_c_bs(filter23_0, filter23_1, filter23_2, filter23_3, filter23_4);
641 results8.value &= (filter23 ^ keystream[23].value);
642 if (results8.bytes64[0] == 0
643 && results8.bytes64[1] == 0
644 && results8.bytes64[2] == 0
645 && results8.bytes64[3] == 0
647 continue;
649 state[-2 + 70].value = lfsr_bs(22);
650 const bitslice_value_t filter24_0 = f_a_bs(state[-2 + 26].value, state[-2 + 27].value, state[-2 + 29].value, state[-2 + 30].value);
651 const bitslice_value_t filter24_1 = f_b_bs(state[-2 + 32].value, state[-2 + 36].value, state[-2 + 38].value, state[-2 + 39].value);
652 const bitslice_value_t filter24_2 = f_b_bs(state[-2 + 41].value, state[-2 + 45].value, state[-2 + 47].value, state[-2 + 50].value);
653 const bitslice_value_t filter24_3 = f_b_bs(state[-2 + 52].value, state[-2 + 53].value, state[-2 + 55].value, state[-2 + 57].value);
654 const bitslice_value_t filter24_4 = f_a_bs(state[-2 + 58].value, state[-2 + 67].value, state[-2 + 68].value, state[-2 + 70].value);
655 const bitslice_value_t filter24 = f_c_bs(filter24_0, filter24_1, filter24_2, filter24_3, filter24_4);
656 results8.value &= (filter24 ^ keystream[24].value);
657 if (results8.bytes64[0] == 0
658 && results8.bytes64[1] == 0
659 && results8.bytes64[2] == 0
660 && results8.bytes64[3] == 0
662 continue;
664 state[-2 + 71].value = lfsr_bs(23);
665 const bitslice_value_t filter25_0 = f_a_bs(state[-2 + 27].value, state[-2 + 28].value, state[-2 + 30].value, state[-2 + 31].value);
666 const bitslice_value_t filter25_1 = f_b_bs(state[-2 + 33].value, state[-2 + 37].value, state[-2 + 39].value, state[-2 + 40].value);
667 const bitslice_value_t filter25_2 = f_b_bs(state[-2 + 42].value, state[-2 + 46].value, state[-2 + 48].value, state[-2 + 51].value);
668 const bitslice_value_t filter25_3 = f_b_bs(state[-2 + 53].value, state[-2 + 54].value, state[-2 + 56].value, state[-2 + 58].value);
669 const bitslice_value_t filter25_4 = f_a_bs(state[-2 + 59].value, state[-2 + 68].value, state[-2 + 69].value, state[-2 + 71].value);
670 const bitslice_value_t filter25 = f_c_bs(filter25_0, filter25_1, filter25_2, filter25_3, filter25_4);
671 results8.value &= (filter25 ^ keystream[25].value);
673 if (results8.bytes64[0] == 0
674 && results8.bytes64[1] == 0
675 && results8.bytes64[2] == 0
676 && results8.bytes64[3] == 0
678 continue;
681 state[-2 + 72].value = lfsr_bs(24);
682 const bitslice_value_t filter26_0 = f_a_bs(state[-2 + 28].value, state[-2 + 29].value, state[-2 + 31].value, state[-2 + 32].value);
683 const bitslice_value_t filter26_1 = f_b_bs(state[-2 + 34].value, state[-2 + 38].value, state[-2 + 40].value, state[-2 + 41].value);
684 const bitslice_value_t filter26_2 = f_b_bs(state[-2 + 43].value, state[-2 + 47].value, state[-2 + 49].value, state[-2 + 52].value);
685 const bitslice_value_t filter26_3 = f_b_bs(state[-2 + 54].value, state[-2 + 55].value, state[-2 + 57].value, state[-2 + 59].value);
686 const bitslice_value_t filter26_4 = f_a_bs(state[-2 + 60].value, state[-2 + 69].value, state[-2 + 70].value, state[-2 + 72].value);
687 const bitslice_value_t filter26 = f_c_bs(filter26_0, filter26_1, filter26_2, filter26_3, filter26_4);
688 results8.value &= (filter26 ^ keystream[26].value);
690 if (results8.bytes64[0] == 0
691 && results8.bytes64[1] == 0
692 && results8.bytes64[2] == 0
693 && results8.bytes64[3] == 0
695 continue;
698 state[-2 + 73].value = lfsr_bs(25);
699 const bitslice_value_t filter27_0 = f_a_bs(state[-2 + 29].value, state[-2 + 30].value, state[-2 + 32].value, state[-2 + 33].value);
700 const bitslice_value_t filter27_1 = f_b_bs(state[-2 + 35].value, state[-2 + 39].value, state[-2 + 41].value, state[-2 + 42].value);
701 const bitslice_value_t filter27_2 = f_b_bs(state[-2 + 44].value, state[-2 + 48].value, state[-2 + 50].value, state[-2 + 53].value);
702 const bitslice_value_t filter27_3 = f_b_bs(state[-2 + 55].value, state[-2 + 56].value, state[-2 + 58].value, state[-2 + 60].value);
703 const bitslice_value_t filter27_4 = f_a_bs(state[-2 + 61].value, state[-2 + 70].value, state[-2 + 71].value, state[-2 + 73].value);
704 const bitslice_value_t filter27 = f_c_bs(filter27_0, filter27_1, filter27_2, filter27_3, filter27_4);
705 results8.value &= (filter27 ^ keystream[27].value);
707 if (results8.bytes64[0] == 0
708 && results8.bytes64[1] == 0
709 && results8.bytes64[2] == 0
710 && results8.bytes64[3] == 0
712 continue;
715 state[-2 + 74].value = lfsr_bs(26);
716 const bitslice_value_t filter28_0 = f_a_bs(state[-2 + 30].value, state[-2 + 31].value, state[-2 + 33].value, state[-2 + 34].value);
717 const bitslice_value_t filter28_1 = f_b_bs(state[-2 + 36].value, state[-2 + 40].value, state[-2 + 42].value, state[-2 + 43].value);
718 const bitslice_value_t filter28_2 = f_b_bs(state[-2 + 45].value, state[-2 + 49].value, state[-2 + 51].value, state[-2 + 54].value);
719 const bitslice_value_t filter28_3 = f_b_bs(state[-2 + 56].value, state[-2 + 57].value, state[-2 + 59].value, state[-2 + 61].value);
720 const bitslice_value_t filter28_4 = f_a_bs(state[-2 + 62].value, state[-2 + 71].value, state[-2 + 72].value, state[-2 + 74].value);
721 const bitslice_value_t filter28 = f_c_bs(filter28_0, filter28_1, filter28_2, filter28_3, filter28_4);
722 results8.value &= (filter28 ^ keystream[28].value);
724 if (results8.bytes64[0] == 0
725 && results8.bytes64[1] == 0
726 && results8.bytes64[2] == 0
727 && results8.bytes64[3] == 0
729 continue;
732 state[-2 + 75].value = lfsr_bs(27);
733 const bitslice_value_t filter29_0 = f_a_bs(state[-2 + 31].value, state[-2 + 32].value, state[-2 + 34].value, state[-2 + 35].value);
734 const bitslice_value_t filter29_1 = f_b_bs(state[-2 + 37].value, state[-2 + 41].value, state[-2 + 43].value, state[-2 + 44].value);
735 const bitslice_value_t filter29_2 = f_b_bs(state[-2 + 46].value, state[-2 + 50].value, state[-2 + 52].value, state[-2 + 55].value);
736 const bitslice_value_t filter29_3 = f_b_bs(state[-2 + 57].value, state[-2 + 58].value, state[-2 + 60].value, state[-2 + 62].value);
737 const bitslice_value_t filter29_4 = f_a_bs(state[-2 + 63].value, state[-2 + 72].value, state[-2 + 73].value, state[-2 + 75].value);
738 const bitslice_value_t filter29 = f_c_bs(filter29_0, filter29_1, filter29_2, filter29_3, filter29_4);
739 results8.value &= (filter29 ^ keystream[29].value);
741 if (results8.bytes64[0] == 0
742 && results8.bytes64[1] == 0
743 && results8.bytes64[2] == 0
744 && results8.bytes64[3] == 0
746 continue;
749 state[-2 + 76].value = lfsr_bs(28);
750 const bitslice_value_t filter30_0 = f_a_bs(state[-2 + 32].value, state[-2 + 33].value, state[-2 + 35].value, state[-2 + 36].value);
751 const bitslice_value_t filter30_1 = f_b_bs(state[-2 + 38].value, state[-2 + 42].value, state[-2 + 44].value, state[-2 + 45].value);
752 const bitslice_value_t filter30_2 = f_b_bs(state[-2 + 47].value, state[-2 + 51].value, state[-2 + 53].value, state[-2 + 56].value);
753 const bitslice_value_t filter30_3 = f_b_bs(state[-2 + 58].value, state[-2 + 59].value, state[-2 + 61].value, state[-2 + 63].value);
754 const bitslice_value_t filter30_4 = f_a_bs(state[-2 + 64].value, state[-2 + 73].value, state[-2 + 74].value, state[-2 + 76].value);
755 const bitslice_value_t filter30 = f_c_bs(filter30_0, filter30_1, filter30_2, filter30_3, filter30_4);
756 results8.value &= (filter30 ^ keystream[30].value);
758 if (results8.bytes64[0] == 0
759 && results8.bytes64[1] == 0
760 && results8.bytes64[2] == 0
761 && results8.bytes64[3] == 0
763 continue;
766 state[-2 + 77].value = lfsr_bs(29);
767 const bitslice_value_t filter31_0 = f_a_bs(state[-2 + 33].value, state[-2 + 34].value, state[-2 + 36].value, state[-2 + 37].value);
768 const bitslice_value_t filter31_1 = f_b_bs(state[-2 + 39].value, state[-2 + 43].value, state[-2 + 45].value, state[-2 + 46].value);
769 const bitslice_value_t filter31_2 = f_b_bs(state[-2 + 48].value, state[-2 + 52].value, state[-2 + 54].value, state[-2 + 57].value);
770 const bitslice_value_t filter31_3 = f_b_bs(state[-2 + 59].value, state[-2 + 60].value, state[-2 + 62].value, state[-2 + 64].value);
771 const bitslice_value_t filter31_4 = f_a_bs(state[-2 + 65].value, state[-2 + 74].value, state[-2 + 75].value, state[-2 + 77].value);
772 const bitslice_value_t filter31 = f_c_bs(filter31_0, filter31_1, filter31_2, filter31_3, filter31_4);
773 results8.value &= (filter31 ^ keystream[31].value);
775 if (results8.bytes64[0] == 0
776 && results8.bytes64[1] == 0
777 && results8.bytes64[2] == 0
778 && results8.bytes64[3] == 0
780 continue;
783 for (size_t r = 0; r < MAX_BITSLICES; r++) {
784 if (!get_vector_bit(r, results8)) continue;
785 // take the state from layer 2 so we can recover the lowest 2 bits by inverting the LFSR
786 uint64_t state31 = unbitslice(&state[-2 + 2], r, 48);
787 state31 = lfsr_inv(state31);
788 state31 = lfsr_inv(state31);
789 try_state(state31 & ((1ull << 48) - 1));
791 } // 8
792 } // 7
793 } // 6
794 } // 5
795 } // 4
796 } // 3
797 } // 2
798 } // 1
799 } // 0
800 return NULL;
803 static void try_state(uint64_t s) {
804 Hitag_State hstate;
805 uint64_t keyrev, key, nR1xk;
806 uint32_t b = 0;
808 hstate.shiftreg = s;
810 // recover key
811 keyrev = hstate.shiftreg & 0xffff;
812 nR1xk = (hstate.shiftreg >> 16) & 0xffffffff;
813 for (int i = 0; i < 32; i++) {
814 hstate.shiftreg = ((hstate.shiftreg) << 1) | ((uid >> (31 - i)) & 0x1);
815 b = (b << 1) | fnf(hstate.shiftreg);
817 keyrev |= (nR1xk ^ nR1 ^ b) << 16;
819 // test key
820 hitag2_init(&hstate, keyrev, uid, nR2);
821 if ((aR2 ^ hitag2_nstep(&hstate, 32)) == 0xffffffff) {
823 key = rev64(keyrev);
825 printf("Key: ");
826 for (int i = 0; i < 6; i++) {
827 printf("%02X", (uint8_t)(key & 0xff));
828 key = key >> 8;
830 printf("\n");
831 exit(0);