added more keys (@equipter)
[RRG-proxmark3.git] / tools / hitag2crack / hitag2_gen_nRaR.py
blob232add1f3d603d79763d4978cdce93cc9edde28d
1 #!/usr/bin/env python3
3 """
4 HITAG2 cipher
5 Implemented by Aram Verstegen
6 """
7 import random
9 def i4(x, a, b, c, d):
10 return (((x >> a) & 1)*8)+((x >> b) & 1)*4+((x >> c) & 1)*2+((x >> d) & 1)
13 def f20_4(state):
14 return ((0x3c65 >> i4(state,34,43,44,46)) & 1)
16 def f20_3(state):
17 return (( 0xee5 >> i4(state,28,29,31,33)) & 1)
19 def f20_2(state):
20 return (( 0xee5 >> i4(state,17,21,23,26)) & 1)
22 def f20_1(state):
23 return (( 0xee5 >> i4(state, 8,12,14,15)) & 1)
25 def f20_0(state):
26 return ((0x3c65 >> i4(state, 2, 3, 5, 6)) & 1)
28 def f20_last(s0,s1,s2,s3,s4):
29 return (0xdd3929b >> ((s0 * 16)
30 + (s1 * 8)
31 + (s2 * 4)
32 + (s3 * 2)
33 + (s4 * 1))) & 1
35 def f20(state):
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])
44 def f20a_bs(a,b,c,d):
45 return (~(((a|b)&c)^(a|d)^b)) # 6 ops
46 def f20b_bs(a,b,c,d):
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])))
58 def unbitslice(s, n):
59 return int(''.join(map(str,map(int,map(bool,s[n:n+48])))[::-1]),2)
61 def hitag2_init(key, uid, nonce):
62 state = 0
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))
71 #print nonce_bit
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))
75 return state
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)
83 ^ (state >> 47)) & 1)
84 def lfsr(state):
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)
93 ^ (state >> 46)) & 1)
95 def lfsr_inv(state):
96 return ((state << 1) + (lfsr_feedback_inv(state))) & ((1<<48)-1)
98 def hitag2(state, length=48):
99 c = 0
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))
104 state = lfsr(state)
105 return c
107 if __name__ == "__main__":
108 import sys
109 if len(sys.argv) == 4:
110 key = int(sys.argv[1], 16)
111 uid = int(sys.argv[2], 16)
112 n = int(sys.argv[3])
113 for i in range(n):
114 nonce = random.randrange(2**32)
115 state = hitag2_init(key, uid, nonce)
116 print('%08X %08X' % (nonce, hitag2(state, 32)^0xffffffff))
117 else:
118 print("Usage: python %s <key> <uid> <nr of nRaR to generate>" % sys.argv[0])