The problem is given in the form of the follewing file:
assert(len(open('flag.txt', 'rb').read()) <= 50)
assert(str(int.from_bytes(open('flag.txt', 'rb').read(), byteorder='big') << 10000).endswith('1002773875431658367671665822006771085816631054109509173556585546508965236428620487083647585179992085437922318783218149808537210712780660412301729655917441546549321914516504576'))
The flag is converted to an integer value and shifted 10,000 bits to the left to give the last 175 decimal digits of the value. In other words, the purpose of this problem is to restore the flag value from:
At first you may try taking the inverse of
The correct way is, first think of
and, using Euler’s theorem, calculate:
and get the flag by:
Since
c = 1002773875431658367671665822006771085816631054109509173556585546508965236428620487083647585179992085437922318783218149808537210712780660412301729655917441546549321914516504576
mod = 5 ** 175
phi = 5 ** 175 - 5 ** 174
inv = pow(pow(2, 10000, mod), phi - 1, mod)
print(((c * inv) % mod).to_bytes(50, byteorder='big'))
The answer is TSGCTF{0K4y_Y0U_are_r3aDy_t0_Go_aNd_dO_M0r3_CryPt}
.
Let's start with
for the previous solution.
By considering:
we can assume that the above case produces even number and the below case produces odd number. So,
def divide_by_two(x):
if x % 2 == 0:
return x // 2
else:
return (x + mod) // 2
simulates division by 2 over the given modulo.
We can repeat this 10000 times and get the flag.
mod = 5 ** 175
c = 1002773875431658367671665822006771085816631054109509173556585546508965236428620487083647585179992085437922318783218149808537210712780660412301729655917441546549321914516504576 % mod
def divide_by_two(x):
if x % 2 == 0:
return x // 2
else:
return (x + mod) // 2
for i in range(10000):
c = divide_by_two(c)
print(c.to_bytes(50, byteorder='big'))
Now we put:
Note that there's no modulo here.
On the other hand we know
Now we want to calculate
Then consider
And the last
So, by determining
Flag can be obtained by right-shifting
c = 1002773875431658367671665822006771085816631054109509173556585546508965236428620487083647585179992085437922318783218149808537210712780660412301729655917441546549321914516504576
c0 = 0
bit = 1
mask = 1 << 175
while '1' in bin(c0 * 10 ** 175 + c)[-10000:]:
if (c0 * 10 ** 175 + c) & mask != 0:
c0 += bit
bit <<= 1
mask <<= 1
C = c0 * 10 ** 175 + c
flag = (C >> 10000).to_bytes(50, byteorder='big')
print(flag)