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)
86 return (state
>> 1) + (lfsr_feedback(state
) << 47)
88 def lfsr_feedback_inv(state
):
89 return (((state
>> 47) ^
(state
>> 1) ^
(state
>> 2)
90 ^
(state
>> 5) ^
(state
>> 6) ^
(state
>> 7)
91 ^
(state
>> 15) ^
(state
>> 21) ^
(state
>> 22)
92 ^
(state
>> 25) ^
(state
>> 29) ^
(state
>> 40)
93 ^
(state
>> 41) ^
(state
>> 42) ^
(state
>> 45)
97 return ((state
<< 1) + (lfsr_feedback_inv(state
))) & ((1 << 48) - 1)
99 def hitag2(state
, length
=48):
101 for i
in range(0, length
):
102 c
= (c
<< 1) |
f20(state
)
103 #print ('%012x' % state)
105 #print ('%012x' % (int("{0:048b}".format(state)[::-1],2)))
106 #print('%08X %08X' % (c, state))
107 #print('final: %08X %08X' % (c, state))
110 if __name__
== "__main__":
113 if len(sys
.argv
) == 4:
114 key
= int(sys
.argv
[1], 16)
115 uid
= int(sys
.argv
[2], 16)
118 nonce
= random
.randrange(2**32)
119 state
= hitag2_init(key
, uid
, nonce
)
120 print('%08X %08X' % (nonce
, hitag2(state
, 32) ^
0xffffffff))
122 elif len(sys
.argv
) == 5:
123 key
= int(sys
.argv
[1], 16)
124 uid
= int(sys
.argv
[2], 16)
127 nonceA
= random
.randrange(2**32)
128 stateA
= hitag2_init(key
, uid
, nonceA
)
129 csA
= hitag2(stateA
, 32) ^
0xffffffff
130 # print('%08X %08X' % (nonceA, csA))
132 nonceB
= random
.randrange(2**32)
133 stateB
= hitag2_init(key
, uid
, nonceB
)
134 csB
= hitag2(stateB
, 32) ^
0xffffffff
135 print('./ht2crack5opencl %08X %08X %08X %08X %08X' % (uid
, nonceA
, csA
, nonceB
, csB
))
136 print('lf hitag lookup --uid %08X --nr %08X --ar %08X --key %012X' % (uid
, nonceA
, csA
, key
))
138 print("Usage: python %s <key> <uid> <nr of nRaR to generate>" % sys
.argv
[0])