5 Implemented by Aram Verstegen
10 return (((x
>> a
) & 1)*8)+((x
>> b
) & 1)*4+((x
>> c
) & 1)*2+((x
>> d
) & 1)
14 return ((0x3c65 >> i4(state
,34,43,44,46)) & 1)
17 return (( 0xee5 >> i4(state
,28,29,31,33)) & 1)
20 return (( 0xee5 >> i4(state
,17,21,23,26)) & 1)
23 return (( 0xee5 >> i4(state
, 8,12,14,15)) & 1)
26 return ((0x3c65 >> i4(state
, 2, 3, 5, 6)) & 1)
28 def f20_last(s0
,s1
,s2
,s3
,s4
):
29 return (0xdd3929b >> ((s0
* 16)
36 return f20_last(f20_0(state
), f20_1(state
), f20_2(state
), f20_3(state
), f20_4(state
))
38 def lfsr_bs(state
, i
):
39 return (state
[i
+ 0] ^ state
[i
+ 2] ^ state
[i
+ 3] ^ state
[i
+ 6] ^
40 state
[i
+ 7] ^ state
[i
+ 8] ^ state
[i
+16] ^ state
[i
+22] ^
41 state
[i
+23] ^ state
[i
+26] ^ state
[i
+30] ^ state
[i
+41] ^
42 state
[i
+42] ^ state
[i
+43] ^ state
[i
+46] ^ state
[i
+47])
45 return (~
(((a|b
)&c
)^
(a|d
)^b
)) # 6 ops
47 return (~
(((d|c
)&(a^b
))^
(d|a|b
))) # 7 ops
48 def f20c_bs(a
,b
,c
,d
,e
):
49 return (~
((((((c^e
)|d
)&a
)^b
)&(c^b
))^
(((d^e
)|a
)&((d^b
)|c
)))) # 13 ops
51 def filter_bs(state
, i
):
52 return (f20c_bs( f20a_bs(state
[i
+ 2],state
[i
+ 3],state
[i
+ 5],state
[i
+ 6]),
53 f20b_bs(state
[i
+ 8],state
[i
+12],state
[i
+14],state
[i
+15]),
54 f20b_bs(state
[i
+17],state
[i
+21],state
[i
+23],state
[i
+26]),
55 f20b_bs(state
[i
+28],state
[i
+29],state
[i
+31],state
[i
+33]),
56 f20a_bs(state
[i
+34],state
[i
+43],state
[i
+44],state
[i
+46])))
59 return int(''.join(map(str,map(int,map(bool,s
[n
:n
+48])))[::-1]),2)
61 def hitag2_init(key
, uid
, nonce
):
63 for i
in range(32, 48):
64 state
= (state
<< 1) |
((key
>> i
) & 1)
65 for i
in range(0, 32):
66 state
= (state
<< 1) |
((uid
>> i
) & 1)
67 #print '%012x' % state
68 #print '%012x' % (int("{0:048b}".format(state)[::-1],2))
69 for i
in range(0, 32):
70 nonce_bit
= (f20(state
) ^
((nonce
>> (31-i
)) & 1))
72 state
= (state
>> 1) |
(((nonce_bit ^
(key
>> (31-i
))) & 1) << 47)
73 #print '%012x' % state
74 #print '%012x' % (int("{0:048b}".format(state)[::-1],2))
77 def lfsr_feedback(state
):
78 return (((state
>> 0) ^
(state
>> 2) ^
(state
>> 3)
79 ^
(state
>> 6) ^
(state
>> 7) ^
(state
>> 8)
80 ^
(state
>> 16) ^
(state
>> 22) ^
(state
>> 23)
81 ^
(state
>> 26) ^
(state
>> 30) ^
(state
>> 41)
82 ^
(state
>> 42) ^
(state
>> 43) ^
(state
>> 46)
85 return (state
>> 1) + (lfsr_feedback(state
) << 47)
87 def lfsr_feedback_inv(state
):
88 return (((state
>> 47) ^
(state
>> 1) ^
(state
>> 2)
89 ^
(state
>> 5) ^
(state
>> 6) ^
(state
>> 7)
90 ^
(state
>> 15) ^
(state
>> 21) ^
(state
>> 22)
91 ^
(state
>> 25) ^
(state
>> 29) ^
(state
>> 40)
92 ^
(state
>> 41) ^
(state
>> 42) ^
(state
>> 45)
96 return ((state
<< 1) + (lfsr_feedback_inv(state
))) & ((1<<48)-1)
98 def hitag2(state
, length
=48):
100 for i
in range(0, length
):
101 c
= (c
<< 1) |
f20(state
)
102 #print '%012x' % state
103 #print '%012x' % (int("{0:048b}".format(state)[::-1],2))
107 if __name__
== "__main__":
109 if len(sys
.argv
) == 4:
110 key
= int(sys
.argv
[1], 16)
111 uid
= int(sys
.argv
[2], 16)
114 nonce
= random
.randrange(2**32)
115 state
= hitag2_init(key
, uid
, nonce
)
116 print('%08X %08X' % (nonce
, hitag2(state
, 32)^
0xffffffff))
118 print("Usage: python %s <key> <uid> <nr of nRaR to generate>" % sys
.argv
[0])