---
# System prepended metadata

title: ASIS CTF Quals 2023 - renamiara
tags: [CTF]

---

# ASIS CTF Quals 2023 - renamiara

Recently, I have participated in Asis CTF Quals 2023. Although I can only solve one challenge, which is **renamiara**, through this challenge I have learned a little more about math and gained a little experience about the way that I should approach a problem. Because this is the most recent flag of mine, I want to share the solution and all my thinking process. This will be a super fast write-up and I hope you like it. :pancakes: 



# Renamiara

This is the link to the challenge [renamiara.py](https://github.com/KienHoSD/CTF-file/blob/master/2023archive/ASIS2023/renamiara/renamiara.py)

First, the server will give us a banner with "greetings and welcome" to the challenge and tell us that this is a real-world's discrete log problem (I don't think so :P)

![](https://hackmd.io/_uploads/H1owhfYgT.png)

If we enter "y" then the fun begin. If we enter "n" then ... :cricket: 
```python=
ans = sc().decode().strip().lower()
if ans == 'y':
    NBIT = 32
    STEP = 40

    pr(border, "In each step solve the given equation and send the solution for x, y", border)
    c = 1
    while c <= STEP:
        nbit = NBIT * c
        p = getPrime(nbit)
        pr(border, f'p = {p}')
        pr(border, 'First send the base g: ')
        g = sc().strip().decode()
        pr(border, 'Send the solutions for pow(g, x + y, p) = x * y, as x and y:')
        xy = sc().strip().decode().split(',')
        try:
            g, x, y = [int(_) for _ in [g] + xy]
            print(g,x,y)
        except:
            die(border, 'Given number is not correct! Bye!!')
        if (x >= p-1 or x <= 1) or (y >= p-1 or y <= 1) or x == y:
            die(border, "Kidding me!? Your solutions must be smaller than p-1 and x ≠ y :(")
        if g <= 2**24 or g >= p-1:
            die(border, "Kidding me!? Please send the correct base :P")
        if pow(g, x + y, p) ==  x * y % p:
            if c == STEP:
                die(border, f"Congratulation! the flag is: {flag}")
            else:
                pr(border, "Good job, try to solve the next level!")
                c += 1
        else:
            die(border, "Try harder and be smarter to find the solution!!")
elif ans == 'n':
    pr(border, 'Bye!!')
else:
    pr(border, 'Please send a valid answer! Bye!!')
```
From the code of the challenge, we can see that this challenge will contain 40 sub-problems with the variable `c` being raised by 1 each time we complete 1 level (in this case, the prime `p = getPrime(32*c)` will be bigger). If we got to level 40, we could have the `flag`. So our way to solve all the sub-problems will be harder and harder, right? We will know later. :wink: 


The server gave us $p$, and our job is to find $g,x,y$ to make the equation below valid. $$ g^{x+y}\%p = {xy \%p} $$

We can only input $x,y$ for $x \in range(1,p-1)$, $y \in range(1,p-1)$ and $x ≠ y$
```python=
if (x >= p-1 or x <= 1) or (y >= p-1 or y <= 1) or x == y:
    die(border, "Kidding me!? Your solutions must be smaller than p-1 and x ≠ y :(")
```
Also, we can only input $g$ for $g \in range(2^{24},p-1)$
```python=
if g <= 2**24 or g >= p-1:
    die(border, "Kidding me!? Please send the correct base :P")
```

So from here, I have come up with many weird solutions, like brute forcing the pair $(x,y)$ such that $x \in range(1,p-1)$ and $y = p-x$ that satisfies the equation at level 1 to see if there is any relation between $x,y$ and $g$ (I choose $g = 2^{24}+1$), but it takes longer than I thought, so I changed my approach.

Another approach of mine is to solve the equation with my crypto-challenge legendary ultimate tool, CASIO fx-580VN X the calculator (You didn't read wrong :P They work like magic sometimes) with small $g$ (like $g=2$) for computation test for random $x$ to have $y$, but I know this just for testing and then move on to the next idea.

After some thought, from the equation above, I have:  $$ g^{x+y}\%p = {xy \%p} 
<=> {g^{x+y} \over x*y} ≡ {1 (mod  \ p)} $$

From Fermat little theorem we have: $$g^{p-1} ≡ 1(mod \ p) \ \ \ with \ p \ is \ prime$$ 
Linked those two together, I have to make $${g^{x+y} \over x*y} = g^{p-1}$$
To do that, first I came up with another weird solution is to find a pair $(x,y)$ to make $x+y = p-1$ and $inverse(x+y,p) = 1$, another brute force solution :laughing:. But I remember that I can change the variable $g$, so this leads me to my final solution for this challenge.

So my solution is to make $x+y = p$ and $(x*y)\%p=g$. Hence,$${g^{x+y} \over x*y} = {g^{p} \over g} = {g^{p-1}}$$
We will pick a random $x$ (I choose constant $x=2^{24}$) and $y=p-x$, and formed $g = (x*y)\%p$. Below is my code to solve this challenge first attempt:
```python=
from Crypto.Util.number import inverse
from pwn import *

io = remote('45.153.241.194', 31337)
# receive the greetings
for i in range(6):  
    print(io.recvline())
# yes
io.sendline(b'y')

# make the same attack for 40 levels
for i in range(40):
    # receive instruction msg or "next level" msg
    print(io.recvline())
    # receive p
    p = io.recvline()
    p = int(p.decode()[5:],10)
    print(io.recvline())
    print(p)
    x = 2**24 
    y = p-x
    g =pow(x*y,1,p)
    # send g
    io.sendline(str(g).encode())
    print(io.recvline())
    # send x,y
    io.sendline((str(x)+","+str(y)).encode())

io.interactive()
```
By the time I ran this code, it was working well for all my attempts to get the flag. But I remember that $g$ have to be in $range(2^{24},p-1)$, so maybe add another while loop to find random $x$ make pair $(x,p-x)$ that $(x*(p-x))\%p \in range(2^{24},p-1)$ if $g \notin range(2^{24},p-1)$ to make sure $g$ is valid before send $g,x,y$ to the server.

#### Conclusion
To sum up, this challenge was the easiest in the crypto category. I have learned that I should not approach a challenge with a brute-force solution instead of examining the math behind it first, and I shouldn't forget any detail that could lead me to the solution (I don't remember the $g$ at the time; only focus on $x$ and $y$). But this challenge didn't take me long to solve, and I'm really glad that I could solve it :smile:

I'm still really naive about crypto challenges, so my explanation could be unprecised. Other unsolved challenges still remain unsolved for me. I'm really curious about others' challenge solutions, but I will come back to it later if I can find a way to solve it. And finally, I hope that you will enjoy reading this little **Sonic** write-up of mine. Thanks you for reading, and have an A1 day!

#KienSD :running: 






