Trailing Bits
The description says that both of head and tail bits are lost, so I just tried adding some bits both of them.
1from itertools import product
2with open('output.txt') as f:
3 s = f.read().strip()
4
5for i, j in product(range(10), repeat=2):
6 try:
7 bits = '1'*i + s + '1'*j
8 x = bytes.fromhex(f'{int(bits, 2):x}')
9 if b'CCTF{' in x:
10 print(x)
11 break
12 except:
13 pass
Flag: CCTF{it5_3n0u9h_jU5T_tO_sH1ft_M3}
Amsterdam
There are two stages in encrypt()
.
- Calculate
m
frommsg
. - Calculate
c
fromm
.
We need to carry out the inverse operation for each stage.
Decrypt m from c
In encrypt()
, c
is decided by lower 2 bits of m
. Conversely, we can reconstruct m
using c
. This is the most difficult part in this challenge.
Thinking c
in ternary, each trit indicates a piece of information about the lower 2 bits of m
. We can reconstruct by comparing m
and c
from lower digit.
Decrypt msg from m
Now we know m
, we can also calculate the value of n
because this value is equal to the bit length of m
. Furthermore, since n
is small enough, we can search for k
using brute-force. All that is left is to recover msg
by calculating:
$$ {\rm msg} = \sum_{2 \le i \le n, m_i=1} \binom{n-i}{k} $$
1from Crypto.Util.number import *
2from functools import reduce
3import operator
4from output import enc
5
6# enc = 5550332817876280162274999855997378479609235817133438293571677699650886802393479724923012712512679874728166741238894341948016359931375508700911359897203801700186950730629587624939700035031277025534500760060328480444149259318830785583493
7
8def comb(n, k):
9 if k > n :
10 return 0
11 k = min(k, n - k)
12 u = reduce(operator.mul, range(n, n - k, -1), 1)
13 d = reduce(operator.mul, range(1, k + 1), 1)
14 return u // d
15
16
17def enc_to_m(enc):
18 mbits = ''
19 two = 0
20 while enc > 0:
21 if enc % 3 == 0:
22 mbits = f'{two}{mbits}'
23 elif enc % 3 == 1:
24 mbits = f'{1-two}{mbits}'
25 two = 0
26 else:
27 mbits = f'{1-two}{mbits}'
28 two = 1
29 enc //= 3
30 return int(mbits, 2)
31
32
33def m_to_msg(m, n, k):
34 m = bin(m)[2:]
35 msg = 0
36 for i in range(2, n+1):
37 if m[i-1] == '1':
38 msg += comb(n-i, k)
39 k -= 1
40
41 return msg
42
43
44
45m = enc_to_m(enc)
46n = len(bin(m)[2:])
47for k in range(n):
48 msg = m_to_msg(m, n, k)
49 try:
50 msg = bytes.fromhex(f'{msg:x}')
51 if b'CCTF{' in msg:
52 print(msg)
53 break
54 except:
55 pass
Flag: CCTF{With_Re3p3ct_for_Sch4lkwijk_dec3nt_Encoding!}