TSGCTF2020 Beginner’s Crypto
Published:
- Solved after the CTF ended :(
- I needed to see this post sooner…
- One of the answers includes an arithmetic version of left and right shift.
- I need to practice more crypto…
Using rewritten version that doesn’t read input from file.
First assert
assert(len(x))<=50)
; where x
is a string (presumably).
This means that each unit of length of x
is a byte (char). However, to easily deal with integers, we can transform this constraint.
The below is pseudocode!
len(str((int) x)) <= 2**(50*8) = 2**400
Second assert
assert(str(int.from_bytes(x, "utf-8"), byteorder='big') << 10000).endswith(...)
Assuming we already did the (int)
conversion to change x
to xint
, we get
assert(str(xint<<10000).endswith(...))
An interesting property about left shift is that x<<y
= x*(2**y)
. Also, this is not relevant, but x>>y
= x/(2**y)
!
This means that our assertion is:
assert(str(xint*(2**10000)).ends(with...))
Putting it together
Let’s call our given ending sequence R
. We will also call L
= len(str(R))
.
We know that
Eq 1: (xint * 2**10000) % 10**L = R
.
And knowing L=175
, (xint * 2*10000) % 10**175 = R
.
So, let’s try to reverse this!
To reverse this, we would generally multiply both sides by the inverse of 2**10000 % 10**175
. However, it is not possible to find the inverse because the gcd of 2**10000
and 10**175
is not 1! reasoning
But, we can massage the right hand terms of Eq 1
a bit (find the gcd and divide, basically).
(xint * 2**10000)%10**175
= ((xint * 2**10000)%10**175)%5**175)
= (xint*2**10000)%5**175)
We can find the inverse of 2**10000 % 5**175
!
Then, we multiply by the inverse:
(xint * 2**10000 * inverse = R * inverse) % 5**175
(xint = solution) % 5**175
Keep in mind that 5**175 > 2**400
, meaning the solution we get will not be cut off in a weird way. After getting the solution, we can convert the integer to bytes, then to a string. Plug into the challenge and make sure that we pass both assertions!
I tried to use Sage
… but couldn’t wrap my head around it… I ended up just using Python
. The script is included in the write-up repository.