Skip to content

Instantly share code, notes, and snippets.

@rmmh
Last active September 22, 2022 16:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmmh/4615975 to your computer and use it in GitHub Desktop.
Save rmmh/4615975 to your computer and use it in GitHub Desktop.
iclicker id obfuscation
def enc(id1, id2, id3):
''' encrypt the first three bytes of the ID
* the 4th byte of the ID is id1 ^ id2 ^ id3
* the top three bits of id1 are lost, meaning
there are 2^21 ~= 2M unique clicker IDs
source: reversed iclicker1 firmware '''
a = (id1 & 0x1F) << 3
a |= (id2 & 0x80) >> 5
a |= maskFrom3rd(a)
b = (id2 & 0x7E) << 1
b |= maskFrom3rd(b)
c = (id2 & 1) << 7
c |= (id3 & 0xF8) >> 1
c |= maskFrom3rd(c)
d = (id3 & 0x07) << 5
d |= ((d & 0x20) ^ 0x20) >> 1
return a, b, c, d
def enc_extended(id1, id2, id3):
''' encrypt losslessly,
based on conjecture from how the base station decodes IDs
'''
a = (id1 & 0x1F) << 3
a |= (id2 & 0x80) >> 7
a |= (id1 & 0x80) >> 5
b = (id2 & 0x7E) << 1
b |= (id1 & 0x40) >> 6
c = (id2 & 1) << 7
c |= (id3 & 0xF8) >> 1
c |= (id1 & 0x20) >> 5
d = (id3 & 0x07) << 5
d |= (d & 0x20) >> 1
return a, b, c, d
def dec(a, b, c, d):
'''
source: base station RF firmware v0504
'''
id1 = a >> 3
id2 = c >> 7
id2 |= (a & 0x01) << 7
id2 |= (b & 0xFC) >> 1
id3 = (c & 0x7C) << 1
id3 |= (d >> 5)
if d & 0x30 in (0, 0x30):
# at some point they realized that
# iclicker1 only had 21 bits of id space
# and made a way to recover it going forward
id1 |= (a & 4) << 5 # msb
id1 |= (b & 1) << 6
id1 |= (c & 1) << 5
return id1, id2, id3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment