Rating:
Block4.dig
```
Add
_______
| c_1|-| .-----------------. .-----------------------------------.
|c_0 b|----. / | | |
____ .------|s_____a|---/ v \|_|/ |
Clock |>--|S ~Q| | | \___/ |
|--|R__Q|--. I | | | |
RS | Clock |>--v | |xor| |
| | ______ | \___/ |
Plain [o]--------|>-----------.----|D | | | |
___ | | | ______ | _____ ______ |
Clock |>-|_H_|-|>C Q|--------.---------|in | .--|a s|-----------------|D | |
| | ______ | out|------|b c_0| | | |
>-----|en____| >-|en out|-|shift_| |-|c____| Clock |>-|_H_|-|>C Q|--.----(o) Enc
Reg Clock|>--|>C ovf| Shift Add | |
|-|clr___| >-----|en____|
Counter Reg
Clock [_n_r]---<| Clock
```
Encryption is done by the following pseudocode:
```
def e(p):
result = 0
for ctr in range(1, 65):
result = ((result ^ p) + (p << ctr)) & 0xffffffffffffffff
p = (p << 1) & 0xffffffffffffffff
return result
```
Notice that during a pass, the lowest `ctr - 1` bits of `p` are all zero. (Since each pass shift `p` to the left by 1 bit).
Therefore, each pass fix the lowest unfixed bit in the result, and we can use this to recover the plaintext bit by bit.
Solve Script:
```
def e(p):
result = 0
for ctr in range(1, 65):
result = ((result ^ p) + (p << ctr)) & 0xffffffffffffffff
p = (p << 1) & 0xffffffffffffffff
return result
def d(p):
result = 0
for ctr in range(64):
tmp = e(result + (1 << ctr))
if tmp & ((1 << (ctr + 1)) - 1) == p & ((1 << (ctr + 1)) - 1):
result += (1 << ctr)
return result
c = [0xEF5BFC29C7DE0F97, 0x4ED8DA28F68A65EC, 0xC4D8A4F1B763C6A4, 0x30850A10387421B3, 0xEB3390DFEB1273F9]
print(b"".join(bytes.fromhex(hex(d(ct))[2:]) for ct in c))
```
Output:
```
b'bcactf{w45nt_tHls_Fun_7423505843fauiehy}'
```