---
# System prepended metadata

title: Wanna Champion 2024
tags: [WANNA CHAMPION 2024]

---

# Wanna Champion 2024
> Nhan_laptop |
> --

> Trong lúc rảnh rỗi thì mình có nhìn lại giải của UIT tổ chức năm vừa rồi và chọn những chall mình thấy hay để làm lại.


## RAS - tvdat2004

chall:
```python!
from Crypto.Util.number import *
# from secret import flag
import random
flag = b'crypto{????????????????????????????}'
# print(len(flag))
class RAS(object):
    def __init__(self, p, q):
        self.p = p
        self.q = q
        self.n = (p**3 - p)*(q**3 - q)
        """

        p ( p ** 2 - 1 ) q ( q ** 2 - 1 )
        p ( p - 1 ) ( p + 1  ) q ( q - 1 ) q ( q + 1 )

        """
    def generate_e(self):
        e = random.randint(self.p * self.q, (self.p * self.q)**2)
        return e
        
    def encrypt(self, pt):
        e = self.generate_e()
        assert pt < self.n
        c = pow(pt, e, self.n)
        return e, c

flag1, flag2, flag3 = bytes_to_long(flag[:len(flag)//3]), bytes_to_long(flag[len(flag)//3:2*len(flag)//3]), bytes_to_long(flag[2*len(flag)//3:])

# shuffle it
m1 = flag1*flag2*flag3
m2 = flag1 + flag2 + flag3 
m3 = flag1 * flag2 + flag2 * flag3 + flag3 * flag1 

nbit = 256 

menu = '''
Welcome to my RAS
1. Send primes
2. Get encrypted flag
'''

b = False
while True:
    try:
        choose = input(menu)
        if choose == '1':
            primes = input(f"Send me two {nbit}-bit strong primes, separated by comma: ")
            try:
                p, q = map(int, primes.strip().split(','))
            except: 
                raise Exception("Invalid input")  

            if (isPrime(p) and isPrime(q) and
                p != q and 
                p.bit_length() == q.bit_length() == nbit):
                b = True
                ras = RAS(p, q)
            else:
                print("Primes not strong enough!")
        elif choose == '2':
            if b:
                print(ras.encrypt(m1))
                print(ras.encrypt(m2))
                print(ras.encrypt(m3))
            else:
                raise Exception("You must send strong primes first!!!")
        else:
            raise Exception("Invalid choice!!!")
            
    except Exception as e:
        print(f"Error: {str(e)}")
        break
```
Tóm tắt là:
- Public key bài này là `n = (p ** 3 - p ) * ( q **3 -q )`
- Và cho mình không hạn lần để truy vấn

solve:

Và chú ý là mình kiểm soát được `p,q` nên chiến lược là mình sẽ lựa các p,q phù hợp rồi tìm `m_p, m_q` phù hợp với `phi_p, phi_q`.

### Part 1: 

```python!

ps1 = []
ms1 = []
ps2 = []
ms2 = []
ps3 = []
ms3 = []
def decrypt(x,p):
    e,c = x 
    if GCD(e ,p-1)!=1:
        return None
    phi = p-1 
    d = inverse(e,phi)
    return pow(c,d,p)

while 1  : 
    p = getPrime(512)
    q = getPrime(512)

    resp = oracle(p,q)
    m1 = decrypt(resp[0],p)
    m2 = decrypt(resp[1],p)
    m3 = decrypt(resp[2],p)
    
    if m1 != None:
        ms1.append(m1)
        ps1.append(p)

    if m2 != None:
        ms2.append(m2)
        ps2.append(p)

    if m3 != None:
        ms3.append(m3)
        ps3.append(p)

    m1 = decrypt(resp[0],q)
    m2 = decrypt(resp[1],q)
    m3 = decrypt(resp[2],q)
    
    if m1 != None:
        ms1.append(m1)
        ps1.append(q)

    if m2 != None:
        ms2.append(m2)
        ps2.append(q)

    if m3 != None:
        ms3.append(m3)
        ps3.append(q)

    print(len(ms3))
    if len(ms3)> 80 and len(ms1) > 80 and len(ms2)> 80:
        break

m1 = flag1*flag2*flag3
m2 = flag1 + flag2 + flag3 
m3 = flag1 * flag2 + flag2 * flag3 + flag3 * flag1 

assert m1 == crt(ms1,ps1)
assert m2 == crt(ms2,ps2)
assert m3 == crt(ms3,ps3)

```
Mình tìm được 3 giá trị chuẩn - trong code này mình đang cho các bạn biết thuật này đúng - cần truy vấn một lượng lớn mẫu `message_prime`,.

### Part 2: 

```py!
m = [m1,m2,m3]

flag1,flag2,flag3 = PolynomialRing(ZZ,'x',3,order = 'lex').gens()

m1 = flag1*flag2*flag3 - m[0]
m2 = flag1 + flag2 + flag3 -m[1]
m3 = flag1 * flag2 + flag2 * flag3 + flag3 * flag1 -m[2]

sol = ideal([m1,m2,m3]).groebner_basis()
```

và biểu thức cuối của sol là : 
```python!
 x2^3 - 93081550437588504762415453164324824815512890448494127125481445*x2^2 + 105666576836626803617552219352359893258738438672438347484052785812492589634912853507595855810570916410282826314295714241368*x2 - 30113957810887199660425965901262837077808596976276277044244604618090976099024732025862764623637567079600132510545058461867624877630019579652029887142843302953305408592327770843664464
```
Và mình chỉ cần tìm trên này:
```python!
f = PolynomialRing(ZZ,'x2')

fi = f(sol[-1]).roots(multiplicities = False)
for i in fi[::-1]:
    print(long_to_bytes(int(i)).decode(),end='')
# W1{wi3rd_ch41!En9e_n33d_4_WlErD_s0O!luti0n_6f339749663eeb3508c3b00c15872e41}
print()
```