So basically we need to recover x and y and we know a, b, and c. The idea i used to solve the challenge is by eliminating the variable. Here is the proof
f1−f2=kx−ly+df2−f3=mx−ny+e
Variables k, m, l, n, d, and e are known so the next step is by doing lcm on one of the coefficent on x or y. After that just eliminate the variable and back to modulus part. For example i eliminate variable x so now we need to work only with variable y and some known constant which are k, d, and e.
k∗y−d=emodpk∗y=e+dmodpy=(e+d)∗k−1modp
After getting y next we just need to substitute y and one of initial equation to get x. To get flag we just need to inverse the x then multiply with y. Here is script i used to solve the challenge
But since there is chance that s1 and k are not coprime with p-1 we can still get the flag by repeating request until get the flag. Here is script i used to solve the challenge
from Crypto.Util.number import*from math import gcdfrom pwn import*whileTrue: r =remote("34.154.18.2", 6951) r.recvuntil(b"Public: ") value = r.recvline().strip()exec(f"p, g, A = {value.decode()}") s1_1, s2_1, m1 =list(map(int,r.recvline().decode().split(" "))) s1_2, s2_2, m2 =list(map(int,r.recvline().decode().split(" "))) r.close() n = p -1 s2_diff = (s2_1 - s2_2) % n s1_inv =inverse(s1_2//(gcd(s1_2,n)), n) list_s = [m1, m2]for k_try in (list_s[0]- list_s[1], list_s[0]+ list_s[1],-list_s[0]- list_s[1],-list_s[0]+ list_s[1]):try: k_inv = (s2_diff *inverse(k_try,n) ) % n k =inverse(k_inv, n) a = (((s2_1 * k) - m1) * s1_inv) % n flag =-a % nfor i inrange(1,100000): tmp = flag // i tmp =long_to_bytes(tmp)if(b"ASCWG"in tmp):print(tmp)breakexceptExceptionas e:continue
Flag : ASCWG{R3uS31n9_G4m4l_NoNc3_S19n1n9_1s_50o_B4d_d9ae71c5}
Power Times (600 pts)
Description
Given challenge below
import osimport timeFLAG = os.getenv("FLAG", "ASCWG{XXXX}").encode()defgen_prime():whileTrue: p =2for _ inrange((2<<2)+1): p *=getrandbits(58)ifis_prime(p+1):return p+1defencrypt(): rand_val =getrandbits(256) x =G(rand_val) h = g^x y = G.random_element() s = h^y c1 = g^y m =G(int.from_bytes(FLAG, byteorder="big")) c2 = m*sreturn (q, g, h, c1, c2), xif__name__=="__main__": q =gen_prime() G =GF(q, modulus="primitive") g = G.gen()print(encrypt()[0])
Solution
We can see that generated prime is smooth, so we can do discrete log by using Pohlig-Hellman algorithm. In this challenge i use sage to do the discrete log. After getting x we just need to power c1 with x then inverse it. After that just multiply c2 with inverse value then get flag. Here is the script i used to solve the challenge
from Crypto.Util.number import*# get values from serviceq, g, h, c1, c2 = (875224290892889410253168846038019495397845981839895578503538762070606629236318636299280667067488152448925123623980445977018237347103987840918389215641601, 53, 668470863937718723825354309435934649904792238682832221264120364357988404177550549769338892561589799679349995460516437572438684131831080306276964600141039, 470878962668317620809812946691419181909240344358287048400184661683087768031571681980489293375447027465015614359318228582735903960499464295349483276943379, 431842574173304880865818550579295915213571302015965986053503318188592141963759191137818608526476403184681573593979962710727636081373213496309873939220545)
gp =GF(q)cp =gp(h)g1 =gp(g)x =discrete_log(cp, g1)x =51569899004643158586115894615877127399796211204579510660966346446530141286946tmp =pow(c1, x, q)result = (c2 *inverse(tmp, q)) % qprint(long_to_bytes(result))