Rating:
circuit_2.dig
```
Key
_
v
| ________
Plain4 [o]----|--|Plain |
| | Enc|---(o) Ciph4
.--|Key____|
| Block
| ________
Plain3 [o]----|--|Plain |
| | Enc|---(o) Ciph3
.--|Key____|
| Block
| ________
Plain2 [o]----|--|Plain |
| | Enc|---(o) Ciph2
.--|Key____|
| Block
| ________
Plain1 [o]----|--|Plain |
| | Enc|---(o) Ciph1
.--|Key____|
| Block
| ________
Plain0 [o]----|--|Plain |
| | Enc|---(o) Ciph0
.--|Key____|
Block
Key [o]---<|Key
```
Block.dig
```
0 ~ 63 0 ~ 31 0 ~ 31 0 ~ 63
Plain [o]--------|-------------.----------------------\ /--------.------------------------|--------(o) Enc
|-. | _____ \ / | _____ .-|
| 32 ~ 63 .-\\ \ \ / .-\\ \ 32 ~ 63 |
| ||xnor|o-. x ||xnor|o-. |
| Key1|>--//____/ | ____ / \ Key2|>--//____/ | ____ |
| .--\\ \ / \ .--\\ \ |
| ||xor|---/ \ ||xor|---.
|-------------------------//___/ \---------------------//___/
0 ~ 7
0 ~ 39 0 ~ 7 /---------| 0 ~ 31
Key [o]--------.--------- 8 ~ 31 |--------<| Key1
| 8 ~ 31 /--------|
.---------x 0 ~ 23
| 32 ~ 39 \--------| 0 ~ 31
.--------- 24 ~ 31 |--------<| Key2
\---------|
```
**Reverse:**
PlainLo = Plain & 0xFFFFFFFF
PlainHi = Plain >> 32
CiphLo = (PlainLo xnor key1) xor PlainHi
CiphHi = (CiphLo xnor key2) xor PlainLo
Enc = (CiphHi << 32) + CiphLo
Key1 = Key & 0xFFFFFFFF
Key2 = Key >> 8
**Solution:**
Known Plaintext is `bcactf{`, which is 7 bytes (28 bits).
Since there are 24 common bits in key1 and key2, so knowing those common bits from one of them can be applied to the other key.
(1) CiphLo = (PlainLo xnor key1) xor PlainHi = 0xFFFFFFFF - (PlainLo xor key1 xor PlainHi)
(2) CiphHi = (CiphLo xnor key2) xor PlainLo = 0xFFFFFFFF - (CiphLo xor key2 xor PlainLo)
By xor-ing two equations, we have
CiphLo xor CiphHi = PlainLo xor key1 xor PlainHi xor CiphLo xor key2 xor PlainLo
=> (3) CiphHi xor PlainHi = key1 xor key2
From encrypted.txt:
7B18824F93FB072A 2909D67381E26C31 57238C7EFEF9132D 7D24AD42B991216A 464B9173A2811D13
We have CiphHi = 0x7B18824F, PlainHi = 0x62636163 (`bcac`), CiphLo = 0x93FB072A, PlainLo = 0x74667b?? (`tf{?`)
Therefore, we have key1 xor key2 = 0x197be32c
Also by (1) we have the top 8 bits of key1 = (0xff - 0x93 (from CiphLo)) xor 0x74 (from PlainLo) xor 0x62 (from PlainHi) = 0x7a
by the same way, we have the top 24 bits of key1 = the bottom 24 bits of key2 = (0xffffff - 0x93fb07) xor 0x74667b xor 0x626361 = 0x7a01e2
the bottom 8 bits of key1 = 0xe2 ^ 0x2c = 0xce
the top 8 bits of key2 = 0x7a ^ 0x19 = 0x63
Therefore, key1 = 0x7a01e2ce, and key2 = 0x637a01e2.
Solving Script:
```python
key1 = 0x7a01e2ce
key2 = 0x637a01e2
c = [0x7B18824F93FB072A, 0x2909D67381E26C31, 0x57238C7EFEF9132D, 0x7D24AD42B991216A, 0x464B9173A2811D13]
for i in c:
# using (3)
plainhi = key1 ^ key2 ^ (i >> 32)
# using (2)
plainlo = (0xffffffff - (i >> 32)) ^ key2 ^ (i & 0xffffffff)
print(bytes.fromhex(hex((plainhi << 32) + plainlo)[2:]).decode(), end="")
```
Output:
```
bcactf{x0r5_4nD_NXoR5_aNd_NnX0r5_0r_xOr}
```