CodeShell.kr - Keyring

Challenge

一份服务日志,题面说一个包里装了六把钥匙。难点在于六条 XOR 边只给相对关系,必须找到唯一那条绝对锚点才能回代解出全部 keystream。

One packet. Six keys

一个包,六把钥匙。

1
https://codeshell.kr/challenges/keyring/

Solution

附件是一份服务日志:

1
2
3
4
5
6
7
8
KEYRING / relay 6
channels: A B C D E F (cycle)
cal: C=5E
pair XOR (hex):
BE=E3 AD=AB CE=7A DF=29 BF=7F AC=64
packet start: E
ciphertext: 74F9699463D069FA7F9513DE6BF6798E0CD271F16E
plaintext: ASCII; PASS=...

Step 1:每条 pair XOR 给出两个通道 keystream 的异或(如 BE=E3k[B] ^ k[E] = 0xE3)。六条边构成闭合环 A–C–E–B–F–D–A,环上异或总和为 0,差分数据自洽。

Step 2cal: C=5E 是唯一的绝对锚点,沿环回代解出全部六个 keystream;冗余边 AD=AB 可用于校验。

1
2
A=3A B=C7 C=5E D=91 E=24 F=B8
k[A] ^ k[D] = 0xAB ✓ 与给定值一致

Step 3:密文从通道 E 起按 A..F 循环取 keystream 逐字节异或。

1
PASS=AMBERMOONCIRCUIT

Script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env python3
"""CodeShell.kr - Keyring: recover the six channel keystreams and decrypt.

Each `pair XOR` line gives k[X] ^ k[Y]; the six lines form a closed 6-cycle, so
their XOR sum is 0 (a self-consistency check on the data) and the system has rank
5. `cal: C=5E` is the single absolute anchor that removes the remaining degree
of freedom; the redundant edge AD=AB verifies the result.
"""
CT = bytes.fromhex("74F9699463D069FA7F9513DE6BF6798E0CD271F16E")
PAIRS = {"BE": 0xE3, "AD": 0xAB, "CE": 0x7A, "DF": 0x29, "BF": 0x7F, "AC": 0x64}
ANCHOR = {"C": 0x5E}
CHANS = "ABCDEF"
START = "E"


def main():
print("cycle xor:", hex(PAIRS["BE"] ^ PAIRS["CE"] ^ PAIRS["AC"]
^ PAIRS["AD"] ^ PAIRS["DF"] ^ PAIRS["BF"]))

k = dict(ANCHOR)
k["A"] = k["C"] ^ PAIRS["AC"]
k["E"] = k["C"] ^ PAIRS["CE"]
k["B"] = k["E"] ^ PAIRS["BE"]
k["F"] = k["B"] ^ PAIRS["BF"]
k["D"] = k["F"] ^ PAIRS["DF"]
print({c: hex(v) for c, v in sorted(k.items())})
print("redundant edge AD:", hex(k["A"] ^ k["D"]), "expected", hex(PAIRS["AD"]))

s = CHANS.index(START)
pt = bytes(CT[i] ^ k[CHANS[(s + i) % 6]] for i in range(len(CT)))
print(pt)


if __name__ == "__main__":
main()
CodeShell{AMBERMOONCIRCUIT}